aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornea <romangraef@gmail.com>2022-11-01 21:24:25 +0100
committernea <romangraef@gmail.com>2022-11-01 21:24:25 +0100
commit05d2ae11997b85918890e853634efd7df2986aef (patch)
tree29afe632ddd32fe1887d4267914ac00c5f51464f
parent170ebea5a6e46c0f489e80460d5e169f6ebdd1dd (diff)
parente42dd2aa0a2e0a988e820e1ceb13cf2bc30ba987 (diff)
downloadNotEnoughUpdates-05d2ae11997b85918890e853634efd7df2986aef.tar.gz
NotEnoughUpdates-05d2ae11997b85918890e853634efd7df2986aef.tar.bz2
NotEnoughUpdates-05d2ae11997b85918890e853634efd7df2986aef.zip
Merge remote-tracking branch 'origin/master' into feature/glowshrooms
-rw-r--r--.github/workflows/infer.yml5
-rw-r--r--.github/workflows/remove-merge-needed-label.yml32
-rwxr-xr-x.github/workflows/send_webhook_update.sh2
-rw-r--r--Update Notes/2.1.1.md8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java46
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java16
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java32
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java20
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java10
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java10
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java85
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java44
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java20
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/ArrowPagesUtils.java190
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java16
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java12
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/events/ProfileDataLoadedEvent.java40
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java167
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/itemeditor/GuiElementTextField.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java405
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java32
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java98
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java7
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java26
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java64
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java391
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnderNodes.java42
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java124
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java15
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/ApiData.java84
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/Minion.java112
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java332
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java305
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java91
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperInventoryLoader.java175
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoLoader.java218
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoMinionLoader.java132
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/RecipeBuilder.java75
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java439
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java274
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperTooltips.java91
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewLine.java (renamed from src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/NeuConfigTutorial.java)9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewText.java42
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CollectionRequirement.java44
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CustomRequirement.java (renamed from src/main/java/io/github/moulberry/notenoughupdates/commands/misc/ButtonsCommand.java)18
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/MinionRequirement.java24
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/ReputationRequirement.java51
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/SlayerRequirement.java46
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CraftingSource.java35
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CustomSource.java33
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/MinionSource.java23
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/NpcSource.java47
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java195
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperRequirementsManager.java129
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/NeuTutorial.java168
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/TutorialBase.java399
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiTextField.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java37
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MinionHelper.java45
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java30
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Notifications.java42
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java32
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java14
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java29
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java100
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java26
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java60
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java61
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeHistory.java74
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java22
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java24
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java0
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/TabListUtils.java70
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java92
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java35
-rw-r--r--src/main/resources/assets/notenoughupdates/minion_overlay.pngbin0 -> 393 bytes
117 files changed, 5048 insertions, 1500 deletions
diff --git a/.github/workflows/infer.yml b/.github/workflows/infer.yml
index 7a035a42..049b9d3b 100644
--- a/.github/workflows/infer.yml
+++ b/.github/workflows/infer.yml
@@ -1,12 +1,13 @@
name: Infer
on:
- - pull_request
+ - pull_request_target
- workflow_dispatch
+permissions: {}
jobs:
inferering:
runs-on: ubuntu-latest
-
+ if: "!contains(github.event.head_commit.message, '[no infer]')"
steps:
- uses: actions/checkout@v3
name: Checkout feature
diff --git a/.github/workflows/remove-merge-needed-label.yml b/.github/workflows/remove-merge-needed-label.yml
new file mode 100644
index 00000000..0ff57523
--- /dev/null
+++ b/.github/workflows/remove-merge-needed-label.yml
@@ -0,0 +1,32 @@
+name: Remove merge label
+
+on:
+ - pull_request_target
+
+
+permissions:
+ contents: read
+ pull-requests: write
+
+jobs:
+ check-mergability:
+ env:
+ GH_TOKEN:
+ ${{ secrets.GITHUB_TOKEN }}
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - run: |
+ echo This is the merginator 2000 speaking, i am now checking your mergability
+ if git merge-tree "$(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }})" ${{ github.event.pull_request.head.sha }} "${{ github.event.pull_request.base.sha }}" | grep "^<<<<<<<\|changed in both" >/dev/null; then
+ echo "This PR is deemed: dirty :("
+ echo "{\"labels\":[\"$MERGE_LABEL\"]}"|gh api -X POST --input - "$ISSUE_PATH" || true
+ else
+ echo This PR is deemed: clean!
+ gh api -X DELETE $ISSUE_PATH/$MERGE_LABEL || true
+ fi
+ env:
+ MERGE_LABEL: needs-merge
+ ISSUE_PATH: /repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/labels
diff --git a/.github/workflows/send_webhook_update.sh b/.github/workflows/send_webhook_update.sh
index f0eb0051..7a6f932d 100755
--- a/.github/workflows/send_webhook_update.sh
+++ b/.github/workflows/send_webhook_update.sh
@@ -104,4 +104,4 @@ fi
echo "Message sent to discord."
echo "$discord_output" | jq .
id_string=$(echo "$discord_output" | jq .id)
-echo "::set-output name=MESSAGE_ID::${id_string//\"/}"
+echo "MESSAGE_ID=${id_string//\"/}" >> $GITHUB_OUTPUT
diff --git a/Update Notes/2.1.1.md b/Update Notes/2.1.1.md
index b87bf974..681f8773 100644
--- a/Update Notes/2.1.1.md
+++ b/Update Notes/2.1.1.md
@@ -18,5 +18,9 @@
- Add exponent and percentage to calculator - u9g
- Add total trophy fish count to /pv - Vixid
- Allow hiding messages below a set skyblock level - nopo
-- Added Glowing Mushroom Highlighter - nea89
-
+ - Add Glowing Mushroom Highlighter - nea89
+ - Add crimson isle quests to todo overlay - Vixid
+ - Add replace chat social options to both party and guild chat - Vixid
+ - Add class average to dungeons page in /pv - Vixid
+ - Add recipe history and fairy soul waypoint distance - Vixid
+ - Fix buggy cape on player model in /pv - Vixid
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
index 34d87c5b..5fe902fb 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
@@ -34,6 +34,7 @@ import io.github.moulberry.notenoughupdates.recipes.CraftingOverlay;
import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe;
import io.github.moulberry.notenoughupdates.recipes.Ingredient;
import io.github.moulberry.notenoughupdates.recipes.NeuRecipe;
+import io.github.moulberry.notenoughupdates.recipes.RecipeHistory;
import io.github.moulberry.notenoughupdates.util.ApiUtil;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.HotmInformation;
@@ -113,12 +114,16 @@ public class NEUManager {
new KeyBinding("Show usages for item", Keyboard.KEY_U, "NotEnoughUpdates");
public final KeyBinding keybindViewRecipe =
new KeyBinding("Show recipe for item", Keyboard.KEY_R, "NotEnoughUpdates");
+ public final KeyBinding keybindPreviousRecipe =
+ new KeyBinding("Show previous recipe", Keyboard.KEY_LBRACKET, "NotEnoughUpdates");
+ public final KeyBinding keybindNextRecipe =
+ new KeyBinding("Show next recipe", Keyboard.KEY_RBRACKET, "NotEnoughUpdates");
public final KeyBinding keybindToggleDisplay = new KeyBinding("Toggle NEU overlay", 0, "NotEnoughUpdates");
public final KeyBinding keybindClosePanes = new KeyBinding("Close NEU panes", 0, "NotEnoughUpdates");
public final KeyBinding keybindItemSelect = new KeyBinding("Select Item", -98 /*middle*/, "NotEnoughUpdates");
public final KeyBinding[] keybinds = new KeyBinding[]{
- keybindGive, keybindFavourite, keybindViewUsages, keybindViewRecipe,
- keybindToggleDisplay, keybindClosePanes, keybindItemSelect
+ keybindGive, keybindFavourite, keybindViewUsages, keybindViewRecipe, keybindPreviousRecipe,
+ keybindNextRecipe, keybindToggleDisplay, keybindClosePanes, keybindItemSelect
};
public String viewItemAttemptID = null;
@@ -132,6 +137,8 @@ public class NEUManager {
private final HashMap<String, Set<NeuRecipe>> recipesMap = new HashMap<>();
private final HashMap<String, Set<NeuRecipe>> usagesMap = new HashMap<>();
+ private final Map<String, String> displayNameCache = new HashMap<>();
+
public String latestRepoCommit = null;
public File configLocation;
@@ -157,10 +164,6 @@ public class NEUManager {
repoLocation.mkdir();
}
- public void setCurrentProfile(String currentProfile) {
- SBInfo.getInstance().currentProfile = currentProfile;
- }
-
public String getCurrentProfile() {
return SBInfo.getInstance().currentProfile;
}
@@ -886,7 +889,6 @@ public class NEUManager {
case "viewpotion":
neu.sendChatMessage("/viewpotion " + internalName.split(";")[0].toLowerCase(Locale.ROOT));
}
- displayGuiItemRecipe(internalName);
}
public void showRecipe(String internalName) {
@@ -990,6 +992,7 @@ public class NEUManager {
List<NeuRecipe> usages = getAvailableUsagesFor(internalName);
if (usages.isEmpty()) return false;
NotEnoughUpdates.INSTANCE.openGui = (new GuiItemRecipe(usages, this));
+ RecipeHistory.add(NotEnoughUpdates.INSTANCE.openGui);
return true;
}
@@ -998,6 +1001,7 @@ public class NEUManager {
List<NeuRecipe> recipes = getAvailableRecipesFor(internalName);
if (recipes.isEmpty()) return false;
NotEnoughUpdates.INSTANCE.openGui = (new GuiItemRecipe(recipes, this));
+ RecipeHistory.add(NotEnoughUpdates.INSTANCE.openGui);
return true;
}
@@ -1593,6 +1597,7 @@ public class NEUManager {
recipes.clear();
recipesMap.clear();
usagesMap.clear();
+ itemMap.clear();
File[] itemFiles = new File(repoLocation, "items").listFiles();
if (itemFiles != null) {
@@ -1606,6 +1611,7 @@ public class NEUManager {
new RepositoryReloadEvent(repoLocation, !hasBeenLoadedBefore).post();
hasBeenLoadedBefore = true;
comp.complete(null);
+ displayNameCache.clear();
} catch (Exception e) {
comp.completeExceptionally(e);
}
@@ -1622,4 +1628,30 @@ public class NEUManager {
public boolean isValidInternalName(String internalName) {
return itemMap.containsKey(internalName);
}
+
+ public String getDisplayName(String internalName) {
+ if (displayNameCache.containsKey(internalName)) {
+ return displayNameCache.get(internalName);
+ }
+
+ String displayName = null;
+ TreeMap<String, JsonObject> itemInformation = NotEnoughUpdates.INSTANCE.manager.getItemInformation();
+ if (itemInformation.containsKey(internalName)) {
+ JsonObject jsonObject = itemInformation.get(internalName);
+ if (jsonObject.has("displayname")) {
+ displayName = jsonObject.get("displayname").getAsString();
+ }
+ }
+
+ if (displayName == null) {
+ displayName = internalName;
+ Utils.showOutdatedRepoNotification();
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) {
+ Utils.addChatMessage("§c[NEU] Found no display name in repo for '" + internalName + "'!");
+ }
+ }
+
+ displayNameCache.put(internalName, displayName);
+ return displayName;
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
index 2f55c338..87ce915b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
@@ -1219,8 +1219,8 @@ public class NEUOverlay extends Gui {
String internal1 = o1.get("internalname").getAsString();
String internal2 = o2.get("internalname").getAsString();
- double cost1 = manager.auctionManager.getBazaarOrBin(internal1);
- double cost2 = manager.auctionManager.getBazaarOrBin(internal2);
+ double cost1 = manager.auctionManager.getBazaarOrBin(internal1, false);
+ double cost2 = manager.auctionManager.getBazaarOrBin(internal2, false);
if (cost1 < cost2) return mult;
if (cost1 > cost2) return -mult;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 308cbdc0..c1190b2b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -45,6 +45,7 @@ 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;
@@ -69,6 +70,7 @@ 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.options.NEUConfig;
import io.github.moulberry.notenoughupdates.overlays.EquipmentOverlay;
@@ -78,6 +80,7 @@ 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;
@@ -295,6 +298,7 @@ public class NotEnoughUpdates {
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);
@@ -319,9 +323,11 @@ public class NotEnoughUpdates {
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(TitleUtil.getInstance());
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 1b6896db..53e72dc1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java
@@ -280,7 +280,7 @@ public class APIManager {
if (lowestBins != null && lowestBins.has(internalName)) {
JsonElement e = lowestBins.get(internalName);
if (e.isJsonPrimitive() && e.getAsJsonPrimitive().isNumber()) {
- return e.getAsBigDecimal().longValue();
+ return e.getAsLong();
}
}
return -1;
@@ -822,10 +822,11 @@ public class APIManager {
return keys;
}
- public double getBazaarOrBin(String internalName) {
+ public double getBazaarOrBin(String internalName, boolean useSellingPrice) {
+ String curr = (useSellingPrice ? "curr_sell" : "curr_buy");
JsonObject bazaarInfo = manager.auctionManager.getBazaarInfo(internalName);
- if (bazaarInfo != null && bazaarInfo.get("curr_buy") != null) {
- return bazaarInfo.get("curr_buy").getAsFloat();
+ if (bazaarInfo != null && bazaarInfo.get(curr) != null) {
+ return bazaarInfo.get(curr).getAsFloat();
} else {
return manager.auctionManager.getLowestBin(internalName);
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java
index 7b4542d0..07ec4a59 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java
@@ -190,8 +190,6 @@ public class CustomAH extends Gui {
private static final int SORT_MODE_LOW = 1;
private static final int SORT_MODE_SOON = 2;
- // private static final String[] rarities = {"COMMON", "UNCOMMON", "RARE", "EPIC",
-// "LEGENDARY", "MYTHIC", "SPECIAL", "VERY SPECIAL", "SUPREME", "DIVINE"};
private static final String[] rarityColours = {
"" + EnumChatFormatting.WHITE,
"" + EnumChatFormatting.GREEN, "" + EnumChatFormatting.BLUE, "" + EnumChatFormatting.DARK_PURPLE,
@@ -264,10 +262,8 @@ public class CustomAH extends Gui {
if (searchField == null || priceField == null) init();
if (System.currentTimeMillis() - lastOpen < 1000) Mouse.setGrabbed(false);
- //sortMode = SORT_MODE_HIGH;
rarityFilter = -1;
filterMyAuctions = false;
- //binFilter = BIN_FILTER_ALL;
enchFilter = ENCH_FILTER_ALL;
dungeonFilter = DUNGEON_FILTER_ALL;
@@ -995,14 +991,6 @@ public class CustomAH extends Gui {
searchField.drawTextBox();
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
- /*if(auctionIds.size() == 0 && searchField.getText().length() == 0) {
- drawRect(guiLeft+8, guiTop+17, guiLeft+170, guiTop+107+18*splits,
- new Color(100, 100, 100, 100).getRGB());
-
- FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
- int strWidth = fr.getStringWidth("Loading items...");
- fr.drawString("Loading items...", guiLeft+(8+170-strWidth)/2, guiTop+(17+107+18*splits)/2, Color.BLACK.getRGB());
- }*/
Minecraft.getMinecraft().getTextureManager().bindTexture(creativeInventoryTabs);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
@@ -1409,9 +1397,7 @@ public class CustomAH extends Gui {
for (String internalname : itemMatches) {
for (String aucid : manager.auctionManager.getAuctionsForInternalname(internalname)) {
APIManager.Auction auc = manager.auctionManager.getAuctionItems().get(aucid);
- if (doesAucMatch(auc)) {
- //matches.add(aucid);
- } else {
+ if (!doesAucMatch(auc)) {
dontMatch.add(aucid);
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java
index 62981a30..91365cd1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java
@@ -95,7 +95,6 @@ public class Commands {
ClientCommandHandler.instance.registerCommand(new ScreenCommand("neubuttons", GuiInvButtonEditor::new));
ClientCommandHandler.instance.registerCommand(new ScreenCommand("neuec", GuiEnchantColour::new));
ClientCommandHandler.instance.registerCommand(new ScreenCommand("neuoverlay", NEUOverlayPlacements::new));
- //ClientCommandHandler.instance.registerCommand(new ScreenCommand("neututorial", NeuTutorial::new));
ClientCommandHandler.instance.registerCommand(new AhCommand());
ClientCommandHandler.instance.registerCommand(new CalculatorCommand());
ClientCommandHandler.instance.registerCommand(new CalendarCommand());
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 138486c3..5f1fe191 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
@@ -23,13 +23,17 @@ import io.github.moulberry.notenoughupdates.BuildFlags;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
import io.github.moulberry.notenoughupdates.core.config.GuiPositionEditor;
+import io.github.moulberry.notenoughupdates.core.util.MiscUtils;
import io.github.moulberry.notenoughupdates.miscfeatures.FishingHelper;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.SpecialBlockZone;
import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
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 net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.command.CommandException;
@@ -62,7 +66,8 @@ public class DevTestCommand extends ClientCommandBase {
"a7d6b3f1-8425-48e5-8acc-9a38ab9b86f7", // whalker
"0ce87d5a-fa5f-4619-ae78-872d9c5e07fe", // ascynx
"a049a538-4dd8-43f8-87d5-03f09d48b4dc", // egirlefe
- "7a9dc802-d401-4d7d-93c0-8dd1bc98c70d" // efefury
+ "7a9dc802-d401-4d7d-93c0-8dd1bc98c70d", // efefury
+ "bb855349-dfd8-4125-a750-5fc2cf543ad5" // hannibal2
);
private static final String[] DEV_FAIL_STRINGS = {
@@ -114,8 +119,7 @@ public class DevTestCommand extends ClientCommandBase {
Minecraft.getMinecraft().getNetHandler().getNetworkManager().closeChannel(component);
return;
}
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- DEV_FAIL_STRINGS[devFailIndex++]));
+ Utils.addChatMessage(EnumChatFormatting.RED + DEV_FAIL_STRINGS[devFailIndex++]);
return;
}
if (args.length >= 1 && args[0].equalsIgnoreCase("profileinfo")) {
@@ -167,7 +171,8 @@ public class DevTestCommand extends ClientCommandBase {
return;
}
if (args.length == 1 && args[0].equalsIgnoreCase("dev")) {
- NotEnoughUpdates.INSTANCE.config.hidden.dev = true;
+ NotEnoughUpdates.INSTANCE.config.hidden.dev = !NotEnoughUpdates.INSTANCE.config.hidden.dev;
+ Utils.addChatMessage("§e[NEU] Dev mode " + (NotEnoughUpdates.INSTANCE.config.hidden.dev ? "§aenabled": "§cdisabled"));
return;
}
if (args.length == 1 && args[0].equalsIgnoreCase("saveconfig")) {
@@ -176,8 +181,7 @@ public class DevTestCommand extends ClientCommandBase {
}
if (args.length == 1 && args[0].equalsIgnoreCase("searchmode")) {
NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus = true;
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.AQUA +
- "I would never search"));
+ Utils.addChatMessage(EnumChatFormatting.AQUA + "I would never search");
return;
}
if (args.length == 1 && args[0].equalsIgnoreCase("bluehair")) {
@@ -187,11 +191,10 @@ public class DevTestCommand extends ClientCommandBase {
if (args.length == 2 && args[0].equalsIgnoreCase("openGui")) {
try {
NotEnoughUpdates.INSTANCE.openGui = (GuiScreen) Class.forName(args[1]).newInstance();
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "Opening gui: " + NotEnoughUpdates.INSTANCE.openGui));
+ Utils.addChatMessage("Opening gui: " + NotEnoughUpdates.INSTANCE.openGui);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | ClassCastException e) {
e.printStackTrace();
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Failed to open this GUI."));
+ Utils.addChatMessage("Failed to open this GUI.");
}
}
if (args.length == 1 && args[0].equalsIgnoreCase("center")) {
@@ -199,5 +202,16 @@ public class DevTestCommand extends ClientCommandBase {
double z = Math.floor(Minecraft.getMinecraft().thePlayer.posZ) + 0.5f;
Minecraft.getMinecraft().thePlayer.setPosition(x, Minecraft.getMinecraft().thePlayer.posY, z);
}
+ if (args.length >= 1 && args[0].equalsIgnoreCase("minion")) {
+ MinionHelperManager.getInstance().handleCommand(args);
+ }
+ if (args.length == 1 && args[0].equalsIgnoreCase("copytablist")) {
+ StringBuilder builder = new StringBuilder();
+ for (String name : TabListUtils.getTabList()) {
+ builder.append(name).append("\n");
+ }
+ MiscUtils.copyToClipboard(builder.toString());
+ Utils.addChatMessage("§e[NEU] Copied tablist to clipboard!");
+ }
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java
index e1504472..1d30a15f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.commands.dev;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
import io.github.moulberry.notenoughupdates.core.util.MiscUtils;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.command.CommandException;
@@ -290,11 +291,10 @@ public class PackDevCommand extends ClientCommandBase {
}
if ((single && closest == null) || (!single && result.length() == 0)) {
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "No " + typeFriendlyName + "s found within " + dist + " blocks."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "No " + typeFriendlyName + "s found within " + dist + " blocks.");
} else {
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.GREEN + "Copied " + typeFriendlyName + " data to clipboard"));
+ Utils.addChatMessage(
+ EnumChatFormatting.GREEN + "Copied " + typeFriendlyName + " data to clipboard");
return single ? livingBaseDataBuilder(closest, clazz) : result;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java
index e9d4eb44..ea417977 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java
@@ -24,11 +24,11 @@ import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
import io.github.moulberry.notenoughupdates.util.DiscordMarkdownBuilder;
import io.github.moulberry.notenoughupdates.util.HastebinUploader;
import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.BlockPos;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.common.ForgeVersion;
import net.minecraftforge.fml.client.FMLClientHandler;
@@ -119,10 +119,8 @@ public class StatsCommand extends ClientCommandBase {
}
private static void modPrefixedMessage(String message) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.GOLD + "[" + EnumChatFormatting.RED + "NotEnoughUpdates" + EnumChatFormatting.GOLD + "]: " +
- message));
-
+ Utils.addChatMessage(
+ EnumChatFormatting.GOLD + "[" + EnumChatFormatting.RED + "NotEnoughUpdates" + EnumChatFormatting.GOLD + "]: " + message);
}
private static String createStats() {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java
index a5a7bcca..3b697905 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java
@@ -20,10 +20,10 @@
package io.github.moulberry.notenoughupdates.commands.dungeon;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
public class DnCommand extends ClientCommandBase {
@@ -35,7 +35,6 @@ public class DnCommand extends ClientCommandBase {
@Override
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
Minecraft.getMinecraft().thePlayer.sendChatMessage("/warp dungeon_hub");
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.AQUA + "Warping to:" + EnumChatFormatting.YELLOW + " Deez Nuts lmao"));
+ Utils.addChatMessage(EnumChatFormatting.AQUA + "Warping to:" + EnumChatFormatting.YELLOW + " Deez Nuts lmao");
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java
index c1f88942..58bfbef2 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java
@@ -21,10 +21,10 @@ package io.github.moulberry.notenoughupdates.commands.dungeon;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import org.apache.commons.lang3.StringUtils;
@@ -40,19 +40,16 @@ public class JoinDungeonCommand extends ClientCommandBase {
Minecraft.getMinecraft().thePlayer.sendChatMessage("/join " + StringUtils.join(args, " "));
} else {
if (args.length != 1) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "Example Usage: /join f7, /join m6 or /join 7"));
+ Utils.addChatMessage(EnumChatFormatting.RED + "Example Usage: /join f7, /join m6 or /join 7");
} else {
String cataPrefix = "catacombs";
if (args[0].toLowerCase().startsWith("m")) {
cataPrefix = "master_catacombs";
}
String cmd = "/joindungeon " + cataPrefix + " " + args[0].charAt(args[0].length() - 1);
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.YELLOW + "Running command: " + cmd));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.YELLOW +
- "The dungeon should start soon. If it doesn't, make sure you have a party of 5 people"));
+ Utils.addChatMessage(EnumChatFormatting.YELLOW + "Running command: " + cmd);
+ Utils.addChatMessage(EnumChatFormatting.YELLOW +
+ "The dungeon should start soon. If it doesn't, make sure you have a party of 5 people");
Minecraft.getMinecraft().thePlayer.sendChatMessage(cmd);
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java
index f5381adb..3967edb4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java
@@ -24,6 +24,7 @@ import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
import io.github.moulberry.notenoughupdates.dungeons.GuiDungeonMapEditor;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.block.material.MapColor;
import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandException;
@@ -128,8 +129,7 @@ public class MapCommand extends ClientCommandBase {
e.printStackTrace();
}
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN +
- "Saved to file."));
+ Utils.addChatMessage(EnumChatFormatting.GREEN + "Saved to file.");
}
return;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java
index 5f709c4f..bc389ad4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java
@@ -41,18 +41,9 @@ public class FeaturesCommand extends ClientCommandBase {
@Override
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
+ Utils.addChatMessage("");
if (Constants.MISC == null || !Constants.MISC.has("featureslist")) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "WARNING: " + EnumChatFormatting.RESET +
- EnumChatFormatting.RED + "Could not load URL from repo."));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "" + EnumChatFormatting.RED + "Please run " + EnumChatFormatting.BOLD + "/neuresetrepo" +
- EnumChatFormatting.RESET + EnumChatFormatting.RED + " and " + EnumChatFormatting.BOLD + "restart your game" +
- EnumChatFormatting.RESET + EnumChatFormatting.RED + " in order to fix. " + EnumChatFormatting.DARK_RED +
- EnumChatFormatting.BOLD + "If that doesn't fix it" + EnumChatFormatting.RESET + EnumChatFormatting.RED +
- ", please join discord.gg/moulberry and post in #neu-support"));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
+ Utils.showOutdatedRepoNotification();
return;
}
String url = Constants.MISC.get("featureslist").getAsString();
@@ -60,9 +51,8 @@ public class FeaturesCommand extends ClientCommandBase {
Desktop desk = Desktop.getDesktop();
try {
desk.browse(new URI(url));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.DARK_PURPLE + "" + EnumChatFormatting.BOLD + "NEU" + EnumChatFormatting.RESET +
- EnumChatFormatting.GOLD + "> Opening Feature List in browser."));
+ Utils.addChatMessage( EnumChatFormatting.DARK_PURPLE + "" + EnumChatFormatting.BOLD + "NEU" + EnumChatFormatting.RESET +
+ EnumChatFormatting.GOLD + "> Opening Feature List in browser.");
} catch (URISyntaxException | IOException ignored) {
ChatComponentText clickTextFeatures = new ChatComponentText(
@@ -72,6 +62,6 @@ public class FeaturesCommand extends ClientCommandBase {
Minecraft.getMinecraft().thePlayer.addChatMessage(clickTextFeatures);
}
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
+ Utils.addChatMessage("");
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java
index 49123f45..3a47509d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java
@@ -22,9 +22,8 @@ package io.github.moulberry.notenoughupdates.commands.help;
import com.google.common.collect.Lists;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
-import net.minecraft.client.Minecraft;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.command.ICommandSender;
-import net.minecraft.util.ChatComponentText;
import java.util.ArrayList;
@@ -66,7 +65,7 @@ public class HelpCommand extends ClientCommandBase {
"\u00a76/neupackdev \u00a7r\u00a77- pack creator command - getnpc, getmob(s), getarmorstand(s), getall. Optional radius argument for all."
);
for (String neuHelpMessage : neuHelpMessages) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(neuHelpMessage));
+ Utils.addChatMessage(neuHelpMessage);
}
if (NotEnoughUpdates.INSTANCE.config.hidden.dev) {
ArrayList<String> neuDevHelpMessages = Lists.newArrayList(
@@ -76,7 +75,7 @@ public class HelpCommand extends ClientCommandBase {
);
for (String neuDevHelpMessage : neuDevHelpMessages) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(neuDevHelpMessage));
+ Utils.addChatMessage(neuDevHelpMessage);
}
}
String[] helpInfo = {
@@ -89,8 +88,7 @@ public class HelpCommand extends ClientCommandBase {
};
for (String message : helpInfo) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(message));
+ Utils.addChatMessage(message);
}
-
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java
index 9938403c..793e652e 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java
@@ -22,10 +22,9 @@ package io.github.moulberry.notenoughupdates.commands.help;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
-import net.minecraft.client.Minecraft;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
-import net.minecraft.util.ChatComponentText;
import java.io.File;
@@ -43,9 +42,9 @@ public class LinksCommand extends ClientCommandBase {
try {
JsonObject update = NotEnoughUpdates.INSTANCE.manager.getJsonFromFile(updateJson);
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
+ Utils.addChatMessage("");
NotEnoughUpdates.INSTANCE.displayLinks(update,0 );
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
+ Utils.addChatMessage("");
} catch (Exception ignored) {
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java
index d51d4d2e..1ca398ef 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java
@@ -22,10 +22,9 @@ package io.github.moulberry.notenoughupdates.commands.misc;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.auction.CustomAHGui;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
-import net.minecraft.client.Minecraft;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import org.apache.commons.lang3.StringUtils;
@@ -38,12 +37,11 @@ public class AhCommand extends ClientCommandBase {
@Override
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "You must be on SkyBlock to use this feature."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "You must be on SkyBlock to use this feature.");
} else if (NotEnoughUpdates.INSTANCE.config.apiData.apiKey == null ||
NotEnoughUpdates.INSTANCE.config.apiData.apiKey.trim().isEmpty()) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "Can't open NEU AH: an api key is not set. Run /api new and put the result in settings."));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "Can't open NEU AH: an api key is not set. Run /api new and put the result in settings.");
} else {
NotEnoughUpdates.INSTANCE.openGui = new CustomAHGui();
NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.lastOpen = System.currentTimeMillis();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java
index 2ba93585..b01f106b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java
@@ -26,8 +26,8 @@ import net.minecraft.command.ICommandSender;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
-import java.text.DecimalFormat;
import java.math.BigDecimal;
+import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java
index 67430ffa..bbab316e 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java
@@ -22,11 +22,10 @@ package io.github.moulberry.notenoughupdates.commands.misc;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
import io.github.moulberry.notenoughupdates.cosmetics.GuiCosmetics;
-import net.minecraft.client.Minecraft;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
public class CosmeticsCommand extends ClientCommandBase {
@@ -38,8 +37,8 @@ public class CosmeticsCommand extends ClientCommandBase {
@Override
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
if (!OpenGlHelper.isFramebufferEnabled() && NotEnoughUpdates.INSTANCE.config.notifications.doFastRenderNotif) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "NEU Cosmetics do not work with OptiFine Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it."));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "NEU Cosmetics do not work with OptiFine Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.");
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java
index 2b184fa0..28c2893d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java
@@ -60,89 +60,4 @@ public class CustomizeCommand extends ClientCommandBase {
NotEnoughUpdates.INSTANCE.openGui = new GuiItemCustomize(held, heldUUID);
}
-
- /*SimpleCommand itemRenameCommand = new SimpleCommand("neurename", new SimpleCommand.ProcessCommandRunnable() {
- public void processCommand(ICommandSender sender, String[] args) {
- if (args.length == 0) {
- args = new String[]{"help"};
- }
- String heldUUID = NotEnoughUpdates.INSTANCE.manager.getUUIDForItem(Minecraft.getMinecraft().thePlayer.getHeldItem());
- switch (args[0].toLowerCase()) {
- case "clearall":
- NotEnoughUpdates.INSTANCE.manager.itemRenameJson = new JsonObject();
- NotEnoughUpdates.INSTANCE.manager.saveItemRenameConfig();
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "[NEU] Cleared custom name for all items"));
- break;
- case "clear":
- if (heldUUID == null) {
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Can't clear rename - no UUID"));
- return;
- }
- NotEnoughUpdates.INSTANCE.manager.itemRenameJson.remove(heldUUID);
- NotEnoughUpdates.INSTANCE.manager.saveItemRenameConfig();
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "[NEU] Cleared custom name for held item"));
- break;
- case "copyuuid":
- if (heldUUID == null) {
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Can't clear rename - no UUID"));
- return;
- }
- StringSelection selection = new StringSelection(heldUUID);
- Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "[NEU] UUID copied to clipboard"));
- break;
- case "uuid":
- if (heldUUID == null) {
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Can't get UUID - no UUID"));
- return;
- }
- ChatStyle style = new ChatStyle();
- style.setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
- new ChatComponentText(EnumChatFormatting.GRAY + "Click to copy to clipboard")));
- style.setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/neurename copyuuid"));
-
- ChatComponentText text = new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] The UUID of your currently held item is: " +
- EnumChatFormatting.GREEN + heldUUID);
- text.setChatStyle(style);
- sender.addChatMessage(text);
- break;
- case "set":
- if (heldUUID == null) {
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Can't rename item - no UUID"));
- return;
- }
- if (args.length == 1) {
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Usage: /neurename set [name...]"));
- return;
- }
- StringBuilder sb = new StringBuilder();
- for (int i = 1; i < args.length; i++) {
- sb.append(args[i]);
- if (i < args.length - 1) sb.append(" ");
- }
- String name = sb.toString()
- .replace("\\&", "{amp}")
- .replace("&", "\u00a7")
- .replace("{amp}", "&");
- name = new UnicodeUnescaper().translate(name);
- NotEnoughUpdates.INSTANCE.manager.itemRenameJson.addProperty(heldUUID, name);
- NotEnoughUpdates.INSTANCE.manager.saveItemRenameConfig();
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + "[NEU] Set custom name for held item"));
- break;
- default:
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[NEU] Unknown subcommand \"" + args[0] + "\""));
- case "help":
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] Available commands:"));
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "help: Print this message"));
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "clearall: Clears all custom names "
- + EnumChatFormatting.BOLD + "(Cannot be undone)"));
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "clear: Clears held item name "
- + EnumChatFormatting.BOLD + "(Cannot be undone)"));
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "uuid: Returns the UUID of the currently held item"));
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "set: Sets the custom name of the currently held item"));
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Usage: /neurename set [name...]"));
-
- }
- }
- });*/
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java
index 77377917..23852ab6 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java
@@ -78,8 +78,8 @@ public class PeekCommand extends ClientCommandBase {
}
if (peekScheduledFuture != null && !peekScheduledFuture.isDone()) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "[PEEK] New peek command was run, cancelling old one."));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "[PEEK] New peek command was run, cancelling old one.");
peekScheduledFuture.cancel(true);
}
@@ -136,8 +136,7 @@ public class PeekCommand extends ClientCommandBase {
EnumChatFormatting.STRIKETHROUGH + "-=-"), id);
if (skyblockInfo == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.YELLOW + "Skills API disabled!"));
+ Utils.addChatMessage(EnumChatFormatting.YELLOW + "Skills API disabled!");
} else {
float totalSkillLVL = 0;
float totalSkillCount = 0;
@@ -208,20 +207,17 @@ public class PeekCommand extends ClientCommandBase {
overallScore += cata * cata / 2000f;
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- g + "Combat: " + combatPrefix + (int) Math.floor(combat) +
+ Utils.addChatMessage(g + "Combat: " + combatPrefix + (int) Math.floor(combat) +
(cata > 0 ? g + " - Cata: " + cataPrefix + cata : "") +
- g + " - AVG: " + avgPrefix + (int) Math.floor(avgSkillLVL)));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- g + "Slayer: " + zombiePrefix + (int) Math.floor(zombie) + g + "-" +
+ g + " - AVG: " + avgPrefix + (int) Math.floor(avgSkillLVL));
+ Utils.addChatMessage(g + "Slayer: " + zombiePrefix + (int) Math.floor(zombie) + g + "-" +
spiderPrefix + (int) Math.floor(spider) + g + "-" +
wolfPrefix + (int) Math.floor(wolf) + g + "-" +
endermanPrefix + (int) Math.floor(enderman) + g + "-" +
- blazePrefix + (int) Math.floor(blaze)));
+ blazePrefix + (int) Math.floor(blaze));
}
if (stats == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.YELLOW + "Skills, collection and/or inventory apis disabled!"));
+ Utils.addChatMessage(EnumChatFormatting.YELLOW + "Skills, collection and/or inventory apis disabled!");
} else {
int health = (int) stats.get("health");
int defence = (int) stats.get("defence");
@@ -249,11 +245,10 @@ public class PeekCommand extends ClientCommandBase {
: EnumChatFormatting.YELLOW)
: EnumChatFormatting.RED;
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- g + "Stats : " + healthPrefix + health + EnumChatFormatting.RED + "\u2764 " +
- defencePrefix + defence + EnumChatFormatting.GREEN + "\u2748 " +
- strengthPrefix + strength + EnumChatFormatting.RED + "\u2741 " +
- intelligencePrefix + intelligence + EnumChatFormatting.AQUA + "\u270e "));
+ Utils.addChatMessage( g + "Stats : " + healthPrefix + health + EnumChatFormatting.RED + "\u2764 " +
+ defencePrefix + defence + EnumChatFormatting.GREEN + "\u2748 " +
+ strengthPrefix + strength + EnumChatFormatting.RED + "\u2741 " +
+ intelligencePrefix + intelligence + EnumChatFormatting.AQUA + "\u270e ");
}
float bankBalance = Utils.getElementAsFloat(Utils.getElement(profileInfo, "banking.balance"), -1);
float purseBalance = Utils.getElementAsFloat(Utils.getElement(profileInfo, "coin_purse"), 0);
@@ -275,11 +270,10 @@ public class PeekCommand extends ClientCommandBase {
(money > 200 * 1000 * 1000
? EnumChatFormatting.GREEN
: EnumChatFormatting.YELLOW) : EnumChatFormatting.RED;
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- g + "Purse: " + moneyPrefix + Utils.shortNumberFormat(purseBalance, 0) + g + " - Bank: " +
- (bankBalance == -1 ? EnumChatFormatting.YELLOW + "N/A" : moneyPrefix +
- (isMe ? "4.8b" : Utils.shortNumberFormat(bankBalance, 0))) +
- (networth > 0 ? g + " - Net: " + moneyPrefix + Utils.shortNumberFormat(networth, 0) : "")));
+ Utils.addChatMessage( g + "Purse: " + moneyPrefix + Utils.shortNumberFormat(purseBalance, 0) + g + " - Bank: " +
+ (bankBalance == -1 ? EnumChatFormatting.YELLOW + "N/A" : moneyPrefix +
+ (isMe ? "4.8b" : Utils.shortNumberFormat(bankBalance, 0))) +
+ (networth > 0 ? g + " - Net: " + moneyPrefix + Utils.shortNumberFormat(networth, 0) : ""));
overallScore += Math.min(2, money / (100f * 1000 * 1000));
@@ -295,8 +289,7 @@ public class PeekCommand extends ClientCommandBase {
String col = NotEnoughUpdates.petRarityToColourMap.get(activePetTier);
if (col == null) col = EnumChatFormatting.LIGHT_PURPLE.toString();
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(g + "Pet : " +
- col + WordUtils.capitalizeFully(activePet.replace("_", " "))));
+ Utils.addChatMessage(g + "Pet : " + col + WordUtils.capitalizeFully(activePet.replace("_", " ")));
String overall = "Skywars Main";
if (isMe) {
@@ -321,8 +314,7 @@ public class PeekCommand extends ClientCommandBase {
overall = EnumChatFormatting.RED + "Played SkyBlock";
}
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(g + "Overall score: " +
- overall + g + " (" + Math.round(overallScore * 10) / 10f + ")"));
+ Utils.addChatMessage(g + "Overall score: " + overall + g + " (" + Math.round(overallScore * 10) / 10f + ")");
peekCommandExecutorService.shutdownNow();
} else {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java
index 887cd28f..26468e39 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.commands.profile;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.command.ICommandSender;
@@ -38,32 +39,31 @@ public class ViewProfileCommand extends ClientCommandBase {
public static final Consumer<String[]> RUNNABLE = (args) -> {
if (!OpenGlHelper.isFramebufferEnabled()) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "Some parts of the profile viewer do not work with OptiFine Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it."));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "Some parts of the profile viewer do not work with OptiFine Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.");
}
if (NotEnoughUpdates.INSTANCE.config.apiData.apiKey == null ||
NotEnoughUpdates.INSTANCE.config.apiData.apiKey.trim().isEmpty()) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "Can't view profile, an API key is not set. Run /api new and put the result in settings."));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "Can't view profile, an API key is not set. Run /api new and put the result in settings.");
} else if (args.length == 0) {
NotEnoughUpdates.profileViewer.getProfileByName(Minecraft.getMinecraft().thePlayer.getName(), profile -> {
if (profile == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "Invalid player name/API key. Maybe the API is down? Try /api new."));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "Invalid player name/API key. Maybe the API is down? Try /api new.");
} else {
profile.resetCache();
NotEnoughUpdates.INSTANCE.openGui = new GuiProfileViewer(profile);
}
});
} else if (args.length > 1) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "Too many arguments. Usage: /neuprofile [name]"));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "Too many arguments. Usage: /neuprofile [name]");
} else {
NotEnoughUpdates.profileViewer.getProfileByName(args[0], profile -> {
if (profile == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "Invalid player name/api key. Maybe the API is down? Try /api new."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "Invalid player name/api key. Maybe the API is down? Try /api new.");
} else {
profile.resetCache();
NotEnoughUpdates.INSTANCE.openGui = new GuiProfileViewer(profile);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/ArrowPagesUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/ArrowPagesUtils.java
new file mode 100644
index 00000000..86430804
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/ArrowPagesUtils.java
@@ -0,0 +1,190 @@
+/*
+ * 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.util;
+
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.util.MathHelper;
+import net.minecraft.util.ResourceLocation;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+import java.util.function.Consumer;
+
+public class ArrowPagesUtils {
+
+ public static final int BUTTON_POSITION_RIGHT_OFFSET_X = 37;
+ public static final int PAGE_STRING_OFFSET_X = 22;
+ public static final int PAGE_STRING_OFFSET_Y = 6;
+
+ public static final int BUTTON_WIDTH = 7;
+ public static final int BUTTON_HEIGHT = 11;
+
+ public static final ResourceLocation resourcePacksTexture = new ResourceLocation("textures/gui/resource_packs.png");
+
+ public static void onDraw(int guiLeft, int guiTop, int[] topLeftButton, int currentPage, int totalPages) {
+ if (totalPages < 2) return;
+
+ final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft());
+ final int scaledWidth = scaledresolution.getScaledWidth();
+ final int scaledHeight = scaledresolution.getScaledHeight();
+ int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth;
+ int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1;
+
+ int buttonPositionLeftX = topLeftButton[0];
+ int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X;
+ int pageStringX = buttonPositionLeftX + PAGE_STRING_OFFSET_X;
+ int buttonPositionY = topLeftButton[1];
+ int pageStringY = buttonPositionY + PAGE_STRING_OFFSET_Y;
+
+ boolean leftSelected = isWithinRect(
+ mouseX - guiLeft,
+ mouseY - guiTop,
+ buttonPositionLeftX,
+ buttonPositionY,
+ BUTTON_WIDTH,
+ BUTTON_HEIGHT
+ );
+ boolean rightSelected = isWithinRect(
+ mouseX - guiLeft,
+ mouseY - guiTop,
+ buttonPositionRightX,
+ buttonPositionY,
+ BUTTON_WIDTH,
+ BUTTON_HEIGHT
+ );
+ Minecraft.getMinecraft().getTextureManager().bindTexture(resourcePacksTexture);
+
+ if (currentPage != 0)
+ Utils.drawTexturedRect(
+ guiLeft + buttonPositionLeftX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT,
+ 34 / 256f, 48 / 256f,
+ leftSelected ? 37 / 256f : 5 / 256f, leftSelected ? 59 / 256f : 27 / 256f
+ );
+ if (currentPage != totalPages - 1)
+ Utils.drawTexturedRect(
+ guiLeft + buttonPositionRightX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT,
+ 10 / 256f, 24 / 256f,
+ rightSelected ? 37 / 256f : 5 / 256f, rightSelected ? 59 / 256f : 27 / 256f
+ );
+ GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
+
+ String selectedPage = (currentPage + 1) + "/" + totalPages;
+
+ FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRendererObj;
+ Utils.drawStringCenteredScaledMaxWidth(selectedPage, fontRendererObj,
+ guiLeft + pageStringX, guiTop + pageStringY, false, 28, Color.BLACK.getRGB()
+ );
+ }
+
+ public static boolean onPageSwitchKey(
+ int currentPage,
+ int totalPages,
+ Consumer<Integer> pageChange
+ ) {
+
+ int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
+ if (Keyboard.getEventKeyState() && keyPressed == Keyboard.KEY_LEFT) {
+ int newPage = currentPage - 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ return true;
+ }
+ if (Keyboard.getEventKeyState() && keyPressed == Keyboard.KEY_RIGHT) {
+ int newPage = currentPage + 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ return true;
+ }
+
+ return false;
+ }
+
+ public static boolean onPageSwitchMouse(
+ int guiLeft,
+ int guiTop,
+ int[] topLeft,
+ int currentPage,
+ int totalPages,
+ Consumer<Integer> pageChange
+ ) {
+
+ int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
+ if (Keyboard.getEventKeyState() && keyPressed == Keyboard.KEY_LEFT) {
+ int newPage = currentPage - 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ return true;
+ }
+ if (Keyboard.getEventKeyState() && keyPressed == Keyboard.KEY_RIGHT) {
+ int newPage = currentPage + 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ return true;
+ }
+
+ final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft());
+ final int scaledWidth = scaledresolution.getScaledWidth();
+ final int scaledHeight = scaledresolution.getScaledHeight();
+ int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth;
+ int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1;
+
+ int buttonPositionLeftX = topLeft[0];
+ int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X;
+ int buttonPositionY = topLeft[1];
+
+ if (isWithinRect(
+ mouseX - guiLeft,
+ mouseY - guiTop,
+ buttonPositionLeftX,
+ buttonPositionY,
+ BUTTON_WIDTH,
+ BUTTON_HEIGHT
+ ) &&
+ currentPage > 0) {
+ int newPage = currentPage - 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ Utils.playPressSound();
+ return true;
+ }
+
+ if (isWithinRect(
+ mouseX - guiLeft,
+ mouseY - guiTop,
+ buttonPositionRightX,
+ buttonPositionY,
+ BUTTON_WIDTH,
+ BUTTON_HEIGHT
+ ) &&
+ currentPage < totalPages) {
+ int newPage = currentPage + 1;
+ pageChange.accept(MathHelper.clamp_int(newPage, 0, totalPages - 1));
+ Utils.playPressSound();
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean isWithinRect(int x, int y, int topLeftX, int topLeftY, int width, int height) {
+ return topLeftX <= x && x < topLeftX + width
+ && topLeftY <= y && y < topLeftY + height;
+ }
+}
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 a4f814d1..7ea9cd00 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
@@ -102,4 +102,20 @@ public class StringUtils {
int start = string.lastIndexOf(toReplace);
return string.substring(0, start) + replacement + string.substring(start + toReplace.length());
}
+
+ public static String removeLastWord(String string, String splitString) {
+ try {
+ String[] split = string.split(splitString);
+ String rawTier = split[split.length - 1];
+ return string.substring(0, string.length() - rawTier.length() - 1);
+ } catch (StringIndexOutOfBoundsException e) {
+ throw new RuntimeException("removeLastWord: '" + string + "'", e);
+ }
+ }
+
+ public static String firstUpperLetter(String text) {
+ if (text.isEmpty()) return text;
+ String firstLetter = ("" + text.charAt(0)).toUpperCase();
+ return firstLetter + text.substring(1);
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java
index ed2afd69..50eff87a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java
@@ -401,14 +401,18 @@ public class RenderUtils {
}
public static void renderWayPoint(List<String> str, Vec3i loc, float partialTicks) {
- renderWayPoint(str, new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks);
+ renderWayPoint(str, new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks, false);
}
public static void renderWayPoint(String str, Vector3f loc, float partialTicks) {
- renderWayPoint(Arrays.asList(str), loc, partialTicks);
+ renderWayPoint(Arrays.asList(str), loc, partialTicks, false);
+ }
+
+ public static void renderWayPoint(Vec3i loc, float partialTicks) {
+ renderWayPoint(Arrays.asList(""), new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks, true);
}
- public static void renderWayPoint(List<String> lines, Vector3f loc, float partialTicks) {
+ public static void renderWayPoint(List<String> lines, Vector3f loc, float partialTicks, boolean onlyShowDistance) {
GlStateManager.alphaFunc(516, 0.1F);
GlStateManager.pushMatrix();
@@ -432,7 +436,7 @@ public class RenderUtils {
GlStateManager.translate(x, y, z);
GlStateManager.translate(0, viewer.getEyeHeight(), 0);
- lines = new ArrayList<>(lines);
+ lines = onlyShowDistance ? new ArrayList<>() : new ArrayList<>(lines);
lines.add(EnumChatFormatting.YELLOW.toString() + Math.round(dist) + "m");
renderNametag(lines);
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 a4c5a60a..88c89773 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java
@@ -122,9 +122,6 @@ public class DungeonMap {
private int startRoomY = -1;
private int connectorSize = 5;
private int roomSize = 0;
-
- //private final List<MapDecoration> decorations = new ArrayList<>();
- //private final List<MapDecoration> lastDecorations = new ArrayList<>();
private long lastDecorationsMillis = -1;
private long lastLastDecorationsMillis = -1;
@@ -1475,9 +1472,7 @@ public class DungeonMap {
}
}
- //System.out.println("--- PERM START ---");
for (Map.Entry<String, Integer> entry : smallestPermutation.entrySet()) {
- //System.out.println(entry.getKey() + ":" + entry.getValue() + " : Total dist: " + smallestTotalDistance);
finalUsedIndexes.add(entry.getValue());
playerMarkerMapPositions.put(entry.getKey(), positions.get(entry.getValue()));
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java
index 8ce9d505..735fa3e6 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java
@@ -152,15 +152,6 @@ public class GuiDungeonMapEditor extends GuiScreen {
public GuiDungeonMapEditor() {
DungeonMapConfig options = NotEnoughUpdates.INSTANCE.config.dungeonMap;
- //Map Border Size
- //buttons.add(new Button(0, 6, 37, "Small", options.dmBorderSize));
- //buttons.add(new Button(1, 52, 37, "Medium", options.dmBorderSize));
- //buttons.add(new Button(2, 98, 37, "Large", options.dmBorderSize));
-
- //Map Rooms Size
- //buttons.add(new Button(3, 6, 67+19, "Small", options.dmRoomSize));
- //buttons.add(new Button(4, 52, 67+19, "Medium", options.dmRoomSize));
- //buttons.add(new Button(5, 98, 67+19, "Large", options.dmRoomSize));
//Map Border Styles
buttons.add(new Button(6, 6, 97 + 30, "None"));
@@ -241,9 +232,6 @@ public class GuiDungeonMapEditor extends GuiScreen {
e.printStackTrace();
}
- //buttons.add(new Button(29, 52, 86+19, "XLarge", options.dmRoomSize));
- //buttons.add(new Button(30, 52, 56, "XLarge", options.dmBorderSize));
-
{
double val = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur;
String strVal;
@@ -466,7 +454,6 @@ public class GuiDungeonMapEditor extends GuiScreen {
button.render();
}
- //List<String> textLines, final int mouseX, final int mouseY, final int screenWidth, final int screenHeight, final int maxTextWidth, FontRenderer font
if (tooltipToDisplay != null) {
Utils.drawHoveringText(
tooltipToDisplay,
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/events/ProfileDataLoadedEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/events/ProfileDataLoadedEvent.java
new file mode 100644
index 00000000..956acfe0
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/events/ProfileDataLoadedEvent.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.events;
+
+import com.google.gson.JsonObject;
+
+import javax.annotation.Nullable;
+
+//TODO extend the usage of this event (accessory bag and storage data)
+public class ProfileDataLoadedEvent extends NEUEvent {
+
+ @Nullable
+ private final JsonObject data;
+
+ public ProfileDataLoadedEvent(@Nullable JsonObject entireApiResponse) {
+ this.data = entireApiResponse;
+ }
+
+ @Nullable
+ public JsonObject getData() {
+ return data;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java
index 0b1963d6..421bc798 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/infopanes/DevInfoPane.java
@@ -25,7 +25,6 @@ import io.github.moulberry.notenoughupdates.NEUOverlay;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.block.Block;
-import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
@@ -33,7 +32,6 @@ import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.oredict.ShapedOreRecipe;
@@ -60,24 +58,6 @@ public class DevInfoPane extends TextInfoPane {
private String getText() {
String text = "";
- /*for(Map.Entry<String, JsonObject> item : manager.getItemInformation().entrySet()) {
- if(!item.getValue().has("infoType") || item.getValue().get("infoType").getAsString().isEmpty()) {
- text += item.getKey() + "\n";
- }
- }*/
- /*for(String s : manager.neuio.getRemovedItems(manager.getItemInformation().keySet())) {
- text += s + "\n";
- }
-
- if(true) return text;*/
-
- /*for(Map.Entry<String, JsonObject> item : manager.getItemInformation().entrySet()) {
- if(!item.getValue().has("infoType") || item.getValue().get("infoType").getAsString().isEmpty()) {
- text += item.getKey() + "\n";
- }
- }*/
- //if(true) return text;
-
for (String internalname : manager.auctionManager.getItemAuctionInfoKeySet()) {
if (internalname.matches("^.*-[0-9]{1,3}$")) continue;
if (!manager.getItemInformation().containsKey(internalname)) {
@@ -86,23 +66,11 @@ public class DevInfoPane extends TextInfoPane {
}
}
- /*for(Map.Entry<String, JsonElement> entry : manager.getAuctionPricesJson().get("prices").getAsJsonObject().entrySet()) {
- if(!manager.getItemInformation().keySet().contains(entry.getKey())) {
- if(entry.getKey().contains("-")) {
- continue;
- }
- if(entry.getKey().startsWith("PERFECT")) continue;
- if(Item.itemRegistry.getObject(new ResourceLocation(entry.getKey().toLowerCase())) != null) {
- continue;
- }
- text += entry.getKey() + "\n";
- }
- }*/
+
return text;
}
//#region add vanilla items
-
AtomicBoolean running = new AtomicBoolean(false);
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
@@ -555,7 +523,6 @@ public class DevInfoPane extends TextInfoPane {
if (stack.getItemDamage() != 0 && stack.getItemDamage() < 32000) {
stacki += "-" + stack.getItemDamage();
}
- //stacki += ":"+stack.stackSize;
stacki += ":1";
}
}
@@ -595,7 +562,6 @@ public class DevInfoPane extends TextInfoPane {
if (stack.getItemDamage() != 0 && stack.getItemDamage() < 32000) {
stacki += "-" + stack.getItemDamage();
}
- //stacki += ":"+stack.stackSize;
stacki += ":1";
}
}
@@ -645,7 +611,6 @@ public class DevInfoPane extends TextInfoPane {
if (stack.getItemDamage() != 0 && stack.getItemDamage() < 32000) {
stacki += "-" + stack.getItemDamage();
}
- //stacki += ":"+stack.stackSize;
stacki += ":1";
}
}
@@ -689,7 +654,7 @@ public class DevInfoPane extends TextInfoPane {
json.addProperty("modver", NotEnoughUpdates.VERSION);
try {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + internalname));
+ Utils.addChatMessage("Added: " + internalname);
manager.writeJsonDefaultDir(json, internalname + ".json");
manager.loadItem(internalname);
} catch (IOException ignored) {
@@ -705,7 +670,6 @@ public class DevInfoPane extends TextInfoPane {
for (String bukkit : bukkitList) {
String internalname = bukkit.split("@")[0];
if (true || !manager.getItemInformation().containsKey(internalname)) {
- //System.out.println("adding vanilla: " + internalname);
String vanilla = internalname.toLowerCase().replace("_item", "");
if (bukkit.contains("@")) {
vanilla = bukkit.split("@")[1];
@@ -750,7 +714,6 @@ public class DevInfoPane extends TextInfoPane {
if (stack.getItemDamage() != 0 && stack.getItemDamage() < 32000) {
stacki += "-" + stack.getItemDamage();
}
- //stacki += ":"+stack.stackSize;
stacki += ":1";
}
}
@@ -801,7 +764,6 @@ public class DevInfoPane extends TextInfoPane {
if (stack.getItemDamage() != 0 && stack.getItemDamage() < 32000) {
stacki += "-" + stack.getItemDamage();
}
- //stacki += ":"+stack.stackSize;
stacki += ":1";
}
}
@@ -839,7 +801,6 @@ public class DevInfoPane extends TextInfoPane {
if (stack.getItemDamage() != 0 && stack.getItemDamage() < 32000) {
stacki += "-" + stack.getItemDamage();
}
- //stacki += ":"+stack.stackSize;
stacki += ":1";
}
}
@@ -887,7 +848,6 @@ public class DevInfoPane extends TextInfoPane {
if (stack.getItemDamage() != 0 && stack.getItemDamage() < 32000) {
stacki += "-" + stack.getItemDamage();
}
- //stacki += ":"+stack.stackSize;
stacki += ":1";
}
}
@@ -919,7 +879,7 @@ public class DevInfoPane extends TextInfoPane {
json.addProperty("clickcommand", "");
try {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + internalname));
+ Utils.addChatMessage("Added: " + internalname);
manager.writeJsonDefaultDir(json, internalname + ".json");
manager.loadItem(internalname);
} catch (IOException ignored) {
@@ -952,7 +912,7 @@ public class DevInfoPane extends TextInfoPane {
json.addProperty("clickcommand", "viewrecipe");
json.add("recipe", entry.getValue());
try {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + internalname));
+ Utils.addChatMessage("Added: " + internalname);
if (entry.getKey() != 0 && entry.getKey() < 32000) {
manager.writeJsonDefaultDir(json, internalname + "-" + entry.getKey() + ".json");
} else {
@@ -967,126 +927,7 @@ public class DevInfoPane extends TextInfoPane {
}
}
- //for(Map.Entry<String, JsonObject> item : manager.getItemInformation().entrySet()) {
- /*if(!item.getValue().has("infoType") || item.getValue().get("infoType").getAsString().isEmpty()) {
- if(item.getValue().has("info") && item.getValue().get("info").getAsJsonArray().size()>0) {
- item.getValue().addProperty("infoType", "WIKI_URL");
- try {
- manager.writeJsonDefaultDir(item.getValue(), item.getKey()+".json");
- } catch(IOException e){}
- manager.loadItem(item.getKey());
- }
- }*/
- /*if(item.getKey().startsWith("PET_ITEM_")) {
- item.getValue().addProperty("infoType", "WIKI_URL");
- JsonArray array = new JsonArray();
- array.add(new JsonPrimitive("https://hypixel-skyblock.fandom.com/wiki/Pet_Items"));
- item.getValue().add("info", array);
- try {
- manager.writeJsonDefaultDir(item.getValue(), item.getKey()+".json");
- } catch(IOException e){}
- manager.loadItem(item.getKey());
- }*/
- /*if(!item.getValue().has("infoType") || item.getValue().get("infoType").getAsString().isEmpty()) {
- //String prettyName =
-
- String itemS = item.getKey().split("-")[0].split(";")[0];
- StringBuilder prettyName = new StringBuilder();
- boolean capital = true;
- for(int i=0; i<itemS.length(); i++) {
- char c = itemS.charAt(i);
- if(capital) {
- prettyName.append(String.valueOf(c).toUpperCase());
- capital = false;
- } else {
- prettyName.append(String.valueOf(c).toLowerCase());
- }
- if(String.valueOf(c).equals("_")) {
- capital = true;
- }
- }
- String prettyNameS = prettyName.toString();
- File f = manager.getWebFile("https://hypixel-skyblock.fandom.com/wiki/"+prettyNameS);
- if(f == null) {
- continue;
- //#REDIRECT [[Armor of Magma]]
- }
- StringBuilder sb = new StringBuilder();
- try(BufferedReader br = new BufferedReader(new InputStreamReader(
- new FileInputStream(f), StandardCharsets.UTF_8))) {
- String l;
- while((l = br.readLine()) != null){
- sb.append(l).append("\n");
- }
- } catch(IOException e) {
- continue;
- }
- if(sb.toString().isEmpty()) {
- continue;
- }
- if(sb.toString().startsWith("#REDIRECT")) {
- prettyNameS = sb.toString().split("\\[\\[")[1].split("]]")[0].replaceAll(" ", "_");
- }
- item.getValue().addProperty("infoType", "WIKI_URL");
- JsonArray array = new JsonArray();
- array.add(new JsonPrimitive("https://hypixel-skyblock.fandom.com/wiki/"+prettyNameS));
- item.getValue().add("info", array);
- try {
- manager.writeJsonDefaultDir(item.getValue(), item.getKey()+".json");
- } catch(IOException e){}
- manager.loadItem(item.getKey());
- }*/
}
-
- /*if(running.get()) {
- List<String> add = new ArrayList<>();
- for(Map.Entry<String, JsonObject> item : manager.getItemInformation().entrySet()) {
- if(item.getValue().has("recipe")) {
- if(!item.getKey().contains("-") && !item.getKey().contains(";")) {
- add.add(item.getKey());
- }
- }
- }
- AtomicInteger index = new AtomicInteger(0);
-
- ses.schedule(new Runnable() {
- public void run() {
- if(!running.get()) return;
-
- int i = index.getAndIncrement();
- String item = add.get(i).split("-")[0].split(";")[0];
- Minecraft.getMinecraft().thePlayer.sendChatMessage("/viewrecipe " + item);
- ses.schedule(this, 1000L, TimeUnit.MILLISECONDS);
- }
- }, 1000L, TimeUnit.MILLISECONDS);
- }*/
- //}
- /*if(Keyboard.isKeyDown(Keyboard.KEY_J) && !running) {
- running = true;
- List<String> add = new ArrayList<>();
- for(Map.Entry<String, JsonElement> entry : manager.getAuctionPricesJson().get("prices").getAsJsonObject().entrySet()) {
- if(!manager.getItemInformation().keySet().contains(entry.getKey())) {
- if(entry.getKey().contains("-")) {
- continue;
- }
- if(entry.getKey().startsWith("PERFECT")) continue;
- if(Item.itemRegistry.getObject(new ResourceLocation(entry.getKey().toLowerCase())) != null) {
- continue;
- }
- add.add(entry.getKey());
- }
- }
- AtomicInteger index = new AtomicInteger(0);
-
- ses.schedule(new Runnable() {
- public void run() {
- int i = index.getAndIncrement();
- String item = add.get(i).split("-")[0].split(";")[0];
- Minecraft.getMinecraft().thePlayer.sendChatMessage("/viewrecipe " + item);
- ses.schedule(this, 1000L, TimeUnit.MILLISECONDS);
- }
- }, 1000L, TimeUnit.MILLISECONDS);
- }*/
return false;
}
//#endregion
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/GuiElementTextField.java b/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/GuiElementTextField.java
index 71c4d498..7cc96d42 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/GuiElementTextField.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/itemeditor/GuiElementTextField.java
@@ -557,8 +557,6 @@ public class GuiElementTextField extends GuiElement {
continue;
}
- //String c2 = bold ? EnumChatFormatting.BOLD.toString() : "" + c;
-
int len = Minecraft.getMinecraft().fontRendererObj.getStringWidth(String.valueOf(c));
if (bold) len++;
if (i >= leftIndex && i < rightIndex) {
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 f85c165a..6a94c0b3 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
@@ -23,6 +23,7 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.dungeons.DungeonWin;
import io.github.moulberry.notenoughupdates.miscfeatures.CookieWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.CrystalMetalDetectorSolver;
+import io.github.moulberry.notenoughupdates.miscfeatures.EnderNodes;
import io.github.moulberry.notenoughupdates.miscfeatures.StreamerMode;
import io.github.moulberry.notenoughupdates.overlays.OverlayManager;
import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay;
@@ -201,11 +202,11 @@ public class ChatListener {
String unformatted = Utils.cleanColour(e.message.getUnformattedText());
Matcher matcher = SLAYER_XP.matcher(unformatted);
if (unformatted.startsWith("You are playing on profile: ")) {
- neu.manager.setCurrentProfile(unformatted
+ SBInfo.getInstance().setCurrentProfile(unformatted
.substring("You are playing on profile: ".length())
.split(" ")[0].trim());
} else if (unformatted.startsWith("Your profile was changed to: ")) {//Your profile was changed to:
- neu.manager.setCurrentProfile(unformatted
+ SBInfo.getInstance().setCurrentProfile(unformatted
.substring("Your profile was changed to: ".length())
.split(" ")[0].trim());
} else if (unformatted.startsWith("Your new API key is ")) {
@@ -214,8 +215,7 @@ public class ChatListener {
0,
36
);
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.YELLOW + "[NEU] API Key automatically configured"));
+ Utils.addChatMessage(EnumChatFormatting.YELLOW + "[NEU] API Key automatically configured");
NotEnoughUpdates.INSTANCE.saveConfig();
} else if (unformatted.startsWith("Player List Info is now disabled!")) {
SBInfo.getInstance().hasNewTab = false;
@@ -242,7 +242,6 @@ public class ChatListener {
} else if (unformatted.startsWith(" RNG Meter")) {
RNGMeter = unformatted.substring(" RNG Meter - ".length());
} else if (matcher.matches()) {
- //matcher.group(1);
SlayerOverlay.slayerLVL = matcher.group(2);
if (!SlayerOverlay.slayerLVL.equals("9")) {
SlayerOverlay.slayerXp = matcher.group(3);
@@ -308,5 +307,9 @@ public class ChatListener {
unformatted.equals("You have successfully picked the lock on this chest!")
|| (unformatted.startsWith("You received +") && unformatted.endsWith(" Powder")))
OverlayManager.powderGrindingOverlay.message(unformatted);
+
+ if (unformatted.equals("ENDER NODE! You found Endermite Nest!")) {
+ EnderNodes.dispalyEndermiteNotif();
+ }
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java
index d89e886f..27e7cfc6 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java
@@ -29,6 +29,7 @@ import io.github.moulberry.notenoughupdates.ItemPriceInformation;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.core.util.MiscUtils;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager;
import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay;
import io.github.moulberry.notenoughupdates.miscgui.GuiEnchantColour;
import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
@@ -60,6 +61,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
@@ -79,6 +81,80 @@ public class ItemTooltipListener {
private boolean pressedShiftLast = false;
private int sbaloaded = -1;
+ //region Enchant optimisation
+ private String lastItemUuid;
+
+ public static class EnchantString {
+ final String preEnchantText;
+ final String enchantName;
+
+ final String mod;
+ final String colourCode;
+ final boolean isChroma;
+
+ public EnchantString(String enchant, String preEnchantText, String modifier, String colourCode) {
+ this.preEnchantText = preEnchantText;
+ this.enchantName = enchant;
+ this.mod = modifier;
+ this.colourCode = colourCode;
+ this.isChroma = colourCode.equals("z");
+ }
+
+ private boolean matches(String line) {
+ return line.matches(".*" + preEnchantText + enchantName + ".*");
+ }
+
+ public String applyMods(String line, int lineIndex) {
+ if (!matches(line)) return null;
+
+ if (!isChroma) {
+ return line.replace(preEnchantText + enchantName,
+ "\u00A7" + colourCode + mod + enchantName
+ );
+ } else {
+ //if you couldn't tell, this is for chroma.
+ int newOffset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(preEnchantText + enchantName);
+ return line.replace(
+ preEnchantText + enchantName,
+ Utils.chromaString(enchantName, newOffset / 12f + lineIndex, preEnchantText.matches(".*\\u00A7d.*"))
+ );
+ }
+ }
+}
+
+public static class EnchantLine {
+ final String originalLine;
+ final ArrayList<EnchantString> enchants;
+
+ public EnchantLine(String line, ArrayList<EnchantString> enchants) {
+ this.enchants = enchants;
+ this.originalLine = line;
+ }
+
+ public boolean isSameAsBefore(String line) {
+ return line.equals(originalLine);
+ }
+
+ public String replaceLine(String line, int index) {
+ if (line.equals(originalLine)) {
+ for (EnchantString enchant: enchants) {
+ String modifiedLine = enchant.applyMods(line, index);
+ if (modifiedLine != null) {
+ line = modifiedLine;
+ }
+ }
+ }
+
+ return line;
+ }
+}
+
+ private final ArrayList<EnchantLine> enchantList = new ArrayList<>();
+ private int firstEnchantIndex = -1;
+ private int lastEnchantIndex = -1;
+
+ //endregion
+
public ItemTooltipListener(NotEnoughUpdates neu) {
this.neu = neu;
percentStats.add("bonus_attack_speed");
@@ -175,12 +251,26 @@ public class ItemTooltipListener {
boolean gotToEnchants = false;
boolean passedEnchants = false;
+ boolean foundEnchants = false;
boolean dungeonProfit = false;
- int index = 0;
List<String> newTooltip = new ArrayList<>();
- for (String line : event.toolTip) {
+ String currentUuid = ItemCustomizeManager.getUuidForItem(event.itemStack);
+
+ boolean resetEnchantCache = false;
+ //reset data if cache is off
+ if (!NotEnoughUpdates.INSTANCE.config.misc.cacheItemEnchant) {
+ lastItemUuid = null;
+ firstEnchantIndex = -1;
+ lastEnchantIndex = -1;
+ enchantList.clear();
+ }
+
+ for (int k = 0; k < event.toolTip.size(); k++) {
+ String line = event.toolTip.get(k);
+ boolean thisLineHasEnchants = false;
+
if (line.endsWith(EnumChatFormatting.DARK_GRAY + "Reforge Stone") &&
NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showReforgeStats) {
JsonObject reforgeStones = Constants.REFORGESTONES;
@@ -327,7 +417,7 @@ public class ItemTooltipListener {
} else if (line.contains("\u00A7cR\u00A76a\u00A7ei\u00A7an\u00A7bb\u00A79o\u00A7dw\u00A79 Rune")) {
line = line.replace(
"\u00A7cR\u00A76a\u00A7ei\u00A7an\u00A7bb\u00A79o\u00A7dw\u00A79 Rune",
- Utils.chromaString("Rainbow Rune", index, false) + EnumChatFormatting.BLUE
+ Utils.chromaString("Rainbow Rune", k, false) + EnumChatFormatting.BLUE
);
} else if (hasEnchantments) {
if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) &&
@@ -381,144 +471,182 @@ public class ItemTooltipListener {
}
}
if (hasEnchantments || hasAttributes) {
- ArrayList<String> addedEnchants = new ArrayList<>();
- for (String op : NotEnoughUpdates.INSTANCE.config.hidden.enchantColours) {
- List<String> colourOps = GuiEnchantColour.splitter.splitToList(op);
- String enchantName = GuiEnchantColour.getColourOpIndex(colourOps, 0);
- String comparator = GuiEnchantColour.getColourOpIndex(colourOps, 1);
- String comparison = GuiEnchantColour.getColourOpIndex(colourOps, 2);
- String colourCode = GuiEnchantColour.getColourOpIndex(colourOps, 3);
- String modifier = GuiEnchantColour.getColourOpIndex(colourOps, 4);
-
- int modifierI = GuiEnchantColour.getIntModifier(modifier);
-
- assert enchantName != null;
- if (enchantName.length() == 0) continue;
- assert comparator != null;
- if (comparator.length() == 0) continue;
- assert comparison != null;
- if (comparison.length() == 0) continue;
- assert colourCode != null;
- if (colourCode.length() == 0) continue;
-
- int comparatorI = ">=<".indexOf(comparator.charAt(0));
-
- int levelToFind;
- try {
- levelToFind = Integer.parseInt(comparison);
- } catch (Exception e) {
- continue;
- }
-
- if (comparatorI < 0) continue;
- String regexText = "0123456789abcdefz";
- if (isSkyblockAddonsLoaded()) {
- regexText = regexText + "Z";
+ Pattern findEnchantPattern = Pattern.compile(".*(?<enchant>[\\w ]+) (?<level>[0-9]+|[IVXLCDM]+)$");
+ Matcher findEnchantMatcher = findEnchantPattern.matcher(line);
+ if (findEnchantMatcher.matches()) {
+ if (NotEnoughUpdates.INSTANCE.config.misc.cacheItemEnchant && !foundEnchants) {
+ foundEnchants = true;
+ if ((
+ lastItemUuid == null || currentUuid == null ||
+ (currentUuid != null &&
+ !Objects.equals(lastItemUuid, currentUuid)))) {
+ firstEnchantIndex = k;//k being the line index
+ lastEnchantIndex = k;
+ enchantList.clear();
+ }
}
+ thisLineHasEnchants = true;
+ }
- if (regexText.indexOf(colourCode.charAt(0)) < 0) continue;
+ ArrayList<String> addedEnchants = new ArrayList<>();
+ //if cacheItemEnchant option is disabled it will always be length of 0
+ if (enchantList.size() == 0 || enchantList.size() <= k - firstEnchantIndex) {
+ ArrayList<EnchantString> enchants = new ArrayList<>();
+ final String oLine = line;
+
+ for (String op : NotEnoughUpdates.INSTANCE.config.hidden.enchantColours) {
+ List<String> colourOps = GuiEnchantColour.splitter.splitToList(op);
+ String enchantName = GuiEnchantColour.getColourOpIndex(colourOps, 0);
+ String comparator = GuiEnchantColour.getColourOpIndex(colourOps, 1);
+ String comparison = GuiEnchantColour.getColourOpIndex(colourOps, 2);
+ String colourCode = GuiEnchantColour.getColourOpIndex(colourOps, 3);
+ String modifier = GuiEnchantColour.getColourOpIndex(colourOps, 4);
+
+ int modifierI = GuiEnchantColour.getIntModifier(modifier);
+
+ assert enchantName != null;
+ if (enchantName.length() == 0) continue;
+ assert comparator != null;
+ if (comparator.length() == 0) continue;
+ assert comparison != null;
+ if (comparison.length() == 0) continue;
+ assert colourCode != null;
+ if (colourCode.length() == 0) continue;
+
+ int comparatorI = ">=<".indexOf(comparator.charAt(0));
+
+ int levelToFind;
+ try {
+ levelToFind = Integer.parseInt(comparison);
+ } catch (Exception e) {
+ continue;
+ }
- //item_lore = item_lore.replaceAll("\\u00A79("+lvl4Max+" IV)", EnumChatFormatting.DARK_PURPLE+"$1");
- //9([a-zA-Z ]+?) ([0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X))(,|$)
- Pattern pattern;
- try {
- pattern = Pattern.compile(
- "(\\u00A7b|\\u00A79|\\u00A7(b|9|l)\\u00A7d\\u00A7l)(?<enchantName>" + enchantName + ") " +
- "(?<level>[0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X|XI|XII|XIII|XIV|XV|XVI|XVII|XVIII|XIX|XX))((\\u00A79)?,|( \\u00A78(?:,?[0-9]+)*)?$)");
- } catch (Exception e) {
- continue;
- }
- Matcher matcher = pattern.matcher(line);
- int matchCount = 0;
- while (matcher.find() && matchCount < 5) {
- if (Utils.cleanColour(matcher.group("enchantName")).startsWith(" ")) continue;
-
- matchCount++;
- int level = -1;
- String levelStr = matcher.group("level");
- if (levelStr == null || levelStr.isEmpty()) continue;
- level = Utils.parseIntOrRomanNumeral(levelStr);
- boolean matches = false;
- if (level > 0) {
- switch (comparator) {
- case ">":
- matches = level > levelToFind;
- break;
- case "=":
- matches = level == levelToFind;
- break;
- case "<":
- matches = level < levelToFind;
- break;
- }
+ if (comparatorI < 0) continue;
+ String regexText = "0123456789abcdefz";
+ if (isSkyblockAddonsLoaded()) {
+ regexText = regexText + "Z";
}
- if (matches) {
- String enchantText = matcher.group("enchantName");
- StringBuilder extraModifiersBuilder = new StringBuilder();
- if ((modifierI & GuiEnchantColour.BOLD_MODIFIER) != 0) {
- extraModifiersBuilder.append(EnumChatFormatting.BOLD);
- }
- if ((modifierI & GuiEnchantColour.ITALIC_MODIFIER) != 0) {
- extraModifiersBuilder.append(EnumChatFormatting.ITALIC);
- }
- if ((modifierI & GuiEnchantColour.UNDERLINE_MODIFIER) != 0) {
- extraModifiersBuilder.append(EnumChatFormatting.UNDERLINE);
- }
- if ((modifierI & GuiEnchantColour.OBFUSCATED_MODIFIER) != 0) {
- extraModifiersBuilder.append(EnumChatFormatting.OBFUSCATED);
- }
- if ((modifierI & GuiEnchantColour.STRIKETHROUGH_MODIFIER) != 0) {
- extraModifiersBuilder.append(EnumChatFormatting.STRIKETHROUGH);
+ if (regexText.indexOf(colourCode.charAt(0)) < 0) continue;
+
+ //item_lore = item_lore.replaceAll("\\u00A79("+lvl4Max+" IV)", EnumChatFormatting.DARK_PURPLE+"$1");
+ //9([a-zA-Z ]+?) ([0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X))(,|$)
+ Pattern pattern;
+ try {
+ pattern = Pattern.compile(
+ "(\\u00A7b|\\u00A79|\\u00A7(b|9|l)\\u00A7d\\u00A7l)(?<enchantName>" + enchantName + ") " +
+ "(?<level>[0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X|XI|XII|XIII|XIV|XV|XVI|XVII|XVIII|XIX|XX))((\\u00A79)?,|( \\u00A78(?:,?[0-9]+)*)?$)");
+ } catch (Exception e) {
+ continue;
+ }
+ Matcher matcher = pattern.matcher(oLine);
+ int matchCount = 0;
+ while (matcher.find() && matchCount < 5) {
+ if (Utils.cleanColour(matcher.group("enchantName")).startsWith(" ")) continue;
+
+ matchCount++;
+ int level = -1;
+ String levelStr = matcher.group("level");
+ if (levelStr == null || levelStr.isEmpty()) continue;
+ level = Utils.parseIntOrRomanNumeral(levelStr);
+ boolean matches = false;
+ if (level > 0) {
+ switch (comparator) {
+ case ">":
+ matches = level > levelToFind;
+ break;
+ case "=":
+ matches = level == levelToFind;
+ break;
+ case "<":
+ matches = level < levelToFind;
+ break;
+ }
}
+ if (matches) {
+ String enchantText = matcher.group("enchantName");
+ StringBuilder extraModifiersBuilder = new StringBuilder();
- String extraMods = extraModifiersBuilder.toString();
+ if ((modifierI & GuiEnchantColour.BOLD_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.BOLD);
+ }
+ if ((modifierI & GuiEnchantColour.ITALIC_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.ITALIC);
+ }
+ if ((modifierI & GuiEnchantColour.UNDERLINE_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.UNDERLINE);
+ }
+ if ((modifierI & GuiEnchantColour.OBFUSCATED_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.OBFUSCATED);
+ }
+ if ((modifierI & GuiEnchantColour.STRIKETHROUGH_MODIFIER) != 0) {
+ extraModifiersBuilder.append(EnumChatFormatting.STRIKETHROUGH);
+ }
+
+ String extraMods = extraModifiersBuilder.toString();
+ if (!colourCode.equals("z")) {
+ if (!addedEnchants.contains(enchantText)) {
+ int startMatch = matcher.start();
+ int endMatch = matcher.end();
+ String subString = oLine.substring(startMatch, endMatch);
+ String preEnchantText = subString.split(String.valueOf(enchantText.charAt(0)))[0];
+
+ line = line.replace(preEnchantText + enchantText,
+ "\u00A7" + colourCode + extraMods + enchantText
+ );
+
+ enchants.add(new EnchantString(
+ enchantText,
+ preEnchantText,
+ extraMods,
+ colourCode
+ ));
+ }
+ } else {
+ //Chroma
+ int startMatch = matcher.start();
+ int endMatch = matcher.end();
+ String subString = line.substring(startMatch, endMatch);
+ int newOffset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(subString);
+
+ //split the substring with the first letter found in enchant text allowing to only get the color codes.
+ String preEnchantText = subString.split(String.valueOf(enchantText.charAt(0)))[0];
- if (!colourCode.equals("z")) {
- if (!addedEnchants.contains(enchantText)) {
- line = line.replace("\u00A79" + enchantText, "\u00A7" + colourCode + extraMods + enchantText);
- line = line.replace("\u00A7b" + enchantText, "\u00A7" + colourCode + extraMods + enchantText);
- line = line.replace(
- "\u00A79\u00A7d\u00A7l" + enchantText,
- "\u00A7" + colourCode + extraMods + enchantText
- );
- line = line.replace(
- "\u00A7b\u00A7d\u00A7l" + enchantText,
- "\u00A7" + colourCode + extraMods + enchantText
- );
line = line.replace(
- "\u00A7l\u00A7d\u00A7l" + enchantText,
- "\u00A7" + colourCode + extraMods + enchantText
+ preEnchantText + enchantText,
+ Utils.chromaString(enchantText, newOffset / 12f + k, preEnchantText.matches(".*\\u00A7d.*"))
);
+ enchants.add(new EnchantString(
+ enchantText,
+ preEnchantText,
+ extraMods,
+ colourCode
+ ));
}
- } else {
- int offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll(
- "\\u00A79" + enchantText + ".*",
- ""
- ));
- line = line.replace(
- "\u00A79" + enchantText,
- Utils.chromaString(enchantText, offset / 12f + index, false)
- );
-
- offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll(
- "\\u00A79\\u00A7d\\u00A7l" + enchantText + ".*",
- ""
- ));
- line = line.replace(
- "\u00A79\u00A7d\u00A7l" + enchantText,
- Utils.chromaString(enchantText, offset / 12f + index, true)
- );
- offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll(
- "\\u00A7l\\u00A7d\\u00A7l" + enchantText + ".*",
- ""
- ));
- line = line.replace(
- "\u00A7l\u00A7d\u00A7l" + enchantText,
- Utils.chromaString(enchantText, offset / 12f + index, true)
- );
+ addedEnchants.add(enchantText);
+ }
+ }
+ }
+ if (NotEnoughUpdates.INSTANCE.config.misc.cacheItemEnchant) {
+ if (lastItemUuid == null || !Objects.equals(lastItemUuid, currentUuid)) {
+ EnchantLine enchantLine = new EnchantLine(oLine, enchants);
+ enchantList.add(enchantLine);
+ }
+ }
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.misc.cacheItemEnchant && foundEnchants) {
+ //found enchants in the past
+ if (k <= lastEnchantIndex) {
+ if (Objects.equals(lastItemUuid, currentUuid) && (firstEnchantIndex != -1 && enchantList.size() > k - firstEnchantIndex) && (k - firstEnchantIndex) > 0) {
+ //if it has the line, replaces it with the cached line
+ EnchantLine enchantLine = enchantList.get(k - firstEnchantIndex);
+ if (!enchantLine.isSameAsBefore(line)) {
+ resetEnchantCache = true;
}
- addedEnchants.add(enchantText);
+
+ line = enchantLine.replaceLine(line, k);
}
}
}
@@ -543,7 +671,7 @@ public class ItemTooltipListener {
Minecraft.getMinecraft().currentScreen instanceof GuiChest) {
if (line.contains(EnumChatFormatting.GREEN + "Open Reward Chest")) {
dungeonProfit = true;
- } else if (index == 7 && dungeonProfit) {
+ } else if (k == 7 && dungeonProfit) {
GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen;
ContainerChest cc = (ContainerChest) eventGui.inventorySlots;
IInventory lower = cc.getLowerChestInventory();
@@ -688,11 +816,9 @@ public class ItemTooltipListener {
}
}
}
-
- index++;
+ if (thisLineHasEnchants) lastEnchantIndex+=1;
}
-
pressedShiftLast = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
pressedArrowLast = Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_RIGHT);
@@ -707,6 +833,18 @@ public class ItemTooltipListener {
NotEnoughUpdates.INSTANCE.config.petOverlay.hidePetTooltip) {
event.toolTip.clear();
}
+
+
+ if (foundEnchants && currentUuid != null && lastItemUuid != currentUuid) {
+ lastItemUuid = currentUuid;//cache is set;
+ }
+
+ if (resetEnchantCache) {
+ lastItemUuid = null;
+ enchantList.clear();
+ firstEnchantIndex = -1;
+ lastEnchantIndex = -1;
+ }
}
private void petToolTipXPExtendPetMenu(ItemTooltipEvent event) {
@@ -843,7 +981,6 @@ public class ItemTooltipListener {
MiscUtils.copyToClipboard(NotEnoughUpdates.INSTANCE.manager.getSkullValueForItem(event.itemStack));
}
-
event.toolTip.add(
EnumChatFormatting.AQUA + "Internal Name: " + EnumChatFormatting.GRAY + internal + EnumChatFormatting.GOLD +
" [K]");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java
index fdae53ea..2b7a9bef 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java
@@ -139,7 +139,7 @@ public class ItemTooltipRngListener {
private String getFormatCoinsPer(ItemStack stack, int needed, int multiplier, String label) {
String internalName = neu.manager.createItemResolutionQuery().withItemStack(stack).resolveInternalName();
- double profit = neu.manager.auctionManager.getBazaarOrBin(internalName);
+ double profit = neu.manager.auctionManager.getBazaarOrBin(internalName, false);
if (profit <= 0) return null;
//ask hypixel nicely to release a 'chest price api' with 4 dimensions for us. the 4 dimensions needed are: item name, floor, normal/mm, s/s+
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
index e202b828..5b388dea 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/NEUEventListener.java
@@ -34,11 +34,13 @@ import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager;
import io.github.moulberry.notenoughupdates.miscfeatures.NPCRetexturing;
import io.github.moulberry.notenoughupdates.miscgui.AccessoryBagOverlay;
import io.github.moulberry.notenoughupdates.miscgui.GuiCustomEnchant;
+import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe;
import io.github.moulberry.notenoughupdates.miscgui.hex.GuiCustomHex;
import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay;
import io.github.moulberry.notenoughupdates.overlays.OverlayManager;
import io.github.moulberry.notenoughupdates.overlays.TextOverlay;
import io.github.moulberry.notenoughupdates.overlays.TextTabOverlay;
+import io.github.moulberry.notenoughupdates.recipes.RecipeHistory;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.NotificationHandler;
import io.github.moulberry.notenoughupdates.util.ProfileApiSyncer;
@@ -162,6 +164,11 @@ public class NEUEventListener {
if (longUpdate) {
+
+ if (!(Minecraft.getMinecraft().currentScreen instanceof GuiItemRecipe)) {
+ RecipeHistory.clear();
+ }
+
CrystalOverlay.tick();
FairySouls.getInstance().tick();
XPInformation.getInstance().tick();
@@ -235,35 +242,24 @@ public class NEUEventListener {
if (!NotEnoughUpdates.INSTANCE.config.hidden.loadedModBefore) {
NotEnoughUpdates.INSTANCE.config.hidden.loadedModBefore = true;
if (Constants.MISC == null || !Constants.MISC.has("featureslist")) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "WARNING: " + EnumChatFormatting.RESET +
- EnumChatFormatting.RED + "Could not load Feature List URL from repo."));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "" + EnumChatFormatting.RED + "Please run " + EnumChatFormatting.BOLD + "/neuresetrepo" +
- EnumChatFormatting.RESET + EnumChatFormatting.RED + " and " + EnumChatFormatting.BOLD +
- "restart your game" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " in order to fix. " +
- EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "If that doesn't fix it" +
- EnumChatFormatting.RESET + EnumChatFormatting.RED +
- ", please join discord.gg/moulberry and post in #neu-support"));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "" + EnumChatFormatting.GOLD + "To view the feature list after restarting type /neufeatures"));
+ Utils.showOutdatedRepoNotification();
+ Utils.addChatMessage(
+ "" + EnumChatFormatting.GOLD + "To view the feature list after restarting type /neufeatures");
} else {
String url = Constants.MISC.get("featureslist").getAsString();
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.BLUE + "It seems this is your first time using NotEnoughUpdates."));
+ Utils.addChatMessage("");
+ Utils.addChatMessage(EnumChatFormatting.BLUE + "It seems this is your first time using NotEnoughUpdates.");
ChatComponentText clickTextFeatures = new ChatComponentText(EnumChatFormatting.YELLOW +
"Click this message if you would like to view a list of NotEnoughUpdate's Features.");
clickTextFeatures.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, url));
Minecraft.getMinecraft().thePlayer.addChatMessage(clickTextFeatures);
}
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
+ Utils.addChatMessage("");
ChatComponentText clickTextHelp = new ChatComponentText(EnumChatFormatting.YELLOW +
"Click this message if you would like to view a list of NotEnoughUpdate's commands.");
clickTextHelp.setChatStyle(Utils.createClickStyle(ClickEvent.Action.RUN_COMMAND, "/neuhelp"));
Minecraft.getMinecraft().thePlayer.addChatMessage(clickTextHelp);
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(""));
+ Utils.addChatMessage("");
}
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
index 2abb2ee8..949358ad 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
@@ -40,6 +40,7 @@ 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.CrystalMetalDetectorSolver;
+import io.github.moulberry.notenoughupdates.miscfeatures.DungeonNpcProfitOverlay;
import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers;
import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager;
import io.github.moulberry.notenoughupdates.miscgui.AccessoryBagOverlay;
@@ -50,6 +51,7 @@ import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe;
import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay;
import io.github.moulberry.notenoughupdates.miscgui.TradeWindow;
import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
import io.github.moulberry.notenoughupdates.miscgui.hex.GuiCustomHex;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
import io.github.moulberry.notenoughupdates.options.NEUConfig;
@@ -83,7 +85,6 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StringUtils;
@@ -136,6 +137,8 @@ public class RenderListener {
public static long lastGuiClosed = 0;
public static boolean inventoryLoaded = false;
private final NotEnoughUpdates neu;
+ private final NumberFormat format = new DecimalFormat("#,##0.#", new DecimalFormatSymbols(Locale.US));
+ private final Pattern ESSENCE_PATTERN = Pattern.compile("§d(.+) Essence §8x([\\d,]+)");
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
JsonObject essenceJson = new JsonObject();
private boolean hoverInv = false;
@@ -150,9 +153,6 @@ public class RenderListener {
private boolean typing;
private HashMap<String, String> cachedDefinitions;
private boolean inDungeonPage = false;
- private final NumberFormat format = new DecimalFormat("#,##0.#", new DecimalFormatSymbols(Locale.US));
-
- private final Pattern ESSENCE_PATTERN = Pattern.compile("§d(.+) Essence §8x([\\d,]+)");
public RenderListener(NotEnoughUpdates neu) {
this.neu = neu;
@@ -327,8 +327,7 @@ public class RenderListener {
JsonObject json = neu.manager.getItemInformation().get(resInternalname);
json.addProperty("crafttext", "Requires: " + col);
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "Added: " + resInternalname));
+ Utils.addChatMessage("Added: " + resInternalname);
neu.manager.writeJsonDefaultDir(json, resInternalname + ".json");
neu.manager.loadItem(resInternalname);
}
@@ -459,7 +458,6 @@ public class RenderListener {
return;
}
-
boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
boolean customAhActive =
@@ -538,6 +536,12 @@ public class RenderListener {
x += diffX;
}
}
+ if (MinionHelperManager.getInstance().inCraftedMinionsInventory()) {
+ int diffX = 172;
+ if (x > guiLeft + xSize && x < guiLeft + xSize + diffX + 5 && y > guiTop - 18 && y < guiTop + 128) {
+ x += diffX;
+ }
+ }
if (AuctionProfit.inAuctionPage()) {
if (x + 18 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 &&
y < guiTop + 56) {
@@ -554,7 +558,7 @@ public class RenderListener {
x -= 25;
}
}
- if (inDungeonPage) {
+ if (inDungeonPage || DungeonNpcProfitOverlay.isRendering()) {
if (x + 10 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 &&
y < guiTop + 100) {
x += 185;
@@ -666,6 +670,12 @@ public class RenderListener {
x += diffX;
}
}
+ if (MinionHelperManager.getInstance().inCraftedMinionsInventory()) {
+ int diffX = 172;
+ if (x > guiLeft + xSize && x < guiLeft + xSize + diffX + 5 && y > guiTop - 18 && y < guiTop + 128) {
+ x += diffX;
+ }
+ }
if (AuctionProfit.inAuctionPage()) {
if (x + 18 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 &&
y < guiTop + 56) {
@@ -683,7 +693,7 @@ public class RenderListener {
}
}
- if (inDungeonPage) {
+ if (inDungeonPage || DungeonNpcProfitOverlay.isRendering()) {
if (x + 10 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 &&
y < guiTop + 100) {
x += 185;
@@ -801,7 +811,7 @@ public class RenderListener {
if (bazaarPrice < 5000000 && internal.equals("RECOMBOBULATOR_3000")) bazaarPrice = 5000000;
double worth = -1;
- boolean isOnBz = false;
+ boolean isOnBz = false;
if (bazaarPrice >= 0) {
worth = bazaarPrice;
isOnBz = true;
@@ -1075,7 +1085,6 @@ public class RenderListener {
return;
}
-
boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
boolean customAhActive =
@@ -1143,6 +1152,12 @@ public class RenderListener {
x += diffX;
}
}
+ if (MinionHelperManager.getInstance().inCraftedMinionsInventory()) {
+ int diffX = 172;
+ if (x > guiLeft + xSize && x < guiLeft + xSize + diffX + 5 && y > guiTop - 18 && y < guiTop + 128) {
+ x += diffX;
+ }
+ }
if (AuctionProfit.inAuctionPage()) {
if (x + 18 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 &&
y < guiTop + 56) {
@@ -1159,7 +1174,7 @@ public class RenderListener {
x -= 25;
}
}
- if (inDungeonPage) {
+ if (inDungeonPage || DungeonNpcProfitOverlay.isRendering()) {
if (x + 10 > guiLeft + xSize && x + 18 < guiLeft + xSize + 4 + 28 + 20 && y > guiTop - 180 &&
y < guiTop + 100) {
x += 185;
@@ -1306,17 +1321,15 @@ public class RenderListener {
))
) {
writer.write(gson.toJson(jsonObject));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.AQUA + "Parsed and saved: " + EnumChatFormatting.WHITE + id));
+ Utils.addChatMessage(EnumChatFormatting.AQUA + "Parsed and saved: " + EnumChatFormatting.WHITE + id);
}
} catch (IOException ignored) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "Error while writing file."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "Error while writing file.");
}
} catch (Exception e) {
e.printStackTrace();
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "Error while parsing inventory. Try again or check logs for details."));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "Error while parsing inventory. Try again or check logs for details.");
}
}
} else if (Keyboard.isKeyDown(Keyboard.KEY_RETURN) && NotEnoughUpdates.INSTANCE.config.hidden.dev) {
@@ -1411,8 +1424,7 @@ public class RenderListener {
} else if (cachedDefinitions.containsKey(item)) {
costArray.add(new JsonPrimitive(cachedDefinitions.get(item) + ":" + amountString));
} else {
- mc.thePlayer.addChatMessage(new ChatComponentText(
- "Change the item ID of " + item + " to the correct one and press Enter."));
+ Utils.addChatMessage("Change the item ID of " + item + " to the correct one and press Enter.");
NEUOverlay.getTextField().setText(item);
event.setCanceled(true);
typing = true;
@@ -1441,17 +1453,16 @@ public class RenderListener {
))
) {
writer.write(gson.toJson(newNPC));
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.AQUA + "Parsed and saved: " + EnumChatFormatting.WHITE + displayName));
+ Utils.addChatMessage(
+ EnumChatFormatting.AQUA + "Parsed and saved: " + EnumChatFormatting.WHITE + displayName);
}
} catch (IOException ignored) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "Error while writing file."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "Error while writing file.");
}
} catch (Exception e) {
e.printStackTrace();
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "Error while parsing inventory. Try again or check logs for details"));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "Error while parsing inventory. Try again or check logs for details");
}
}
} else if (NotEnoughUpdates.INSTANCE.config.hidden.dev && Keyboard.isKeyDown(Keyboard.KEY_B) &&
@@ -1471,9 +1482,9 @@ public class RenderListener {
if (stack.getDisplayName().isEmpty() || stack.getDisplayName().equals(" ")) continue;
String internalName = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack);
if (internalName == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
+ Utils.addChatMessage(
EnumChatFormatting.RED + "ERROR: Could not get internal name for: " + EnumChatFormatting.AQUA +
- stack.getDisplayName()));
+ stack.getDisplayName());
continue;
}
JsonObject itemObject = NotEnoughUpdates.INSTANCE.manager.getJsonForItem(stack);
@@ -1493,13 +1504,11 @@ public class RenderListener {
itemObject.add("lore", newLore);
if (!NEUItemEditor.saveOnly(internalName, itemObject)) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "ERROR: Failed to save item: " + EnumChatFormatting.AQUA +
- stack.getDisplayName()));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "ERROR: Failed to save item: " + EnumChatFormatting.AQUA + stack.getDisplayName());
}
}
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.AQUA + "Parsed page: " + lower.getDisplayName().getUnformattedText()));
+ Utils.addChatMessage(EnumChatFormatting.AQUA + "Parsed page: " + lower.getDisplayName().getUnformattedText());
event.setCanceled(true);
return;
}
@@ -1553,7 +1562,6 @@ public class RenderListener {
return;
}
-
boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName);
boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName);
boolean customAhActive =
@@ -1703,7 +1711,7 @@ public class RenderListener {
json.addProperty("clickcommand", "viewrecipe");
json.addProperty("modver", NotEnoughUpdates.VERSION);
try {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + resInternalname));
+ Utils.addChatMessage("Added: " + resInternalname);
neu.manager.writeJsonDefaultDir(json, resInternalname + ".json");
neu.manager.loadItem(resInternalname);
} catch (IOException ignored) {
@@ -1717,4 +1725,24 @@ public class RenderListener {
public void onRenderLast(RenderWorldLastEvent event) {
CrystalMetalDetectorSolver.render(event.partialTicks);
}
+
+ /**
+ * Support for switching between different pages in the RecipeView gui via right and left arrow key
+ * @param event
+ */
+ //Because GuiScreen.keyTyped does not fire the KEY_LEFT and KEY_RIGHT keys. Maybe some event cancelled it?
+ @SubscribeEvent
+ public void onMouseClick(GuiScreenEvent.KeyboardInputEvent.Post event) {
+
+ if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return;
+
+ Minecraft minecraft = Minecraft.getMinecraft();
+ if (minecraft == null || minecraft.thePlayer == null) return;
+
+ GuiScreen screen = minecraft.currentScreen;
+ if (screen instanceof GuiItemRecipe) {
+ GuiItemRecipe itemRecipe = (GuiItemRecipe) screen;
+ itemRecipe.arrowKeyboardInput();
+ }
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java
index 622b2088..3727a441 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ScoreboardLocationChangeListener.java
@@ -31,10 +31,10 @@ public class ScoreboardLocationChangeListener {
try {
Thread.sleep(3000);
TimersOverlay.afterPearls = TimersOverlay.heavyPearlCount();
- //Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW+"You exited the beast with ["+EnumChatFormatting.AQUA+(TimersOverlay.afterPearls-TimersOverlay.beforePearls)+EnumChatFormatting.YELLOW+"/"+EnumChatFormatting.AQUA+TimersOverlay.availablePearls+EnumChatFormatting.YELLOW+"] Heavy Pearls!"));
+ //Utils.sendMessageToPlayer(EnumChatFormatting.YELLOW+"You exited the beast with ["+EnumChatFormatting.AQUA+(TimersOverlay.afterPearls-TimersOverlay.beforePearls)+EnumChatFormatting.YELLOW+"/"+EnumChatFormatting.AQUA+TimersOverlay.availablePearls+EnumChatFormatting.YELLOW+"] Heavy Pearls!");
if (TimersOverlay.afterPearls - TimersOverlay.beforePearls == TimersOverlay.availablePearls) {
NotEnoughUpdates.INSTANCE.config.getProfileSpecific().dailyHeavyPearlCompleted = System.currentTimeMillis();
- //Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN+"Daily "+EnumChatFormatting.DARK_AQUA+"Heavy Pearls"+EnumChatFormatting.GREEN+" Complete!"));
+ //Utils.sendMessageToPlayer(EnumChatFormatting.GREEN+"Daily "+EnumChatFormatting.DARK_AQUA+"Heavy Pearls"+EnumChatFormatting.GREEN+" Complete!");
}
} catch (InterruptedException e) {
e.printStackTrace();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java
index f21d0c50..fede9bdf 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java
@@ -23,8 +23,8 @@ import com.google.common.collect.Lists;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiPlayerTabOverlay;
import io.github.moulberry.notenoughupdates.util.NotificationHandler;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
public class CookieWarning {
@@ -94,9 +94,8 @@ public class CookieWarning {
}
} catch (NumberFormatException e) {
e.printStackTrace();
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED +
- "NEU ran into an issue when retrieving the Booster Cookie Timer. Check the logs for details."));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "NEU ran into an issue when retrieving the Booster Cookie Timer. Check the logs for details.");
hasNotified = true;
}
if (minutes < NotEnoughUpdates.INSTANCE.config.notifications.boosterCookieWarningMins && !hasNotified) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java
index ab9345cb..23115c36 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalMetalDetectorSolver.java
@@ -25,10 +25,10 @@ import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag;
import io.github.moulberry.notenoughupdates.util.NEUDebugLogger;
import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.util.BlockPos;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.Vec3i;
@@ -169,7 +169,7 @@ public class CrystalMetalDetectorSolver {
NEUDebugLogger.log(NEUDebugFlag.METAL, "Known location identified.");
// falls through
case FOUND:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] Found solution."));
+ Utils.addChatMessage(EnumChatFormatting.YELLOW + "[NEU] Found solution.");
if (NEUDebugFlag.METAL.isSet() &&
(previousState == SolutionState.INVALID || previousState == SolutionState.FAILED)) {
NEUDebugLogger.log(
@@ -180,14 +180,12 @@ public class CrystalMetalDetectorSolver {
}
break;
case INVALID:
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "[NEU] Previous solution is invalid."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Previous solution is invalid.");
logDiagnosticData(false);
resetSolution(false);
break;
case FAILED:
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "[NEU] Failed to find a solution."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Failed to find a solution.");
logDiagnosticData(false);
resetSolution(false);
break;
@@ -195,8 +193,9 @@ public class CrystalMetalDetectorSolver {
NEUDebugLogger.log(NEUDebugFlag.METAL, "Multiple known locations identified:");
// falls through
case MULTIPLE:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Need another position to find solution. Possible blocks: " + possibleBlocks.size()));
+ Utils.addChatMessage(
+ EnumChatFormatting.YELLOW + "[NEU] Need another position to find solution. Possible blocks: " +
+ possibleBlocks.size());
break;
default:
throw new IllegalStateException("Metal detector is in invalid state");
@@ -372,8 +371,8 @@ public class CrystalMetalDetectorSolver {
if (keeperEntities.size() == 0) {
if (!visitKeeperMessagePrinted) {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Approach a Keeper while holding the metal detector to enable faster treasure hunting."));
+ Utils.addChatMessage(EnumChatFormatting.YELLOW +
+ "[NEU] Approach a Keeper while holding the metal detector to enable faster treasure hunting.");
visitKeeperMessagePrinted = true;
}
return false;
@@ -387,8 +386,8 @@ public class CrystalMetalDetectorSolver {
minesCenter = keeperEntity.getPosition().add(keeperOffsets.get(keeperType.toLowerCase()));
NEUDebugLogger.log(NEUDebugFlag.METAL, "Mines center: " +
EnumChatFormatting.WHITE + minesCenter.toString());
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.YELLOW + "[NEU] Faster treasure hunting is now enabled based on Keeper location."));
+ Utils.addChatMessage(
+ EnumChatFormatting.YELLOW + "[NEU] Faster treasure hunting is now enabled based on Keeper location.");
return true;
}
@@ -560,8 +559,7 @@ public class CrystalMetalDetectorSolver {
}
if (!NotEnoughUpdates.INSTANCE.config.mining.metalDetectorEnabled) {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Metal Detector Solver is not enabled."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Metal Detector Solver is not enabled.");
return;
}
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 21d1d4a3..50975af9 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CrystalWishingCompassSolver.java
@@ -234,35 +234,35 @@ public class CrystalWishingCompassSolver {
case SUCCESS:
return;
case STILL_PROCESSING_PRIOR_USE:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Wait a little longer before using the wishing compass again."));
+ Utils.addChatMessage(
+ EnumChatFormatting.YELLOW + "[NEU] Wait a little longer before using the wishing compass again.");
event.setCanceled(true);
break;
case LOCATION_TOO_CLOSE:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Move a little further before using the wishing compass again."));
+ Utils.addChatMessage(
+ EnumChatFormatting.YELLOW + "[NEU] Move a little further before using the wishing compass again.");
event.setCanceled(true);
break;
case POSSIBLE_TARGETS_CHANGED:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Possible wishing compass targets have changed. Solver has been reset."));
+ Utils.addChatMessage(
+ EnumChatFormatting.YELLOW + "[NEU] Possible wishing compass targets have changed. Solver has been reset.");
event.setCanceled(true);
break;
case NO_PARTICLES_FOR_PREVIOUS_COMPASS:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] No particles detected for prior compass use. Need another position to solve."));
+ Utils.addChatMessage(EnumChatFormatting.YELLOW +
+ "[NEU] No particles detected for prior compass use. Need another position to solve.");
break;
case PLAYER_IN_NUCLEUS:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Wishing compass must be used outside the nucleus for accurate results."));
+ Utils.addChatMessage(
+ EnumChatFormatting.YELLOW + "[NEU] Wishing compass must be used outside the nucleus for accurate results.");
event.setCanceled(true);
break;
default:
throw new IllegalStateException("Unexpected wishing compass solver state: \n" + getDiagnosticMessage());
}
} catch (Exception e) {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Error processing wishing compass action - see log for details"));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "[NEU] Error processing wishing compass action - see log for details");
e.printStackTrace();
event.setCanceled(true);
solverState = SolverState.FAILED_EXCEPTION;
@@ -375,39 +375,36 @@ public class CrystalWishingCompassSolver {
showSolution();
break;
case FAILED_EXCEPTION:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Unable to determine wishing compass target."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Unable to determine wishing compass target.");
logDiagnosticData(false);
break;
case FAILED_TIMEOUT_NO_REPEATING:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Timed out waiting for repeat set of compass particles."));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "[NEU] Timed out waiting for repeat set of compass particles.");
logDiagnosticData(false);
break;
case FAILED_TIMEOUT_NO_PARTICLES:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Timed out waiting for compass particles."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Timed out waiting for compass particles.");
logDiagnosticData(false);
break;
case FAILED_INTERSECTION_CALCULATION:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Unable to determine intersection of wishing compasses."));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "[NEU] Unable to determine intersection of wishing compasses.");
logDiagnosticData(false);
break;
case FAILED_INVALID_SOLUTION:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Failed to find solution."));
+ Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] Failed to find solution.");
logDiagnosticData(false);
break;
case NEED_SECOND_COMPASS:
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
- "[NEU] Need another position to determine wishing compass target."));
+ Utils.addChatMessage(
+ EnumChatFormatting.YELLOW + "[NEU] Need another position to determine wishing compass target.");
break;
}
}
} catch (Exception e) {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Exception while calculating wishing compass solution - see log for details"));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "[NEU] Exception while calculating wishing compass solution - see log for details");
e.printStackTrace();
}
}
@@ -781,15 +778,14 @@ public class CrystalWishingCompassSolver {
if (solution == null) return;
if (NUCLEUS_BB.isVecInside(solution)) {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU] " +
- EnumChatFormatting.AQUA + "Wishing compass target is the Crystal Nucleus"));
+ Utils.addChatMessage(EnumChatFormatting.YELLOW + "[NEU] " + EnumChatFormatting.AQUA + "Wishing compass target is the Crystal Nucleus");
return;
}
String destinationMessage = getWishingCompassDestinationsMessage();
if (!isSkytilsPresent) {
- mc.thePlayer.addChatMessage(new ChatComponentText(destinationMessage));
+ Utils.addChatMessage(destinationMessage);
return;
}
@@ -799,13 +795,13 @@ public class CrystalWishingCompassSolver {
String skytilsCommand = String.format("/sthw add %s %s", getSolutionCoordsText(), targetNameForSkytils);
if (NotEnoughUpdates.INSTANCE.config.mining.wishingCompassAutocreateKnownWaypoints &&
solutionPossibleTargets.size() == 1) {
- mc.thePlayer.addChatMessage(new ChatComponentText(destinationMessage));
+ Utils.addChatMessage(destinationMessage);
int commandResult = ClientCommandHandler.instance.executeCommand(mc.thePlayer, skytilsCommand);
if (commandResult == 1) {
return;
}
- mc.thePlayer.addChatMessage(new ChatComponentText(
- EnumChatFormatting.RED + "[NEU] Failed to automatically run /sthw"));
+ Utils.addChatMessage(
+ EnumChatFormatting.RED + "[NEU] Failed to automatically run /sthw");
}
destinationMessage += EnumChatFormatting.YELLOW + " [Add Skytils Waypoint]";
@@ -920,8 +916,8 @@ public class CrystalWishingCompassSolver {
}
if (!NotEnoughUpdates.INSTANCE.config.mining.wishingCompassSolver) {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] Wishing Compass Solver is not enabled."));
+ Utils.addChatMessage(EnumChatFormatting.RED +
+ "[NEU] Wishing Compass Solver is not enabled.");
return;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java
new file mode 100644
index 00000000..7caa4d6b
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/DungeonNpcProfitOverlay.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscfeatures;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
+import io.github.moulberry.notenoughupdates.util.ItemUtils;
+import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.init.Items;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.jetbrains.annotations.Nullable;
+import org.lwjgl.opengl.GL11;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DungeonNpcProfitOverlay {
+
+ private static final ResourceLocation dungeonProfitResource =
+ new ResourceLocation("notenoughupdates:dungeon_chest_worth.png");
+
+ private static final Pattern chestNamePattern = Pattern.compile(".+ Catacombs - Floor .+");
+ private static final Pattern essencePattern = Pattern.compile(
+ "^§.(?<essenceType>\\w+) Essence §.x(?<essenceAmount>\\d+)$");
+ private static final Pattern enchantedBookPattern = Pattern.compile("^§.Enchanted Book \\((?<enchantName>.*)\\)");
+ private static List<DungeonChest> chestProfits;
+ private static List<Slot> previousSlots;
+
+ /**
+ * Check the current status for the overlay
+ *
+ * @return if the overlay is rendering right now
+ */
+ public static boolean isRendering() {
+ return NotEnoughUpdates.INSTANCE.config.dungeons.croesusProfitOverlay && chestProfits != null;
+ }
+
+ /**
+ * Highlight the slot that is being drawn if applicable. Called by MixinGuiContainer
+ *
+ * @param slot the slot to be checked
+ * @see io.github.moulberry.notenoughupdates.mixins.MixinGuiContainer#drawSlotRet(Slot, CallbackInfo)
+ */
+ public static void onDrawSlot(Slot slot) {
+ if (isRendering() && NotEnoughUpdates.INSTANCE.config.dungeons.croesusHighlightHighestProfit) {
+ for (DungeonChest chestProfit : chestProfits) {
+ if (chestProfit.shouldHighlight) {
+ if (slot.slotNumber == chestProfit.slot) {
+ Gui.drawRect(
+ slot.xDisplayPosition,
+ slot.yDisplayPosition,
+ slot.xDisplayPosition + 16,
+ slot.yDisplayPosition + 16,
+ Color.GREEN.getRGB()
+ );
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onDrawBackground(GuiScreenEvent.BackgroundDrawnEvent event) {
+ if (!NotEnoughUpdates.INSTANCE.config.dungeons.croesusProfitOverlay || !(event.gui instanceof GuiChest)) {
+ chestProfits = null;
+ previousSlots = null;
+ return;
+ }
+
+ String lastOpenChestName = SBInfo.getInstance().lastOpenChestName;
+ Matcher matcher = chestNamePattern.matcher(lastOpenChestName);
+ if (!matcher.matches()) {
+ chestProfits = null;
+ previousSlots = null;
+ return;
+ }
+ GuiChest guiChest = (GuiChest) event.gui;
+ List<Slot> slots = guiChest.inventorySlots.inventorySlots;
+
+ if (chestProfits == null || chestProfits.isEmpty() || !slots.equals(previousSlots)) {
+ updateDungeonChests(slots);
+ }
+ previousSlots = guiChest.inventorySlots.inventorySlots;
+
+ render(guiChest);
+ }
+
+ /**
+ * Update the profit applicable for the chests currently visible
+ *
+ * @param inventorySlots list of Slots from the GUI containing the dungeon chest previews
+ */
+ private void updateDungeonChests(List<Slot> inventorySlots) {
+ chestProfits = new ArrayList<>();
+ //loop through the upper chest
+ for (int i = 0; i < 27; i++) {
+ Slot inventorySlot = inventorySlots.get(i);
+ if (inventorySlot == null) {
+ continue;
+ }
+
+ ItemStack stack = inventorySlot.getStack();
+ if (stack != null && stack.getItem() != null && stack.getItem() == Items.skull) {
+ //each item is a DungeonChest
+ DungeonChest dungeonChest = new DungeonChest();
+ dungeonChest.slot = i;
+
+ List<String> lore = ItemUtils.getLore(stack);
+ if ("§7Contents".equals(lore.get(0))) {
+ dungeonChest.name = stack.getDisplayName();
+ List<SkyblockItem> items = new ArrayList<>();
+ for (String s : lore) {
+ //check if this line is showing the cost of opening the Chest
+ if (s.endsWith(" Coins")) {
+ String coinString = StringUtils.cleanColour(s);
+ int whitespace = coinString.indexOf(' ');
+ if (whitespace != -1) {
+ String amountString = coinString.substring(0, whitespace).replace(",", "");
+ dungeonChest.costToOpen = Integer.parseInt(amountString);
+ continue;
+ }
+ } else if (s.equals("§aFREE")) {
+ dungeonChest.costToOpen = 0;
+ }
+
+ //check if the line can be converted to a SkyblockItem
+ SkyblockItem skyblockItem = SkyblockItem.createFromLoreEntry(s);
+ if (skyblockItem != null) {
+ items.add(skyblockItem);
+ }
+ }
+ dungeonChest.items = items;
+ if (dungeonChest.costToOpen != -1) {
+ dungeonChest.calculateProfitAndBuildLore();
+ chestProfits.add(dungeonChest);
+ }
+ }
+ }
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.dungeons.croesusSortByProfit) {
+ chestProfits.sort(Comparator.comparing(DungeonChest::getProfit).reversed());
+ }
+
+ if (NotEnoughUpdates.INSTANCE.config.dungeons.croesusHighlightHighestProfit && chestProfits.size() >= 1) {
+ List<DungeonChest> copiedList = new ArrayList<>(chestProfits);
+ copiedList.sort(Comparator.comparing(DungeonChest::getProfit).reversed());
+
+ copiedList.get(0).shouldHighlight = true;
+ }
+ }
+
+ public void render(GuiChest guiChest) {
+ int xSize = ((AccessorGuiContainer) guiChest).getXSize();
+ int guiLeft = ((AccessorGuiContainer) guiChest).getGuiLeft();
+ int guiTop = ((AccessorGuiContainer) guiChest).getGuiTop();
+ Minecraft.getMinecraft().getTextureManager().bindTexture(dungeonProfitResource);
+ GL11.glColor4f(1, 1, 1, 1);
+ GlStateManager.disableLighting();
+ Utils.drawTexturedRect(guiLeft + xSize + 4, guiTop, 180, 101, 0, 180 / 256f, 0, 101 / 256f, GL11.GL_NEAREST);
+
+ for (int i = 0; i < chestProfits.size(); i++) {
+ DungeonChest chestProfit = chestProfits.get(i);
+ int x = guiLeft + xSize + 14;
+ int y = guiTop + 6 + (i * 10);
+ Utils.renderAlignedString(
+ chestProfit.name,
+ (chestProfit.profit > 0
+ ? EnumChatFormatting.GREEN.toString()
+ : EnumChatFormatting.RED) + Utils.shortNumberFormat(chestProfit.profit, 0),
+ x,
+ y,
+ 160
+ );
+
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ int width = scaledResolution.getScaledWidth();
+ int height = scaledResolution.getScaledHeight();
+
+ int mouseX = Utils.getMouseX();
+ int mouseY = Utils.getMouseY();
+
+ if (Utils.isWithinRect(mouseX, mouseY, x, y, 160, 10))
+ Utils.drawHoveringText(
+ chestProfit.lore,
+ mouseX,
+ mouseY,
+ width,
+ height,
+ -1,
+ Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+
+ }
+
+ /**
+ * Dataclass holding info on a single Dungeon Chest Preview
+ * <p>
+ * This includes:
+ * <ul>
+ * <li>The items, represented as a SkyblockItem</li>
+ * <li>The cost to open the chest</li>
+ * </ul>
+ *
+ * @see SkyblockItem
+ */
+ private static class DungeonChest {
+ private List<SkyblockItem> items = new ArrayList<>();
+ private List<String> lore;
+ private int costToOpen = -1;
+ private String name;
+ private int slot;
+ private boolean shouldHighlight;
+ private double profit;
+
+ public double getProfit() {
+ return profit;
+ }
+
+ public void calculateProfitAndBuildLore() {
+ profit = 0d;
+ lore = new ArrayList<>();
+ lore.add(name);
+ for (SkyblockItem item : items) {
+ double cost = item.calculateCost();
+ profit += cost;
+ lore.add(
+ EnumChatFormatting.AQUA + " - " + item.getDisplayName() + EnumChatFormatting.RESET + " " +
+ EnumChatFormatting.GREEN +
+ Utils.shortNumberFormat(cost, 0));
+ }
+ lore.add("");
+ profit -= costToOpen;
+ lore.add(
+ EnumChatFormatting.AQUA + "Cost to open: " + EnumChatFormatting.RED + Utils.shortNumberFormat(costToOpen, 0));
+ lore.add(
+ EnumChatFormatting.AQUA + "Total profit: " + (profit > 0 ? EnumChatFormatting.GREEN : EnumChatFormatting.RED) +
+ Utils.shortNumberFormat(profit, 0));
+ }
+ }
+
+ /**
+ * Dataclass holding info on a single skyblock item which is part of a DungeonChest
+ * <p>
+ * This includes:
+ * <ul>
+ * <li>The internal name of the item</li>
+ * <li>The amount</li>
+ * </ul>
+ *
+ * @see DungeonChest
+ */
+ private static class SkyblockItem {
+ private final String internalName;
+ private final int amount;
+
+ private SkyblockItem(String internalName, int amount) {
+ this.internalName = internalName;
+ this.amount = amount;
+ }
+
+ /**
+ * Try to create a SkyblockItem from the given lore line.
+ * <p>
+ * This involves checking for:
+ * <ul>
+ * <li>Enchanted books</li>
+ * <li>Dungeon essence</li>
+ * <li>Normal items that can appear in dungeon chests</li>
+ * </ul>
+ *
+ * @param line the line to be parsed
+ * @return a new SkyblockItem if possible, otherwise null
+ */
+ public static @Nullable SkyblockItem createFromLoreEntry(String line) {
+ Matcher essenceMatcher = essencePattern.matcher(line);
+ Matcher enchantedBookMatcher = enchantedBookPattern.matcher(line);
+
+ if (enchantedBookMatcher.matches()) {
+ String enchant = StringUtils.cleanColour(enchantedBookMatcher.group("enchantName"));
+
+ for (Map.Entry<String, JsonObject> entry : NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .entrySet()) {
+ String displayName = StringUtils.cleanColour(entry.getValue().get("displayname").getAsString());
+ if (displayName.equals("Enchanted Book")) {
+ JsonArray lore = entry.getValue().get("lore").getAsJsonArray();
+ String enchantName = StringUtils.cleanColour(lore.get(0).getAsString());
+ if (enchant.equals(enchantName)) {
+ return new SkyblockItem(entry.getKey(), 1);
+ }
+ }
+ }
+ } else if (essenceMatcher.matches()) {
+ String essenceType = essenceMatcher.group("essenceType");
+ String essenceAmount = essenceMatcher.group("essenceAmount");
+ if (essenceType == null || essenceAmount == null) {
+ return null;
+ }
+
+ String internalName = "ESSENCE_" + essenceType.toUpperCase(Locale.ROOT);
+ if (!NotEnoughUpdates.INSTANCE.manager.isValidInternalName(internalName)) {
+ return null;
+ }
+
+ //this can only be an integer if the regex matches
+ int amount = Integer.parseInt(essenceAmount);
+ return new SkyblockItem(internalName, amount);
+ } else {
+ String s = StringUtils.cleanColour(line.trim());
+ for (Map.Entry<String, JsonObject> entries : NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .entrySet()) {
+ String displayName = entries.getValue().get("displayname").getAsString();
+ String cleanDisplayName = StringUtils.cleanColour(displayName);
+ if (s.equals(cleanDisplayName)) {
+ return new SkyblockItem(entries.getKey(), 1);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Calculate the price of this item, factoring in the amount
+ *
+ * @return total price
+ */
+ public double calculateCost() {
+ double price = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarOrBin(internalName, true);
+ if (price != -1) {
+ return price * amount;
+ }
+ return 0d;
+ }
+
+ public String getDisplayName() {
+ JsonObject entry = NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withKnownInternalName(
+ internalName).resolveToItemListJson();
+ if (entry != null) {
+ String displayName = entry.get("displayname").getAsString();
+ String cleanedDisplayName = StringUtils.cleanColour(displayName);
+ if ("Enchanted Book".equals(cleanedDisplayName)) {
+ return entry.get("lore").getAsJsonArray().get(0).getAsString();
+ } else {
+ return entry.get("displayname").getAsString();
+ }
+ }
+ return "ERROR";
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnderNodes.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnderNodes.java
new file mode 100644
index 00000000..b0823a7d
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/EnderNodes.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscfeatures;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.SpecialColour;
+import io.github.moulberry.notenoughupdates.util.TitleUtil;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.ChatComponentText;
+
+public class EnderNodes {
+ // TODO Add ender node highliter
+ // TODO Add ender node counter ( maybe money estimation )
+
+ public static void dispalyEndermiteNotif() {
+ if (NotEnoughUpdates.INSTANCE.config.notifications.endermiteAlert && SBInfo.getInstance().getLocation() != null &&
+ SBInfo.getInstance().getLocation().equals("combat_3")) {
+ TitleUtil.getInstance().createTitle("Nested Endermite",
+ NotEnoughUpdates.INSTANCE.config.notifications.endermiteAlertTicks,
+ SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.notifications.endermiteAlertColor));
+ Minecraft.getMinecraft().thePlayer.playSound("random.orb", 1, 1);
+ }
+ }
+}
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 75f1b427..5fa68fc2 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/FairySouls.java
@@ -29,11 +29,11 @@ import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.BlockPos;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent;
@@ -177,6 +177,7 @@ public class FairySouls {
double factor = normalize(currentDistSq, 0.0, farSoulDistSq);
int rgb = interpolateColors(closeColor, farColor, Math.min(0.40, factor));
RenderUtils.renderBeaconBeamOrBoundingBox(currentSoul, rgb, 1.0f, event.partialTicks);
+ if (NotEnoughUpdates.INSTANCE.config.misc.fairySoulWaypointDistance) RenderUtils.renderWayPoint(currentSoul, event.partialTicks);
}
}
@@ -370,7 +371,7 @@ public class FairySouls {
}
private static void print(String s) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(s));
+ Utils.addChatMessage(s);
}
private static void printHelp() {
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 f68f3c58..4fc63734 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java
@@ -150,9 +150,7 @@ public class ItemCooldowns {
} else if (internalname.contains("_DRILL_")) {
char lastChar = internalname.charAt(internalname.length() - 1);
return lastChar >= '0' && lastChar <= '9';
- } else if (internalname.equals("DIVAN_DRILL")) {
- return true;
- } else return internalname.equals("GEMSTONE_GAUNTLET");
+ } else return internalname.equals("GEMSTONE_GAUNTLET") || internalname.equals("PICKONIMBUS") || internalname.equals("DIVAN_DRILL");
}
private static void updatePickaxeCooldown() {
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 e1b9d567..15fc8ef8 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCustomizeManager.java
@@ -269,7 +269,7 @@ public class ItemCustomizeManager {
return CUSTOM_GLINT_TEXTURE;
}
- private static String getUuidForItem(ItemStack stack) {
+ public static String getUuidForItem(ItemStack stack) {
if (!stack.hasTagCompound()) return null;
int nbtHash = stack.getTagCompound().hashCode();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java
index 6244c32c..89e95e25 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java
@@ -38,7 +38,6 @@ import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.Vec3i;
import net.minecraftforge.client.event.RenderWorldLastEvent;
@@ -93,7 +92,7 @@ public class Navigation {
}
}
- private NotEnoughUpdates neu;
+ private final NotEnoughUpdates neu;
public Navigation(NotEnoughUpdates notEnoughUpdates) {
neu = notEnoughUpdates;
@@ -379,8 +378,7 @@ public class Navigation {
private void showError(String message, boolean log) {
EntityPlayerSP player = Minecraft.getMinecraft().thePlayer;
if (player != null)
- player.addChatMessage(new ChatComponentText(EnumChatFormatting.DARK_RED +
- "[NEU-Waypoint] " + message));
+ Utils.addChatMessage(EnumChatFormatting.DARK_RED + "[NEU-Waypoint] " + message);
if (log)
new RuntimeException("[NEU-Waypoint] " + message).printStackTrace();
}
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 776e3647..20fa553f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java
@@ -1087,7 +1087,7 @@ public class PetInfoOverlay extends TextOverlay {
PetInfoOverlay.config.selectedPet = -1;
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
EnumChatFormatting.RED + "[NEU] Can't find pet \u00a7" + petStringMatch +
- EnumChatFormatting.RED + " try revisiting all pages of /pets."));
+ EnumChatFormatting.RED + " try revisiting all pages of /pets."));
}
}
} else if ((chatMessage.toLowerCase().startsWith("you despawned your")) || (chatMessage.toLowerCase().contains(
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 e06c271f..cc9f36fa 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java
@@ -21,7 +21,10 @@ package io.github.moulberry.notenoughupdates.miscgui;
import com.google.common.collect.ImmutableList;
import io.github.moulberry.notenoughupdates.NEUManager;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.ArrowPagesUtils;
import io.github.moulberry.notenoughupdates.recipes.NeuRecipe;
+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;
@@ -38,24 +41,20 @@ import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
-import org.lwjgl.opengl.GL11;
-import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GuiItemRecipe extends GuiScreen {
- public static final ResourceLocation resourcePacksTexture = new ResourceLocation("textures/gui/resource_packs.png");
public static final ResourceLocation tabsTexture = new ResourceLocation("notenoughupdates", "textures/gui/tab.png");
public static final int SLOT_SIZE = 16;
public static final int SLOT_SPACING = SLOT_SIZE + 2;
- public static final int BUTTON_WIDTH = 7;
- public static final int BUTTON_HEIGHT = 11;
public static final int TITLE_X = 28;
public static final int TITLE_Y = 6;
public static final int HOTBAR_SLOT_X = 8;
@@ -89,6 +88,7 @@ public class GuiItemRecipe extends GuiScreen {
if (!tabs.contains(recipe.getType()))
tabs.add(recipe.getType());
}
+ tabs.sort(Comparator.naturalOrder());
changeRecipe(0, 0);
}
@@ -145,7 +145,8 @@ public class GuiItemRecipe extends GuiScreen {
Utils.drawItemStack(slot.getItemStack(), slot.getX(this), slot.getY(this), true);
}
- drawArrows(currentRecipe, mouseX, mouseY);
+ int[] topLeft = currentRecipe.getPageFlipPositionLeftTopCorner();
+ ArrowPagesUtils.onDraw(guiLeft, guiTop, topLeft, currentIndex, getCurrentRecipeList().size());
Utils.drawStringScaledMaxWidth(
currentRecipe.getTitle(),
@@ -220,61 +221,6 @@ public class GuiItemRecipe extends GuiScreen {
}
}
- public static final int BUTTON_POSITION_RIGHT_OFFSET_X = 37;
- public static final int PAGE_STRING_OFFSET_X = 22;
- public static final int PAGE_STRING_OFFSET_Y = 6;
-
- private void drawArrows(
- NeuRecipe currentRecipe,
- int mouseX,
- int mouseY
- ) {
- int recipeCount = getCurrentRecipeList().size();
- if (recipeCount < 2) return;
- int[] topLeft = currentRecipe.getPageFlipPositionLeftTopCorner();
- int buttonPositionLeftX = topLeft[0];
- int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X;
- int pageStringX = buttonPositionLeftX + PAGE_STRING_OFFSET_X;
- int buttonPositionY = topLeft[1];
- int pageStringY = buttonPositionY + PAGE_STRING_OFFSET_Y;
-
- boolean leftSelected = isWithinRect(
- mouseX - guiLeft,
- mouseY - guiTop,
- buttonPositionLeftX,
- buttonPositionY,
- BUTTON_WIDTH,
- BUTTON_HEIGHT
- );
- boolean rightSelected = isWithinRect(
- mouseX - guiLeft,
- mouseY - guiTop,
- buttonPositionRightX,
- buttonPositionY,
- BUTTON_WIDTH,
- BUTTON_HEIGHT
- );
- Minecraft.getMinecraft().getTextureManager().bindTexture(resourcePacksTexture);
-
- if (currentIndex != 0)
- Utils.drawTexturedRect(guiLeft + buttonPositionLeftX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT,
- 34 / 256f, 48 / 256f,
- leftSelected ? 37 / 256f : 5 / 256f, leftSelected ? 59 / 256f : 27 / 256f
- );
- if (currentIndex != recipeCount - 1)
- Utils.drawTexturedRect(guiLeft + buttonPositionRightX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT,
- 10 / 256f, 24 / 256f,
- rightSelected ? 37 / 256f : 5 / 256f, rightSelected ? 59 / 256f : 27 / 256f
- );
- GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
-
- String selectedPage = (currentIndex + 1) + "/" + recipeCount;
-
- Utils.drawStringCenteredScaledMaxWidth(selectedPage, fontRendererObj,
- guiLeft + pageStringX, guiTop + pageStringY, false, 24, Color.BLACK.getRGB()
- );
- }
-
public List<RecipeSlot> getPlayerInventory() {
List<RecipeSlot> slots = new ArrayList<>();
ItemStack[] inventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory;
@@ -317,6 +263,12 @@ public class GuiItemRecipe extends GuiScreen {
}
}
}
+
+ if (keyPressed == manager.keybindPreviousRecipe.getKeyCode()) {
+ NotEnoughUpdates.INSTANCE.openGui = RecipeHistory.getPrevious();
+ } else if (keyPressed == manager.keybindNextRecipe.getKeyCode()) {
+ NotEnoughUpdates.INSTANCE.openGui = RecipeHistory.getNext();
+ }
}
public void changeRecipe(int tabIndex, int recipeIndex) {
@@ -327,7 +279,7 @@ public class GuiItemRecipe extends GuiScreen {
}
@Override
- protected void actionPerformed(GuiButton p_actionPerformed_1_) throws IOException {
+ protected void actionPerformed(GuiButton p_actionPerformed_1_) {
getCurrentRecipe().actionPerformed(p_actionPerformed_1_);
}
@@ -336,38 +288,23 @@ public class GuiItemRecipe extends GuiScreen {
super.mouseClicked(mouseX, mouseY, mouseButton);
NeuRecipe currentRecipe = getCurrentRecipe();
int[] topLeft = currentRecipe.getPageFlipPositionLeftTopCorner();
- int buttonPositionLeftX = topLeft[0];
- int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X;
- int buttonPositionY = topLeft[1];
-
- if (isWithinRect(
- mouseX - guiLeft,
- mouseY - guiTop,
- buttonPositionLeftX,
- buttonPositionY,
- BUTTON_WIDTH,
- BUTTON_HEIGHT
- ) &&
- currentIndex > 0) {
- changeRecipe(currentTab, currentIndex - 1);
- Utils.playPressSound();
- return;
- }
- if (isWithinRect(
- mouseX - guiLeft,
- mouseY - guiTop,
- buttonPositionRightX,
- buttonPositionY,
- BUTTON_WIDTH,
- BUTTON_HEIGHT
- ) &&
- currentIndex < getCurrentRecipeList().size()) {
- changeRecipe(currentTab, currentIndex + 1);
- Utils.playPressSound();
- return;
+ if (mouseButton == 3) {
+ NotEnoughUpdates.INSTANCE.openGui = RecipeHistory.getPrevious();
+ } else if (mouseButton == 4) {
+ NotEnoughUpdates.INSTANCE.openGui = RecipeHistory.getNext();
}
+ if (ArrowPagesUtils.onPageSwitchMouse(
+ guiLeft,
+ guiTop,
+ topLeft,
+ currentIndex,
+ getCurrentRecipeList().size(),
+ pageChange ->
+ changeRecipe(currentTab, pageChange)
+ )) return;
+
for (int i = 0; i < tabs.size(); i++) {
if (isWithinRect(
mouseX - guiLeft,
@@ -398,4 +335,9 @@ public class GuiItemRecipe extends GuiScreen {
currentRecipe.mouseClicked(this, mouseX, mouseY, mouseButton);
}
+
+ public void arrowKeyboardInput() {
+ ArrowPagesUtils.onPageSwitchKey(currentIndex, getCurrentRecipeList().size(), pageChange ->
+ changeRecipe(currentTab, pageChange));
+ }
}
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 e6c4dc74..828e50b1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/TrophyRewardOverlay.java
@@ -160,7 +160,7 @@ public class TrophyRewardOverlay {
texts.add("Trophy Fish Exchange");
texts.add("Magma Fish: §e" + total);
- for (Map.Entry<String, Integer> entry : sortByValue(totalExchange).entrySet()) {
+ for (Map.Entry<String, Integer> entry : sortByValueReverse(totalExchange).entrySet()) {
String name = entry.getKey();
int amount = totalAmount.get(name);
String[] split = name.split(" ");
@@ -206,6 +206,19 @@ public class TrophyRewardOverlay {
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
list.sort(Map.Entry.comparingByValue());
+
+ Map<K, V> result = new LinkedHashMap<>();
+ for (Map.Entry<K, V> entry : list) {
+ result.put(entry.getKey(), entry.getValue());
+ }
+
+ return result;
+ }
+
+ //TODO move into utils class maybe?
+ public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueReverse(Map<K, V> map) {
+ List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
+ list.sort(Map.Entry.comparingByValue());
Collections.reverse(list);
Map<K, V> result = new LinkedHashMap<>();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/ApiData.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/ApiData.java
new file mode 100644
index 00000000..215c3fe7
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/ApiData.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper;
+
+import java.util.List;
+import java.util.Map;
+
+public class ApiData {
+
+ private final Map<String, Integer> highestCollectionTier;
+ private final Map<String, Integer> slayerTiers;
+ private final int magesReputation;
+ private final int barbariansReputation;
+ private final boolean collectionApiDisabled;
+ private final List<String> craftedMinions;
+ private int peltCount;
+
+ public ApiData(
+ Map<String, Integer> highestCollectionTier,
+ Map<String, Integer> slayerTiers,
+ int magesReputation,
+ int barbariansReputation,
+ boolean collectionApiDisabled,
+ List<String> craftedMinions,
+ int peltCount
+ ) {
+ this.highestCollectionTier = highestCollectionTier;
+ this.slayerTiers = slayerTiers;
+ this.magesReputation = magesReputation;
+ this.barbariansReputation = barbariansReputation;
+ this.collectionApiDisabled = collectionApiDisabled;
+ this.craftedMinions = craftedMinions;
+ this.peltCount = peltCount;
+ }
+
+ public Map<String, Integer> getHighestCollectionTier() {
+ return highestCollectionTier;
+ }
+
+ public Map<String, Integer> getSlayerTiers() {
+ return slayerTiers;
+ }
+
+ public int getMagesReputation() {
+ return magesReputation;
+ }
+
+ public int getBarbariansReputation() {
+ return barbariansReputation;
+ }
+
+ public boolean isCollectionApiDisabled() {
+ return collectionApiDisabled;
+ }
+
+ public List<String> getCraftedMinions() {
+ return craftedMinions;
+ }
+
+ public int getPeltCount() {
+ return peltCount;
+ }
+
+ public void setPeltCount(int peltCount) {
+ this.peltCount = peltCount;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/Minion.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/Minion.java
new file mode 100644
index 00000000..ba38b01d
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/Minion.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables.OverviewLine;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.MinionRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CustomSource;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Minion extends OverviewLine {
+ private final String internalName;
+ private final int tier;
+ private String displayName;
+ private MinionSource minionSource;
+ private CustomSource customSource;
+ private Minion parent;
+ private final List<MinionRequirement> requirements = new ArrayList<>();
+
+ private boolean crafted = false;
+ private boolean meetRequirements = false;
+
+ public Minion(String internalName, int tier) {
+ this.internalName = internalName;
+ this.tier = tier;
+ }
+
+ public MinionSource getMinionSource() {
+ return minionSource;
+ }
+
+ public void setMinionSource(MinionSource minionSource) {
+ this.minionSource = minionSource;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public boolean isCrafted() {
+ return crafted;
+ }
+
+ public void setCrafted(boolean crafted) {
+ this.crafted = crafted;
+ }
+
+ public String getInternalName() {
+ return internalName;
+ }
+
+ public void setParent(Minion parent) {
+ this.parent = parent;
+ }
+
+ public Minion getParent() {
+ return parent;
+ }
+
+ public int getTier() {
+ return tier;
+ }
+
+ public List<MinionRequirement> getRequirements() {
+ return requirements;
+ }
+
+ public boolean doesMeetRequirements() {
+ return meetRequirements;
+ }
+
+ public void setMeetRequirements(boolean meetRequirements) {
+ this.meetRequirements = meetRequirements;
+ }
+
+ @Override
+ public void onClick() {
+ NotEnoughUpdates.INSTANCE.manager.displayGuiItemRecipe(internalName);
+ }
+
+ public void setCustomSource(CustomSource customSource) {
+ this.customSource = customSource;
+ }
+
+ public CustomSource getCustomSource() {
+ return customSource;
+ }
+}
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
new file mode 100644
index 00000000..f3c8a86a
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/MinionHelperManager.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+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;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.repo.MinionHelperRepoLoader;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.MinionHelperOverlay;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.MinionHelperTooltips;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CustomSource;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.util.MinionHelperPriceCalculation;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.util.MinionHelperRequirementsManager;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.inventory.Container;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraftforge.common.MinecraftForge;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MinionHelperManager {
+ private static MinionHelperManager instance = null;
+ private final Map<String, Minion> minions = new HashMap<>();
+ private int needForNextSlot = -1;
+ private int localPelts = -1;
+
+ private final MinionHelperPriceCalculation priceCalculation = new MinionHelperPriceCalculation(this);
+ private final MinionHelperRequirementsManager requirementsManager = new MinionHelperRequirementsManager(this);
+ private final MinionHelperApiLoader api = new MinionHelperApiLoader(this);
+ private final MinionHelperRepoLoader repo = new MinionHelperRepoLoader(this);
+ private final MinionHelperOverlay overlay = new MinionHelperOverlay(this);
+ private final MinionHelperInventoryLoader inventoryLoader = new MinionHelperInventoryLoader(this);
+ private String debugPlayerUuid;
+ private String debugProfileName;
+ private int debugNeedForNextSlot = -1;
+
+ public static MinionHelperManager getInstance() {
+ if (instance == null) {
+ instance = new MinionHelperManager();
+ }
+ return instance;
+ }
+
+ private MinionHelperManager() {
+ MinecraftForge.EVENT_BUS.register(priceCalculation);
+ MinecraftForge.EVENT_BUS.register(api);
+ MinecraftForge.EVENT_BUS.register(repo);
+ MinecraftForge.EVENT_BUS.register(overlay);
+ MinecraftForge.EVENT_BUS.register(new MinionHelperTooltips(this));
+ MinecraftForge.EVENT_BUS.register(new MinionHelperChatLoader(this));
+ MinecraftForge.EVENT_BUS.register(inventoryLoader);
+ }
+
+ public boolean inCraftedMinionsInventory() {
+ if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return false;
+
+ Minecraft minecraft = Minecraft.getMinecraft();
+ if (minecraft == null || minecraft.thePlayer == null) return false;
+
+ Container inventoryContainer = minecraft.thePlayer.openContainer;
+ if (!(inventoryContainer instanceof ContainerChest)) return false;
+ ContainerChest containerChest = (ContainerChest) inventoryContainer;
+ String name = containerChest.getLowerChestInventory().getDisplayName().getUnformattedText();
+ return name.equalsIgnoreCase("Crafted Minions");
+ }
+
+ public boolean notReady() {
+ return !repo.isReadyToUse() || !api.isReadyToUse();
+ }
+
+ public boolean isInvalidApiKey() {
+ return api.isInvalidApiKey();
+ }
+
+ public Minion getMinionById(String internalName) {
+ if (minions.containsKey(internalName)) {
+ return minions.get(internalName);
+ } else {
+ System.err.println("Cannot get minion for id '" + internalName + "'!");
+ return null;
+ }
+ }
+
+ public Minion getMinionByName(String displayName, int tier) {
+ for (Minion minion : minions.values()) {
+ if (displayName.equals(minion.getDisplayName())) {
+ if (minion.getTier() == tier) {
+ return minion;
+ }
+ }
+ }
+ System.err.println("Cannot get minion for display name '" + displayName + "'!");
+ return null;
+ }
+
+ public void createMinion(String internalName, int tier) {
+ minions.put(internalName, new Minion(internalName, tier));
+ }
+
+ public String formatInternalName(String minionName) {
+ return minionName.toUpperCase().replace(" ", "_");
+ }
+
+ private List<Minion> getChildren(Minion minion) {
+ List<Minion> list = new ArrayList<>();
+ for (Minion other : minions.values()) {
+ if (minion == other.getParent()) {
+ list.add(other);
+ list.addAll(getChildren(other));
+ break;
+ }
+ }
+ return list;
+ }
+
+ public void onProfileSwitch() {
+ for (Minion minion : minions.values()) {
+ minion.setCrafted(false);
+ minion.setMeetRequirements(false);
+ }
+
+ needForNextSlot = -1;
+ api.onProfileSwitch();
+ overlay.onProfileSwitch();
+ inventoryLoader.onProfileSwitch();
+ }
+
+ public void reloadData() {
+ requirementsManager.reloadRequirements();
+
+ ApiData apiData = api.getApiData();
+ if (apiData != null) {
+ for (String minion : apiData.getCraftedMinions()) {
+ setCrafted(getMinionById(minion));
+ }
+ }
+ }
+
+ public void setCrafted(Minion minion) {
+ minion.setCrafted(true);
+
+ if (minion.getCustomSource() != null) {
+ minion.setMeetRequirements(true);
+
+ for (Minion child : getChildren(minion)) {
+ child.setMeetRequirements(true);
+ }
+ }
+ }
+
+ public void handleCommand(String[] args) {
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) {
+ Utils.addChatMessage("§e[NEU] Minion Helper gui is disabled!");
+ return;
+ }
+
+ if (args.length > 1) {
+ String parameter = args[1];
+
+ if (parameter.equals("debugplayer")) {
+ if (args.length == 3) {
+ if (args[2].equals("reset")) {
+ Utils.addChatMessage("§e[NEU] Minion debug player reset.");
+ setDebugPlayer(null, null, -1);
+ return;
+ }
+ }
+ if (args.length < 4) {
+ Utils.addChatMessage("§c[NEU] Usage: /neudevtest minion " +
+ "setplayer <player-uuid> <player-profile-name> [need-for-next-slot]");
+ return;
+ }
+ String playerUuid = args[2];
+ String playerProfileName = args[3];
+ int need = args.length == 5 ? Integer.parseInt(args[4]) : -1;
+ setDebugPlayer(playerUuid, playerProfileName, need);
+ Utils.addChatMessage("§e[NEU] Minion debug player set.");
+ return;
+ }
+
+ if (args.length == 2) {
+ if (parameter.equals("clearminion")) {
+ minions.clear();
+ Utils.addChatMessage("minion map cleared");
+ return;
+ }
+ if (parameter.equals("reloadrepo")) {
+ repo.setDirty();
+ Utils.addChatMessage("repo reload requested");
+ return;
+ }
+ if (parameter.equals("reloadapi")) {
+ api.resetData();
+ api.setDirty();
+ Utils.addChatMessage("api reload requested");
+ return;
+ }
+ if (parameter.equals("clearapi")) {
+ api.resetData();
+ Utils.addChatMessage("api data cleared");
+ return;
+ }
+ }
+
+ if (args.length == 3) {
+ if (parameter.equals("maxperpage")) {
+ api.resetData();
+ int maxPerPage = Integer.parseInt(args[2]);
+ Utils.addChatMessage("set max per page to " + maxPerPage);
+ overlay.setMaxPerPage(maxPerPage);
+ return;
+ }
+ }
+
+ if (args.length == 4) {
+ if (parameter.equals("arrowpos")) {
+ int x = Integer.parseInt(args[2]);
+ int y = Integer.parseInt(args[3]);
+ Utils.addChatMessage("set page pos to " + x + ";" + y);
+ overlay.setTopLeft(new int[]{x, y});
+ return;
+ }
+ }
+ }
+
+ Utils.addChatMessage("");
+ Utils.addChatMessage("§3NEU Minion Helper commands: §c(for testing only!)");
+ Utils.addChatMessage("§6/neudevtest minion clearminion §7Clears the minion map");
+ Utils.addChatMessage("§6/neudevtest minion reloadrepo §7Manually loading the data from repo");
+ Utils.addChatMessage("§6/neudevtest minion reloadapi §7Manually loading the data from api");
+ Utils.addChatMessage("§6/neudevtest minion clearapi §7Clears the api data");
+ Utils.addChatMessage("§6/neudevtest minion maxperpage <number> §7Changes the max minions per page number");
+ Utils.addChatMessage("§6/neudevtest minion arrowpos <x, y> §7Changes the position of the page numbers");
+ Utils.addChatMessage("§6/neudevtest minion debugplayer <player-uuid> <player-profile-name> [need-for-next-slot] §7" +
+ "See the Minions missing of other player");
+ Utils.addChatMessage("");
+ }
+
+ private void setDebugPlayer(String playerUuid, String playerProfileName, int fakeNeedForNextSlot) {
+ this.debugPlayerUuid = playerUuid;
+ this.debugProfileName = playerProfileName;
+ this.debugNeedForNextSlot = fakeNeedForNextSlot;
+
+ onProfileSwitch();
+ }
+
+ public MinionHelperPriceCalculation getPriceCalculation() {
+ return priceCalculation;
+ }
+
+ public MinionHelperRequirementsManager getRequirementsManager() {
+ return requirementsManager;
+ }
+
+ public MinionHelperApiLoader getApi() {
+ return api;
+ }
+
+ public MinionHelperOverlay getOverlay() {
+ return overlay;
+ }
+
+ public Map<String, Minion> getAllMinions() {
+ return minions;
+ }
+
+ public void setNeedForNextSlot(int needForNextSlot) {
+ this.needForNextSlot = needForNextSlot;
+ overlay.resetCache();
+ }
+
+ public int getNeedForNextSlot() {
+ return needForNextSlot;
+ }
+
+ public void setCustomSource(Minion minion, CustomSource customSource) {
+ MinionSource minionSource = minion.getMinionSource();
+ if (minionSource == null) {
+ minion.setMinionSource(customSource);
+ }
+ minion.setCustomSource(customSource);
+ }
+
+ public int getLocalPelts() {
+ return localPelts;
+ }
+
+ public void setLocalPelts(int pelts) {
+ localPelts = pelts;
+ if (localPelts != -1) {
+ ApiData apiData = api.getApiData();
+ if (apiData != null) {
+ apiData.setPeltCount(localPelts);
+ }
+ }
+ }
+
+ public String getDebugPlayerUuid() {
+ return debugPlayerUuid;
+ }
+
+ public String getDebugProfileName() {
+ return debugProfileName;
+ }
+
+ public int getDebugNeedForNextSlot() {
+ return debugNeedForNextSlot;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java
new file mode 100644
index 00000000..aaa398f4
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders;
+
+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.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.events.ProfileDataLoadedEvent;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.ApiData;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MinionHelperApiLoader {
+ private final MinionHelperManager manager;
+ private boolean dirty = true;
+ private int ticks = 0;
+ private boolean collectionApiEnabled = true;
+ private boolean ignoreWorldSwitches = false;
+ private boolean readyToUse = false;
+ private ApiData apiData = null;
+ private boolean notifyNoCollectionApi = false;
+ private long lastLoaded = 0;
+ private boolean invalidApiKey = false;
+
+ public MinionHelperApiLoader(MinionHelperManager manager) {
+ this.manager = manager;
+ }
+
+ @SubscribeEvent
+ public void onWorldLoad(WorldEvent.Load event) {
+ if (ignoreWorldSwitches) return;
+
+ setDirty();
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (Minecraft.getMinecraft().thePlayer == null) return;
+ if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return;
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return;
+ ticks++;
+
+ if (ticks % 20 != 0) return;
+
+ if (dirty) {
+ load();
+ } else {
+ if (System.currentTimeMillis() > lastLoaded + 60_000 * 3) {
+ dirty = true;
+ }
+ }
+ }
+
+ private void load() {
+ lastLoaded = System.currentTimeMillis();
+
+ dirty = false;
+ String uuid = getUuid();
+ if (uuid == null) return;
+
+ NotEnoughUpdates.INSTANCE.manager.apiUtils.updateProfileData(uuid);
+ }
+
+ private String getUuid() {
+ EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer;
+ if (thePlayer == null) return null;
+
+ String debugPlayerUuid = manager.getDebugPlayerUuid();
+ if (debugPlayerUuid != null) return debugPlayerUuid;
+
+ return thePlayer.getUniqueID().toString().replace("-", "");
+ }
+
+ @SubscribeEvent
+ public void onApiDataLoaded(ProfileDataLoadedEvent event) {
+ JsonObject data = event.getData();
+ if (data == null) {
+ invalidApiKey = true;
+ return;
+ }
+ invalidApiKey = false;
+
+ if (!data.has("success") || !data.get("success").getAsBoolean()) return;
+ JsonArray profiles = data.getAsJsonArray("profiles");
+ for (JsonElement element : profiles) {
+ JsonObject profile = element.getAsJsonObject();
+ String profileName = profile.get("cute_name").getAsString();
+ JsonObject members = profile.getAsJsonObject("members");
+ JsonObject player = members.getAsJsonObject(getUuid());
+
+ String debugProfileName = manager.getDebugProfileName();
+ String currentProfile = debugProfileName != null ? debugProfileName : SBInfo.getInstance().currentProfile;
+
+ if (profileName.equals(currentProfile)) {
+ readData(player, members);
+ return;
+ }
+ }
+ }
+
+ private void readData(JsonObject player, JsonObject members) {
+ int magesReputation = 0;
+ int barbariansReputation = 0;
+ if (player.has("nether_island_player_data")) {
+ JsonObject netherData = player.getAsJsonObject("nether_island_player_data");
+ if (netherData.has("mages_reputation")) {
+ magesReputation = netherData.get("mages_reputation").getAsInt();
+ }
+ if (netherData.has("barbarians_reputation")) {
+ barbariansReputation = netherData.get("barbarians_reputation").getAsInt();
+ }
+ }
+
+ apiData = new ApiData(
+ getCollections(player),
+ getSlayers(player),
+ magesReputation,
+ barbariansReputation,
+ !collectionApiEnabled,
+ loadCraftedMinions(members),
+ loadPeltCount(player)
+ );
+
+ manager.reloadData();
+ readyToUse = true;
+ }
+
+ private int loadPeltCount(JsonObject player) {
+ int localPelts = manager.getLocalPelts();
+ if (localPelts != -1) return localPelts;
+
+ int peltCount = 0;
+ if (player.has("trapper_quest")) {
+ JsonObject jsonObject = player.getAsJsonObject("trapper_quest");
+ if (jsonObject.has("pelt_count")) {
+ peltCount = jsonObject.get("pelt_count").getAsInt();
+ }
+ }
+ return peltCount;
+ }
+
+ private Map<String, Integer> getSlayers(JsonObject player) {
+ JsonObject slayerLeveling = Constants.LEVELING.getAsJsonObject("slayer_xp");
+
+ Map<String, Integer> slayerTier = new HashMap<>();
+ if (player.has("slayer_bosses")) {
+ JsonObject slayerBosses = player.getAsJsonObject("slayer_bosses");
+ for (Map.Entry<String, JsonElement> entry : slayerBosses.entrySet()) {
+ String name = entry.getKey();
+ JsonObject slayerEntry = entry.getValue().getAsJsonObject();
+ if (slayerEntry.has("xp")) {
+ long xp = slayerEntry.get("xp").getAsLong();
+
+ int tier = 0;
+ for (JsonElement element : slayerLeveling.getAsJsonArray(name)) {
+ int needForLevel = element.getAsInt();
+ if (xp >= needForLevel) {
+ tier++;
+ } else {
+ break;
+ }
+ }
+ slayerTier.put(name, tier);
+ }
+ }
+ }
+ return slayerTier;
+ }
+
+ private Map<String, Integer> getCollections(JsonObject player) {
+ Map<String, Integer> highestCollectionTier = new HashMap<>();
+ if (player.has("unlocked_coll_tiers")) {
+ for (JsonElement element : player.get("unlocked_coll_tiers").getAsJsonArray()) {
+ String text = element.getAsString();
+ String[] split = text.split("_");
+ int level = Integer.parseInt(split[split.length - 1]);
+ String name = StringUtils.removeLastWord(text, "_");
+
+ //Because skyblock is good in naming things
+ LinkedHashMap<String, ItemStack> collectionMap = ProfileViewer.getCollectionToCollectionDisplayMap();
+ if (collectionMap.containsKey(name)) {
+ ItemStack itemStack = collectionMap.get(name);
+ String displayName = itemStack.getDisplayName();
+ name = Utils.cleanColour(displayName);
+ name = manager.formatInternalName(name);
+ } else {
+ //Doing this since there is no space in the profile viewer gui for more entries in collectionToCollectionDisplayMap
+ if (name.equals("SAND:1")) name = "RED_SAND";
+ if (name.equals("MYCEL")) name = "MYCELIUM";
+ }
+
+ level = Math.max(highestCollectionTier.getOrDefault(name, 0), level);
+ highestCollectionTier.put(name, level);
+ }
+ if (!collectionApiEnabled) {
+ Utils.addChatMessage("§e[NEU] Collection API detected!");
+ }
+ collectionApiEnabled = true;
+ } else {
+ if (collectionApiEnabled) {
+ notifyNoCollectionApi = true;
+ }
+ collectionApiEnabled = false;
+ }
+ return highestCollectionTier;
+ }
+
+ private List<String> loadCraftedMinions(JsonObject members) {
+ List<String> craftedMinions = new ArrayList<>();
+ for (Map.Entry<String, JsonElement> entry : members.entrySet()) {
+ JsonObject value = entry.getValue().getAsJsonObject();
+ if (value.has("crafted_generators")) {
+ for (JsonElement e : value.get("crafted_generators").getAsJsonArray()) {
+ String rawGenerator = e.getAsString();
+ String[] split = rawGenerator.split("_");
+ String tier = split[split.length - 1];
+ String name = rawGenerator.substring(0, rawGenerator.length() - tier.length() - 1);
+ String internalName = name + "_GENERATOR_" + tier;
+ craftedMinions.add(internalName);
+ }
+ }
+ }
+
+ return craftedMinions;
+ }
+
+ public void setDirty() {
+ dirty = true;
+ readyToUse = false;
+ }
+
+ public void prepareProfileSwitch() {
+ ignoreWorldSwitches = true;
+ readyToUse = false;
+ }
+
+ public void onProfileSwitch() {
+ apiData = null;
+ setDirty();
+ ignoreWorldSwitches = false;
+ collectionApiEnabled = true;
+ }
+
+ public boolean isReadyToUse() {
+ return readyToUse;
+ }
+
+ public ApiData getApiData() {
+ return apiData;
+ }
+
+ public boolean isCollectionApiDisabled() {
+ return apiData != null && apiData.isCollectionApiDisabled();
+ }
+
+ public void resetData() {
+ apiData = null;
+ }
+
+ public void setNotifyNoCollectionApi(boolean notifyNoCollectionApi) {
+ this.notifyNoCollectionApi = notifyNoCollectionApi;
+ }
+
+ public boolean isNotifyNoCollectionApi() {
+ return notifyNoCollectionApi;
+ }
+
+ public boolean isInvalidApiKey() {
+ return invalidApiKey;
+ }
+}
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
new file mode 100644
index 00000000..bef633d2
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperChatLoader.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class MinionHelperChatLoader {
+
+ private final MinionHelperManager manager;
+
+ //§aYou crafted a §eTier I Redstone Minion§a! That's a new one!
+ // §aCraft §e7 §amore unique Minions to unlock your §e9th Minion slot§a!
+ private final Pattern PATTERN_OWN_MINION = Pattern.compile(
+ "§r§aYou crafted a §eTier (\\S+) (.+) Minion§a! That's a new one!(\\r\\n|\\r|\\n)(.*)");
+ //§aYou crafted a §eTier VI Enderman Minion§a! That's a new one!
+
+ //§b[MVP§3+§b] Eisengolem§f §acrafted a §eTier I Birch Minion§a!
+ private final Pattern PATTERN_COOP_MINION = Pattern.compile(
+ "(.+)§f §acrafted a §eTier (\\S+) (.+) Minion§a!(§r)?(\\r\\n|\\r|\\n)?(.*)?");
+
+ public MinionHelperChatLoader(MinionHelperManager manager) {
+ this.manager = manager;
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
+ public void onChat(ClientChatReceivedEvent event) {
+ if (event.type != 0) return;
+ String message = event.message.getFormattedText();
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return;
+
+ try {
+ Matcher ownMatcher = PATTERN_OWN_MINION.matcher(message);
+ if (ownMatcher.matches()) {
+ String rawTier = ownMatcher.group(1);
+ int tier = Utils.parseRomanNumeral(rawTier);
+ String name = ownMatcher.group(2) + " Minion";
+
+ setCrafted(manager.getMinionByName(name, tier));
+ }
+
+ Matcher coopMatcher = PATTERN_COOP_MINION.matcher(message);
+ if (coopMatcher.matches()) {
+ String rawTier = coopMatcher.group(2);
+ int tier = Utils.parseRomanNumeral(rawTier);
+ String name = coopMatcher.group(3) + " Minion";
+
+ setCrafted(manager.getMinionByName(name, tier));
+ manager.getOverlay().resetCache();
+ }
+
+ if (message.startsWith("§r§7Switching to profile ")) {
+ manager.getApi().prepareProfileSwitch();
+ }
+
+ } catch (Exception e) {
+ Utils.addChatMessage(
+ "[NEU] §cMinion Helper failed reading the minion upgrade message. See the logs for more info!");
+ e.printStackTrace();
+ }
+ }
+
+ private void setCrafted(Minion minion) {
+ manager.setCrafted(minion);
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperInventoryLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperInventoryLoader.java
new file mode 100644
index 00000000..7fc703e6
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperInventoryLoader.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
+import io.github.moulberry.notenoughupdates.util.ItemUtils;
+import io.github.moulberry.notenoughupdates.util.TabListUtils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.inventory.Container;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraft.inventory.Slot;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class MinionHelperInventoryLoader {
+ private final MinionHelperManager manager;
+ private final List<String> pagesSeenAlready = new ArrayList<>();
+ private boolean dirty = true;
+
+ private int ticks = 0;
+
+ //§7Craft §b5 §7more §aunique §7minions
+ private final Pattern PATTERN_MINIONS_NEEDED = Pattern.compile("§7Craft §b(\\d+) §7more §aunique( §7minions)?");
+
+ //§r §r§fPelts: §r§59§r
+ private final Pattern PATTERN_PELTS = Pattern.compile("§r §r§fPelts: §r§5(\\d+)§r");
+
+ public MinionHelperInventoryLoader(MinionHelperManager manager) {
+ this.manager = manager;
+ }
+
+ @SubscribeEvent
+ public void onWorldLoad(WorldEvent.Load event) {
+ manager.setLocalPelts(-1);
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return;
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return;
+ if (manager.notReady()) return;
+ ticks++;
+
+ if (ticks % 5 != 0) return;
+
+ if (manager.inCraftedMinionsInventory()) {
+ checkInventory();
+ } else {
+ pagesSeenAlready.clear();
+ dirty = true;
+ }
+ }
+
+ private void checkInventory() {
+ Container openContainer = Minecraft.getMinecraft().thePlayer.openContainer;
+ if (openContainer instanceof ContainerChest) {
+ if (dirty) {
+ dirty = false;
+ checkNextSlot(openContainer);
+ checkLocalPelts();
+ }
+ if (manager.getDebugPlayerUuid() == null) {
+ loadMinionData(openContainer);
+ }
+ }
+ }
+
+ private void checkLocalPelts() {
+ int pelts = -1;
+ for (String name : TabListUtils.getTabList()) {
+ Matcher matcher = PATTERN_PELTS.matcher(name);
+ if (matcher.matches()) {
+ pelts = Integer.parseInt(matcher.group(1));
+ break;
+ }
+ }
+
+ manager.setLocalPelts(pelts);
+ }
+
+ private void checkNextSlot(Container openContainer) {
+ Slot informationSlot = openContainer.inventorySlots.get(50);
+ if (informationSlot.getHasStack()) {
+ ItemStack informationStack = informationSlot.getStack();
+ for (String line : ItemUtils.getLore(informationStack)) {
+ Matcher matcher = PATTERN_MINIONS_NEEDED.matcher(line);
+ if (matcher.matches()) {
+ int debugNeedForNextSlot = manager.getDebugNeedForNextSlot();
+ int needForNextSlot = debugNeedForNextSlot != -1 ? debugNeedForNextSlot : Integer.parseInt(matcher.group(1));
+
+ manager.setNeedForNextSlot(needForNextSlot);
+ return;
+ }
+ }
+ }
+ }
+
+ private void loadMinionData(Container openContainer) {
+ Slot firstSlot = openContainer.inventorySlots.get(10);
+ boolean shouldLoad = false;
+ if (firstSlot != null) {
+ if (firstSlot.getHasStack()) {
+ ItemStack stack = firstSlot.getStack();
+ String displayName = stack.getDisplayName();
+ if (!pagesSeenAlready.contains(displayName)) {
+ pagesSeenAlready.add(displayName);
+ shouldLoad = true;
+ }
+ }
+ }
+
+ if (!shouldLoad) return;
+
+ int crafted = 0;
+ for (Slot slot : openContainer.inventorySlots) {
+ if (!slot.getHasStack()) continue;
+ ItemStack stack = slot.getStack();
+ if (stack == null) continue;
+ if (slot.slotNumber != slot.getSlotIndex()) continue;
+
+ String displayName = stack.getDisplayName();
+ if (!displayName.contains(" Minion")) continue;
+
+ displayName = StringUtils.cleanColour(displayName);
+ int index = 0;
+ for (String line : ItemUtils.getLore(stack)) {
+ index++;
+ if (!line.contains("Tier")) {
+ continue;
+ }
+ if (line.contains("§a")) {
+ Minion minion = manager.getMinionByName(displayName, index);
+ if (!minion.isCrafted()) {
+ minion.setCrafted(true);
+ crafted++;
+ }
+ }
+ }
+ }
+ if (crafted > 0) {
+ manager.getOverlay().resetCache();
+ }
+ }
+
+ public void onProfileSwitch() {
+ dirty = true;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoLoader.java
new file mode 100644
index 00000000..49dac537
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoLoader.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.repo;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.CustomRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CustomSource;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.NpcSource;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class MinionHelperRepoLoader {
+ private final MinionHelperManager manager;
+ private boolean dirty = true;
+ private int ticks = 0;
+ private boolean readyToUse = false;
+ private final MinionHelperRepoMinionLoader minionLoader;
+ boolean errorWhileLoading = false;
+
+ public MinionHelperRepoLoader(MinionHelperManager manager) {
+ this.manager = manager;
+ minionLoader = new MinionHelperRepoMinionLoader(this, manager);
+ }
+
+ /**
+ * This adds support for the /neureloadrepo command
+ */
+ @SubscribeEvent(priority = EventPriority.LOWEST)
+ public void onRepoReload(RepositoryReloadEvent event) {
+ setDirty();
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ if (Minecraft.getMinecraft().thePlayer == null) return;
+ if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return;
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return;
+ ticks++;
+
+ if (ticks % 5 != 0) return;
+
+ if (dirty) {
+ dirty = false;
+ load();
+ }
+ }
+
+ void load() {
+ errorWhileLoading = false;
+
+ createMinions();
+
+ loadNpcData();
+ minionLoader.loadMinionData();
+ loadCustomSources();
+
+ testForMissingData();
+
+ manager.reloadData();
+ readyToUse = true;
+
+ if (errorWhileLoading) {
+ Utils.showOutdatedRepoNotification();
+ }
+ }
+
+ private void loadCustomSources() {
+ Map<String, String> customSource = new HashMap<>();
+
+ customSource.put("SNOW_GENERATOR_1", "Gifts");
+
+ customSource.put("FLOWER_GENERATOR_1", "Dark Auction");
+
+ customSource.put("REVENANT_GENERATOR_1", "Zombie Slayer");
+ customSource.put("TARANTULA_GENERATOR_1", "Spider Slayer");
+
+ for (Map.Entry<String, String> entry : customSource.entrySet()) {
+ String internalName = entry.getKey();
+ String sourceName = entry.getValue();
+ Minion minion = manager.getMinionById(internalName);
+ if (minion == null) continue;
+ manager.setCustomSource(minion, new CustomSource(sourceName));
+ }
+
+ manager.getMinionById("FLOWER_GENERATOR_1").getRequirements().add(new CustomRequirement(
+ "Buy a §cFlower Minion 1 §7from Dark Auction"));
+ manager.getMinionById("SNOW_GENERATOR_1").getRequirements().add(new CustomRequirement(
+ "Get a §cSnow Minion 1 §7from opening gifts"));
+
+ }
+
+ private void loadNpcData() {
+ TreeMap<String, JsonObject> itemInformation = NotEnoughUpdates.INSTANCE.manager.getItemInformation();
+ for (Map.Entry<String, JsonObject> entry : itemInformation.entrySet()) {
+ String internalName = entry.getKey();
+ if (!internalName.endsWith("_NPC")) continue;
+ JsonObject jsonObject = entry.getValue();
+ if (!jsonObject.has("recipes")) continue;
+
+ if (!jsonObject.has("displayname")) continue;
+ String npcName = jsonObject.get("displayname").getAsString();
+ npcName = StringUtils.cleanColour(npcName);
+ if (npcName.contains(" (")) {
+ npcName = npcName.split(" \\(")[0];
+ }
+
+ for (JsonElement element : jsonObject.get("recipes").getAsJsonArray()) {
+ JsonObject object = element.getAsJsonObject();
+ if (!object.has("type")) continue;
+ if (!object.get("type").getAsString().equals("npc_shop")) continue;
+ if (!object.has("result")) continue;
+
+ String result = object.get("result").getAsString();
+ if (!result.contains("_GENERATOR_")) continue;
+ Minion minion = manager.getMinionById(result);
+ if (!object.has("cost")) continue;
+
+ RecipeBuilder builder = new RecipeBuilder(manager);
+
+ for (JsonElement costEntry : object.get("cost").getAsJsonArray()) {
+ String price = costEntry.getAsString();
+ builder.addLine(minion, price);
+ }
+
+ ArrayListMultimap<String, Integer> map = builder.getItems();
+ int coins = 0;
+ if (map.containsKey("SKYBLOCK_COIN")) {
+ coins = map.get("SKYBLOCK_COIN").get(0);
+ map.removeAll("SKYBLOCK_COIN");
+ }
+
+ minion.setMinionSource(new NpcSource(npcName, coins, builder.getItems()));
+ minion.setParent(builder.getParent());
+ }
+ }
+ }
+
+ private void createMinions() {
+ for (Map.Entry<String, JsonElement> entry : Constants.MISC.get("minions").getAsJsonObject().entrySet()) {
+ String internalName = entry.getKey();
+ int maxTier = entry.getValue().getAsInt();
+ for (int i = 0; i < maxTier; i++) {
+ int tier = i + 1;
+ manager.createMinion(internalName + "_" + tier, tier);
+ }
+ }
+ }
+
+ private void testForMissingData() {
+ for (Minion minion : manager.getAllMinions().values()) {
+ if (minion.getMinionSource() == null) {
+ errorWhileLoading = true;
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) {
+ Utils.addChatMessage("§c[NEU] The Minion '" + minion.getInternalName() + " has no source!");
+ }
+ }
+ if (minion.getDisplayName() == null) {
+ errorWhileLoading = true;
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) {
+ Utils.addChatMessage("§c[NEU] The Minion '" + minion.getInternalName() + " has no display name!");
+ }
+ }
+ if (manager.getRequirementsManager().getRequirements(minion).isEmpty()) {
+ errorWhileLoading = true;
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) {
+ Utils.addChatMessage("§c[NEU] The Minion '" + minion.getInternalName() + " has no requirements!");
+ }
+ }
+ if (minion.getTier() > 1 && minion.getParent() == null) {
+ errorWhileLoading = true;
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) {
+ Utils.addChatMessage("§c[NEU] The Minion '" + minion.getInternalName() + " has parent!");
+ }
+ }
+ }
+ }
+
+ public void setDirty() {
+ dirty = true;
+ readyToUse = false;
+ }
+
+ public boolean isReadyToUse() {
+ return readyToUse;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoMinionLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoMinionLoader.java
new file mode 100644
index 00000000..6abc5c56
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/MinionHelperRepoMinionLoader.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.loaders.repo;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.CollectionRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.ReputationRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.SlayerRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CraftingSource;
+import io.github.moulberry.notenoughupdates.util.Utils;
+
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.regex.Pattern;
+
+public class MinionHelperRepoMinionLoader {
+
+ private final MinionHelperRepoLoader repoLoader;
+ private final MinionHelperManager manager;
+
+ public MinionHelperRepoMinionLoader(MinionHelperRepoLoader repoLoader, MinionHelperManager manager) {
+ this.repoLoader = repoLoader;
+ this.manager = manager;
+ }
+
+ void loadMinionData() {
+ TreeMap<String, JsonObject> itemInformation = NotEnoughUpdates.INSTANCE.manager.getItemInformation();
+
+ for (Map.Entry<String, Minion> entry : manager.getAllMinions().entrySet()) {
+ String internalName = entry.getKey();
+ if (!itemInformation.containsKey(internalName)) continue;
+ Minion minion = entry.getValue();
+
+ JsonObject jsonObject = itemInformation.get(internalName);
+ if (jsonObject.has("displayname")) {
+ String displayName = jsonObject.get("displayname").getAsString();
+ displayName = StringUtils.cleanColour(displayName);
+ displayName = StringUtils.removeLastWord(displayName, " ");
+ minion.setDisplayName(displayName);
+ }
+
+ if (jsonObject.has("recipe")) {
+ loadRecipes(minion, jsonObject);
+ }
+
+ loadRequirements(minion, jsonObject);
+ }
+ }
+
+ private void loadRequirements(Minion minion, JsonObject jsonObject) {
+ for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
+ String name = entry.getKey();
+ if (name.endsWith("_req") || name.equals("crafttext")) {
+ String value = entry.getValue().getAsString();
+
+ try {
+ switch (name) {
+ case "reputation_req": {
+ String[] split = value.split(":");
+ String reputationType = split[0];
+ int reputation = Integer.parseInt(split[1]);
+ minion.getRequirements().add(new ReputationRequirement(reputationType, reputation));
+ break;
+ }
+ case "crafttext": {
+ if (minion.getTier() != 1) break;
+ if (value.isEmpty()) break;
+
+ String rawCollection = value.split(Pattern.quote(": "))[1];
+ String cleanCollection = StringUtils.removeLastWord(rawCollection, " ");
+ String rawTier = rawCollection.substring(cleanCollection.length() + 1);
+ int tier = Utils.parseRomanNumeral(rawTier);
+ minion.getRequirements().add(new CollectionRequirement(cleanCollection, tier));
+ break;
+ }
+ case "slayer_req": {
+ String[] split = value.split("_");
+ String slayerType = split[0].toLowerCase();
+ int tier = Integer.parseInt(split[1]);
+ minion.getRequirements().add(new SlayerRequirement(slayerType, tier));
+ break;
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
+ repoLoader.errorWhileLoading = true;
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) {
+ Utils.addChatMessage(
+ "§c[NEU] Error in MinionHelperRepoLoader while loading repo entry " + minion.getDisplayName() + " " +
+ minion.getTier() + ": " +
+ e.getClass().getSimpleName() + ": " + e.getMessage());
+ }
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void loadRecipes(Minion minion, JsonObject jsonObject) {
+ JsonObject recipes = jsonObject.get("recipe").getAsJsonObject();
+ RecipeBuilder builder = new RecipeBuilder(manager);
+ for (Map.Entry<String, JsonElement> entry : recipes.entrySet()) {
+ String rawString = entry.getValue().getAsString();
+
+ builder.addLine(minion, rawString);
+ }
+
+ minion.setMinionSource(new CraftingSource(builder.getItems()));
+ minion.setParent(builder.getParent());
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/RecipeBuilder.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/RecipeBuilder.java
new file mode 100644
index 00000000..e7738954
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/repo/RecipeBuilder.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.miscgui.minionhelper.loaders.repo;
+
+import com.google.common.collect.ArrayListMultimap;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
+import io.github.moulberry.notenoughupdates.util.Utils;
+
+public class RecipeBuilder {
+ private final MinionHelperManager manager;
+ private Minion parent = null;
+ private final ArrayListMultimap<String, Integer> items = ArrayListMultimap.create();
+
+ public RecipeBuilder(MinionHelperManager manager) {
+ this.manager = manager;
+ }
+
+ public Minion getParent() {
+ return parent;
+ }
+
+ public ArrayListMultimap<String, Integer> getItems() {
+ return items;
+ }
+
+ public void addLine(Minion minion, String rawString) {
+ String[] split = rawString.split(":");
+ String itemName = split[0];
+
+ boolean isParent = false;
+ if (itemName.contains("_GENERATOR_")) {
+ String minionInternalName = minion.getInternalName();
+ boolean same = StringUtils.removeLastWord(itemName, "_").equals(StringUtils.removeLastWord(
+ minionInternalName,
+ "_"
+ ));
+ if (same) {
+ Minion recipeMinion = manager.getMinionById(itemName);
+ if (recipeMinion.getTier() == minion.getTier() - 1) {
+ parent = recipeMinion;
+ if (parent == null) {
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) {
+ Utils.addChatMessage("Parent is null for minion " + minionInternalName);
+ }
+ }
+ isParent = true;
+ }
+ }
+ }
+ if (!isParent) {
+ int amount = Integer.parseInt(split[1]);
+ items.put(itemName, amount);
+ }
+ }
+}
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
new file mode 100644
index 00000000..6219cf2c
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlay.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.render;
+
+import com.google.common.collect.Lists;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.ArrowPagesUtils;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay;
+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.mixins.AccessorGuiContainer;
+import io.github.moulberry.notenoughupdates.util.ItemUtils;
+import io.github.moulberry.notenoughupdates.util.NotificationHandler;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.RenderHelper;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.lwjgl.input.Mouse;
+import org.lwjgl.opengl.GL11;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class MinionHelperOverlay {
+
+ private final ResourceLocation minionOverlayImage = new ResourceLocation("notenoughupdates:minion_overlay.png");
+ private final ResourceLocation greenCheckImage = new ResourceLocation("notenoughupdates:dungeon_map/green_check.png");
+ private final ResourceLocation whiteCheckImage = new ResourceLocation("notenoughupdates:dungeon_map/white_check.png");
+
+ private final MinionHelperManager manager;
+ private final MinionHelperOverlayHover hover;
+ private int[] topLeft = new int[]{237, 110};
+
+ private LinkedHashMap<String, OverviewLine> cacheRenderMap = null;
+ private int cacheTotalPages = -1;
+
+ private boolean filterEnabled = true;
+ private boolean useInstantBuyPrice = true;
+
+ private int maxPerPage = 8;
+ private int currentPage = 0;
+
+ public MinionHelperOverlay(MinionHelperManager manager) {
+ this.manager = manager;
+ hover = new MinionHelperOverlayHover(this, manager);
+ }
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ resetCache();
+ }
+
+ public void resetCache() {
+ cacheRenderMap = null;
+ cacheTotalPages = -1;
+ }
+
+ @SubscribeEvent
+ public void onDrawBackground(GuiScreenEvent.BackgroundDrawnEvent event) {
+ if (!manager.inCraftedMinionsInventory()) return;
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return;
+ if (manager.isInvalidApiKey()) {
+ LinkedHashMap<String, OverviewLine> map = new LinkedHashMap<>();
+ map.put("§cInvalid API Key!", new OverviewText(Collections.emptyList(), () -> {}));
+ render(map);
+ return;
+ }
+ if (manager.notReady()) {
+ LinkedHashMap<String, OverviewLine> map = new LinkedHashMap<>();
+ map.put("§cLoading...", new OverviewText(Collections.emptyList(), () -> {}));
+ render(map);
+ return;
+ }
+
+ if (manager.getApi().isNotifyNoCollectionApi()) {
+ NotificationHandler.displayNotification(Lists.newArrayList(
+ "",
+ "§cCollection API is disabled!",
+ "§cMinion Helper will not filter minions that",
+ "§cdo not meet the collection requirements!"
+ ), false, true);
+ manager.getApi().setNotifyNoCollectionApi(false);
+ }
+
+ LinkedHashMap<String, OverviewLine> renderMap = getRenderMap();
+
+ hover.renderHover(renderMap);
+ render(renderMap);
+
+ renderArrows();
+ }
+
+ private void renderArrows() {
+ GuiScreen gui = Minecraft.getMinecraft().currentScreen;
+ if (gui instanceof AccessorGuiContainer) {
+ AccessorGuiContainer container = (AccessorGuiContainer) gui;
+ int guiLeft = container.getGuiLeft();
+ int guiTop = container.getGuiTop();
+ int totalPages = getTotalPages();
+ ArrowPagesUtils.onDraw(guiLeft, guiTop, topLeft, currentPage, totalPages);
+ }
+ }
+
+ @SubscribeEvent
+ public void onMouseClick(GuiScreenEvent.MouseInputEvent.Pre event) {
+ if (!manager.inCraftedMinionsInventory()) return;
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return;
+ if (manager.notReady()) return;
+ if (!Mouse.getEventButtonState()) return;
+
+ OverviewLine overviewLine = getObjectOverMouse(getRenderMap());
+ if (overviewLine != null) {
+ overviewLine.onClick();
+ event.setCanceled(true);
+ }
+
+ int totalPages = getTotalPages();
+ if (event.gui instanceof AccessorGuiContainer) {
+ int guiLeft = ((AccessorGuiContainer) event.gui).getGuiLeft();
+ int guiTop = ((AccessorGuiContainer) event.gui).getGuiTop();
+ if (ArrowPagesUtils.onPageSwitchMouse(guiLeft, guiTop, topLeft, currentPage, totalPages, pageChange -> {
+ currentPage = pageChange;
+ resetCache();
+ })) {
+ event.setCanceled(true);
+ }
+ }
+ checkButtonClick();
+ }
+
+ private void checkButtonClick() {
+ GuiScreen gui = Minecraft.getMinecraft().currentScreen;
+ if (!(gui instanceof GuiChest)) return;
+
+ int xSize = ((AccessorGuiContainer) gui).getXSize();
+ int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft();
+ int guiTop = ((AccessorGuiContainer) gui).getGuiTop();
+
+ final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft());
+ final int scaledWidth = scaledresolution.getScaledWidth();
+ final int scaledHeight = scaledresolution.getScaledHeight();
+ int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth;
+ int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1;
+
+ int x = guiLeft + xSize + 4 + 149 - 3;
+ int y = guiTop + 109 - 3;
+ if (mouseX > x && mouseX < x + 16 &&
+ mouseY > y && mouseY < y + 16) {
+ toggleShowAvailable();
+ }
+
+ x = guiLeft + xSize + 4 + 149 - 3 - 16 - 3;
+ y = guiTop + 109 - 3;
+ if (mouseX > x && mouseX < x + 16 &&
+ mouseY > y && mouseY < y + 16) {
+ toggleUseInstantBuyPrice();
+ }
+ }
+
+ @SubscribeEvent
+ public void onMouseClick(GuiScreenEvent.KeyboardInputEvent.Pre event) {
+ if (!manager.inCraftedMinionsInventory()) return;
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return;
+ if (manager.notReady()) return;
+
+ int totalPages = getTotalPages();
+ if (ArrowPagesUtils.onPageSwitchKey(currentPage, totalPages, pageChange -> {
+ currentPage = pageChange;
+ resetCache();
+ })) {
+ event.setCanceled(true);
+ }
+ }
+
+ private Map<Minion, Double> getMissing() {
+ Map<Minion, Double> prices = new HashMap<>();
+ for (Minion minion : manager.getAllMinions().values()) {
+
+ if (!minion.doesMeetRequirements() && filterEnabled) continue;
+ if (!minion.isCrafted()) {
+ double price = manager.getPriceCalculation().calculateUpgradeCosts(minion, true);
+ prices.put(minion, price);
+ }
+ }
+ return prices;
+ }
+
+ private void render(Map<String, OverviewLine> renderMap) {
+ Minecraft minecraft = Minecraft.getMinecraft();
+ Gui gui = Minecraft.getMinecraft().currentScreen;
+ if (!(gui instanceof GuiChest)) return;
+ int xSize = ((AccessorGuiContainer) gui).getXSize();
+ int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft();
+ int guiTop = ((AccessorGuiContainer) gui).getGuiTop();
+ minecraft.getTextureManager().bindTexture(minionOverlayImage);
+ GL11.glColor4f(1, 1, 1, 1);
+ GlStateManager.disableLighting();
+ Utils.drawTexturedRect(guiLeft + xSize + 4, guiTop, 168, 128, 0, 1f, 0, 1f, GL11.GL_NEAREST);
+
+ if (filterEnabled) {
+ minecraft.getTextureManager().bindTexture(greenCheckImage);
+ } else {
+ minecraft.getTextureManager().bindTexture(whiteCheckImage);
+ }
+ Utils.drawTexturedRect(guiLeft + xSize + 4 + 149, guiTop + 109, 10, 10, 0, 1f, 0, 1f, GL11.GL_NEAREST);
+ GlStateManager.disableLighting();
+
+ RenderHelper.enableGUIStandardItemLighting();
+ ItemStack itemStack;
+ if (useInstantBuyPrice) {
+ itemStack = ItemUtils.getCoinItemStack(10_000_000);
+ } else {
+ itemStack = ItemUtils.getCoinItemStack(100_000);
+ }
+ Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(
+ itemStack,
+ guiLeft + xSize + 4 + 149 - 3 - 16 - 3,
+ guiTop + 109 - 3
+ );
+
+ RenderHelper.disableStandardItemLighting();
+
+ int x = guiLeft + xSize + 10;
+ int i = 0;
+ int y = guiTop + 6;
+ FontRenderer fontRendererObj = minecraft.fontRendererObj;
+ for (Map.Entry<String, OverviewLine> entry : renderMap.entrySet()) {
+ String line = entry.getKey();
+
+ if (line.contains("§6")) {
+ String[] split = line.split("§6");
+ line = split[0];
+ String price = "§6§l" + split[1];
+ 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;
+ } else {
+ y += 10;
+ }
+ }
+ }
+
+ private LinkedHashMap<String, OverviewLine> getRenderMap() {
+ if (cacheRenderMap != null) return cacheRenderMap;
+
+ Map<Minion, Double> prices = getMissing();
+ LinkedHashMap<String, OverviewLine> renderMap = new LinkedHashMap<>();
+
+ addTitle(prices, renderMap);
+ addNeedToNextSlot(prices, renderMap);
+
+ if (!prices.isEmpty()) {
+ addMinions(prices, renderMap);
+ }
+
+ cacheRenderMap = renderMap;
+ return renderMap;
+ }
+
+ private void addNeedToNextSlot(
+ Map<Minion, Double> prices,
+ LinkedHashMap<String, OverviewLine> renderMap
+ ) {
+ int neededForNextSlot = manager.getNeedForNextSlot();
+ String color = "§8";
+ if (neededForNextSlot == -1) {
+ renderMap.put(color + "Next slot: ?", new OverviewText(Collections.emptyList(), () -> {}));
+ return;
+ }
+
+ double priceNeeded = 0;
+ int index = 0;
+ for (Double price : TrophyRewardOverlay.sortByValue(prices).values()) {
+ priceNeeded += price;
+ index++;
+ if (index == neededForNextSlot) break;
+ }
+ String format = manager.getPriceCalculation().formatCoins(priceNeeded);
+ format = format.replace(" coins", "");
+ String text = color + "Next slot: §3" + neededForNextSlot + " minions §8- " + format;
+ renderMap.put(text, new OverviewText(Collections.emptyList(), () -> {}));
+ }
+
+ private void addTitle(Map<Minion, Double> prices, LinkedHashMap<String, OverviewLine> renderMap) {
+ String name = "§8" + prices.size() + " " + (filterEnabled ? "craftable" : "total") + " minions";
+ renderMap.put(name, new OverviewText(Collections.emptyList(), () -> {}));
+ }
+
+ private void addMinions(Map<Minion, Double> prices, LinkedHashMap<String, OverviewLine> renderMap) {
+ int skipPreviousPages = currentPage * maxPerPage;
+ int i = 0;
+ Map<Minion, Double> sort = TrophyRewardOverlay.sortByValue(prices);
+ for (Minion minion : sort.keySet()) {
+ if (i >= skipPreviousPages) {
+ String displayName = minion.getDisplayName();
+ if (displayName == null) {
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dev) {
+ Utils.addChatMessage("§cDisplayname is null for " + minion.getInternalName());
+ }
+ continue;
+ }
+
+ displayName = displayName.replace(" Minion", "");
+ String format = manager.getPriceCalculation().calculateUpgradeCostsFormat(minion, true);
+ format = format.replace(" coins", "");
+ String requirementFormat = minion.doesMeetRequirements() ? "§9" : "§c";
+ renderMap.put(
+ requirementFormat + displayName + " " + minion.getTier() + " §8- " + format,
+ minion
+ );
+ }
+
+ i++;
+ if (i == ((currentPage + 1) * maxPerPage)) break;
+ }
+ }
+
+ private int getTotalPages() {
+ if (cacheTotalPages != -1) return cacheTotalPages;
+
+ Map<Minion, Double> prices = getMissing();
+ int totalPages = (int) ((double) prices.size() / maxPerPage);
+ if (prices.size() % maxPerPage != 0) {
+ totalPages++;
+ }
+
+ cacheTotalPages = totalPages;
+ return totalPages;
+ }
+
+ private void toggleShowAvailable() {
+ filterEnabled = !filterEnabled;
+ currentPage = 0;
+ resetCache();
+ }
+
+ private void toggleUseInstantBuyPrice() {
+ useInstantBuyPrice = !useInstantBuyPrice;
+ currentPage = 0;
+ resetCache();
+ manager.getPriceCalculation().resetCache();
+ }
+
+ OverviewLine getObjectOverMouse(LinkedHashMap<String, OverviewLine> renderMap) {
+ GuiScreen gui = Minecraft.getMinecraft().currentScreen;
+ if (!(gui instanceof GuiChest)) return null;
+
+ int xSize = ((AccessorGuiContainer) gui).getXSize();
+ int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft();
+ int guiTop = ((AccessorGuiContainer) gui).getGuiTop();
+
+ int x = guiLeft + xSize + 9;
+ int y = guiTop + 5;
+
+ final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft());
+ final int scaledWidth = scaledresolution.getScaledWidth();
+ final int scaledHeight = scaledresolution.getScaledHeight();
+ int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth;
+ int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1;
+
+ int i = 0;
+ FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
+ for (Map.Entry<String, OverviewLine> entry : renderMap.entrySet()) {
+ String text = entry.getKey();
+ int width = fontRenderer.getStringWidth(StringUtils.cleanColour(text));
+ if (mouseX > x && mouseX < x + width + 4 &&
+ mouseY > y && mouseY < y + 11) {
+ return entry.getValue();
+ }
+ i++;
+ if (i == 2) {
+ y += 15;
+ } else {
+ y += 10;
+ }
+ }
+
+ return null;
+ }
+
+ public void onProfileSwitch() {
+ currentPage = 0;
+ filterEnabled = true;
+ useInstantBuyPrice = true;
+ }
+
+ public void setMaxPerPage(int maxPerPage) {
+ this.maxPerPage = maxPerPage;
+ }
+
+ public void setTopLeft(int[] topLeft) {
+ this.topLeft = topLeft;
+ }
+
+ public boolean isFilterEnabled() {
+ return filterEnabled;
+ }
+
+ public boolean isUseInstantBuyPrice() {
+ return useInstantBuyPrice;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java
new file mode 100644
index 00000000..fcafa534
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperOverlayHover.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.render;
+
+import com.google.common.collect.ArrayListMultimap;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.ApiData;
+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.requirements.CollectionRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.MinionRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.ReputationRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CraftingSource;
+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.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.gui.inventory.GuiChest;
+import org.lwjgl.input.Mouse;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MinionHelperOverlayHover {
+
+ private final MinionHelperOverlay overlay;
+ private final MinionHelperManager manager;
+
+ public MinionHelperOverlayHover(MinionHelperOverlay overlay, MinionHelperManager manager) {
+ this.overlay = overlay;
+ this.manager = manager;
+ }
+
+ void renderHover(LinkedHashMap<String, OverviewLine> renderMap) {
+ if (!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) return;
+
+ final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft());
+ final int scaledWidth = scaledresolution.getScaledWidth();
+ final int scaledHeight = scaledresolution.getScaledHeight();
+ int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth;
+ int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1;
+
+ OverviewLine mouseObject = overlay.getObjectOverMouse(renderMap);
+ if (mouseObject != null) {
+ Utils.drawHoveringText(getTooltip(mouseObject), mouseX, mouseY,
+ scaledWidth, scaledHeight, -1, Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+
+ renderButtons();
+ }
+
+ private void renderButtons() {
+ GuiScreen gui = Minecraft.getMinecraft().currentScreen;
+ if (!(gui instanceof GuiChest)) return;
+
+ int xSize = ((AccessorGuiContainer) gui).getXSize();
+ int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft();
+ int guiTop = ((AccessorGuiContainer) gui).getGuiTop();
+
+ final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft());
+ final int scaledWidth = scaledresolution.getScaledWidth();
+ final int scaledHeight = scaledresolution.getScaledHeight();
+ int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth;
+ int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1;
+
+
+ int x = guiLeft + xSize + 4 + 149 - 3;
+ int y = guiTop + 109 - 3;
+ if (mouseX > x && mouseX < x + 16 &&
+ mouseY > y && mouseY < y + 16) {
+ renderFilterButton(scaledWidth, scaledHeight, mouseX, mouseY);
+ }
+
+ x = guiLeft + xSize + 4 + 149 - 3 - 16 - 3;
+ y = guiTop + 109 - 3;
+ if (mouseX > x && mouseX < x + 16 &&
+ mouseY > y && mouseY < y + 16) {
+ renderBuyPriceButton(scaledWidth, scaledHeight, mouseX, mouseY);
+ }
+ }
+
+ private void renderFilterButton(int scaledWidth, int scaledHeight, int mouseX, int mouseY) {
+ List<String> list = new ArrayList<>();
+
+ if (overlay.isFilterEnabled()) {
+ list.add("§aFilter enabled");
+ list.add("§7Only show minions that can be");
+ list.add("§7crafted and meet requirements.");
+ } else {
+ list.add("§cFilter disabled");
+ list.add("§7Show all minions. §cRed ones §7have");
+ list.add("§7missing requirements.");
+ }
+
+ list.add("");
+ list.add("§eClick to toggle!");
+
+ Utils.drawHoveringText(list, mouseX, mouseY, scaledWidth, scaledHeight, -1,
+ Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+
+ private void renderBuyPriceButton(int scaledWidth, int scaledHeight, int mouseX, int mouseY) {
+ List<String> list = new ArrayList<>();
+
+ if (overlay.isUseInstantBuyPrice()) {
+ list.add("§bUse Instant Buy price");
+ list.add("§7Use the price to pay when");
+ list.add("§7buying the item right now.");
+ list.add("§7This will be more expensive!");
+ } else {
+ list.add("§6Use Buy Offer price");
+ list.add("§7Use the price for creating an");
+ list.add("§7offer to buy the item cheaper.");
+ list.add("§7This can take longer!");
+ }
+
+ list.add("");
+ list.add("§eClick to toggle!");
+
+ Utils.drawHoveringText(list, mouseX, mouseY, scaledWidth, scaledHeight, -1,
+ Minecraft.getMinecraft().fontRendererObj
+ );
+ }
+
+ private List<String> getTooltip(OverviewLine overviewLine) {
+ List<String> lines = new ArrayList<>();
+
+ if (overviewLine instanceof OverviewText) {
+ OverviewText overviewText = (OverviewText) overviewLine;
+ lines.addAll(overviewText.getLines());
+ } else if (overviewLine instanceof Minion) {
+
+ Minion minion = (Minion) overviewLine;
+ MinionSource minionSource = minion.getMinionSource();
+ if (minion.getCustomSource() != null) {
+ minionSource = minion.getCustomSource();
+ }
+ String displayName = minion.getDisplayName();
+ lines.add("§9" + displayName + " " + minion.getTier());
+ List<MinionRequirement> requirements = manager.getRequirementsManager().getRequirements(minion);
+ if (!requirements.isEmpty()) {
+ for (MinionRequirement requirement : requirements) {
+ String result = getRequirementDescription(minion, requirement);
+ if (result == null) continue;
+ lines.add(result);
+ }
+ } else {
+ lines.add("§cNo requirements loaded!");
+ }
+
+ if (minionSource instanceof CraftingSource) {
+ CraftingSource craftingSource = (CraftingSource) minionSource;
+ lines.add("");
+ String format = manager.getPriceCalculation().calculateUpgradeCostsFormat(minion, true);
+ if (minion.getTier() == 1) {
+ lines.add("§7Full crafting cost: " + format);
+ } else {
+ lines.add("§7Upgrade cost: " + format);
+ }
+ formatItems(lines, grabAllItems(craftingSource.getItems()));
+
+ } else if (minionSource instanceof NpcSource) {
+ NpcSource npcSource = (NpcSource) minionSource;
+ String npcName = npcSource.getNpcName();
+ lines.add("");
+ lines.add("§7Buy from: §9" + npcName + " (NPC)");
+ lines.add("");
+ lines.add("§7Cost: " + manager.getPriceCalculation().calculateUpgradeCostsFormat(minion, true));
+ int coins = npcSource.getCoins();
+ if (coins != 0) {
+ lines.add(" §8- " + manager.getPriceCalculation().formatCoins(coins));
+ }
+ formatItems(lines, grabAllItems(npcSource.getItems()));
+ }
+
+ lines.add("");
+ lines.add("§eClick to view recipe!");
+ }
+ return lines;
+ }
+
+ private String getRequirementDescription(Minion minion, MinionRequirement requirement) {
+ boolean meetRequirement = manager.getRequirementsManager().meetRequirement(minion, requirement);
+ String color = meetRequirement ? "§a" : "§c";
+
+ String description = requirement.printDescription(color);
+ if (requirement instanceof CollectionRequirement && manager.getApi().isCollectionApiDisabled()) {
+ description += " §cAPI DISABLED! §7";
+ }
+
+ if (!meetRequirement) {
+ if (requirement instanceof ReputationRequirement) {
+ ReputationRequirement reputationRequirement = (ReputationRequirement) requirement;
+ String reputationType = reputationRequirement.getReputationType();
+ ApiData apiData = manager.getApi().getApiData();
+ int having;
+ if (reputationType.equals("BARBARIAN")) {
+ having = apiData.getBarbariansReputation();
+ } else if (reputationType.equals("MAGE")) {
+ having = apiData.getMagesReputation();
+ } else {
+ Utils.addChatMessage("§c[NEU] Minion Helper: Unknown reputation type: '" + reputationType + "'");
+ return null;
+ }
+ int need = reputationRequirement.getReputation();
+ if (having < 0) having = 0;
+
+ String reputationName = StringUtils.firstUpperLetter(reputationType.toLowerCase());
+ String havingFormat = Utils.formatNumberWithDots(having);
+ String needFormat = Utils.formatNumberWithDots(need);
+ description = "Reputation: §c" + havingFormat + "§8/§c" + needFormat + " §7" + reputationName + " Reputation";
+ }
+ }
+
+ return " §8- §7" + description;
+ }
+
+ private void formatItems(List<String> lines, Map<String, Integer> allItems) {
+ for (Map.Entry<String, Integer> entry : allItems.entrySet()) {
+ String internalName = entry.getKey();
+ int amount = entry.getValue();
+ if (internalName.equals("SKYBLOCK_PELT")) {
+ int peltCount = manager.getApi().getApiData().getPeltCount();
+
+ lines.add(" §8- §5" + peltCount + "§8/§5" + amount + " Pelts");
+ continue;
+ }
+
+ String name = NotEnoughUpdates.INSTANCE.manager.getDisplayName(internalName);
+ double price = manager.getPriceCalculation().getPrice(internalName);
+ String priceFormat = manager.getPriceCalculation().formatCoins(price * amount);
+ lines.add(" §8- §a" + amount + "§7x §f" + name + " " + priceFormat);
+ }
+ }
+
+ private Map<String, Integer> grabAllItems(ArrayListMultimap<String, Integer> multimap) {
+ Map<String, Integer> allItems = new HashMap<>();
+ for (Map.Entry<String, Integer> entry : multimap.entries()) {
+ String name = entry.getKey();
+ int amount = entry.getValue();
+ amount = allItems.getOrDefault(name, 0) + amount;
+ allItems.put(name, amount);
+ }
+ return allItems;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperTooltips.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperTooltips.java
new file mode 100644
index 00000000..ef243a6f
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/MinionHelperTooltips.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.render;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource;
+import io.github.moulberry.notenoughupdates.util.ItemUtils;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.event.entity.player.ItemTooltipEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.lwjgl.input.Keyboard;
+
+import java.util.List;
+
+public class MinionHelperTooltips {
+ private final MinionHelperManager manager;
+ private boolean pressedShiftLast = false;
+ private boolean showFullCost = false;
+
+ public MinionHelperTooltips(MinionHelperManager manager) {
+ this.manager = manager;
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOW)
+ public void onItemTooltip(ItemTooltipEvent event) {
+ if (!manager.inCraftedMinionsInventory()) return;
+ if (!NotEnoughUpdates.INSTANCE.config.minionHelper.tooltip) return;
+ if (manager.notReady()) return;
+
+ boolean shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT);
+ if (!pressedShiftLast && shift) {
+ showFullCost = !showFullCost;
+ }
+ pressedShiftLast = shift;
+
+ ItemStack itemStack = event.itemStack;
+ if (itemStack == null) return;
+ String displayName = itemStack.getDisplayName();
+ if (!displayName.endsWith(" Minion")) return;
+ displayName = StringUtils.cleanColour(displayName);
+
+ List<String> lore = ItemUtils.getLore(itemStack);
+ if (lore.get(0).equals("§7You haven't crafted this minion.")) return;
+
+ int index = 0;
+ for (String line : lore) {
+ index++;
+ if (!line.contains("Tier")) continue;
+
+ Minion minion = manager.getMinionByName(displayName, index);
+ if (minion == null) {
+ System.err.println("minion is null for displayName '" + displayName + "' and tier " + index);
+ continue;
+ }
+ MinionSource minionSource = minion.getMinionSource();
+ if (minionSource == null) {
+ System.err.println("minionSource is null for " + minion.getInternalName());
+ continue;
+ }
+ String format = manager.getPriceCalculation().calculateUpgradeCostsFormat(minion, !showFullCost);
+ event.toolTip.set(index, line + " §8- " + format);
+ }
+
+ if (showFullCost) {
+ event.toolTip.add("§8[Press SHIFT to show upgrade cost]");
+ } else {
+ event.toolTip.add("§8[Press SHIFT to show full cost]");
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/NeuConfigTutorial.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewLine.java
index 6a2602f8..85d682b3 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/NeuConfigTutorial.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewLine.java
@@ -17,10 +17,9 @@
* along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
*/
-package io.github.moulberry.notenoughupdates.miscgui.tutorials;
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables;
-public class NeuConfigTutorial extends TutorialBase {
- static {
- title = "NEU Config Tutorial";
- }
+public abstract class OverviewLine {
+
+ public abstract void onClick();
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewText.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewText.java
new file mode 100644
index 00000000..499ca758
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/render/renderables/OverviewText.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.render.renderables;
+
+import java.util.List;
+
+public class OverviewText extends OverviewLine {
+
+ private final Runnable clickRunnable;
+ private final List<String> lines;
+
+ public OverviewText(List<String> line, Runnable clickRunnable) {
+ this.lines = line;
+ this.clickRunnable = clickRunnable;
+ }
+
+ public List<String> getLines() {
+ return lines;
+ }
+
+ @Override
+ public void onClick() {
+ clickRunnable.run();
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CollectionRequirement.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CollectionRequirement.java
new file mode 100644
index 00000000..c01386e1
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CollectionRequirement.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements;
+
+public class CollectionRequirement extends MinionRequirement {
+
+ private final String collection;
+ private final int level;
+
+ public CollectionRequirement(String collection, int level) {
+ this.collection = collection;
+ this.level = level;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public String getCollection() {
+ return collection;
+ }
+
+ @Override
+ public String printDescription(String color) {
+ return "Collection: " + color + collection + " level " + level;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/ButtonsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CustomRequirement.java
index 55113462..93174f03 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/ButtonsCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/CustomRequirement.java
@@ -17,19 +17,17 @@
* along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
*/
-package io.github.moulberry.notenoughupdates.commands.misc;
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements;
-import io.github.moulberry.notenoughupdates.commands.ClientCommandBase;
-import net.minecraft.command.CommandException;
-import net.minecraft.command.ICommandSender;
+public class CustomRequirement extends MinionRequirement {
-public class ButtonsCommand extends ClientCommandBase {
- protected ButtonsCommand(String name) {
- super(name);
- }
+ private final String text;
+ public CustomRequirement(String text) {
+ this.text = text;
+ }
@Override
- public void processCommand(ICommandSender sender, String[] args) throws CommandException {
-
+ public String printDescription(String color) {
+ return text;
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/MinionRequirement.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/MinionRequirement.java
new file mode 100644
index 00000000..9dd3fe09
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/MinionRequirement.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements;
+
+public abstract class MinionRequirement {
+ public abstract String printDescription(String color);
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/ReputationRequirement.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/ReputationRequirement.java
new file mode 100644
index 00000000..70d1e5fc
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/ReputationRequirement.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements;
+
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.util.Utils;
+
+public class ReputationRequirement extends MinionRequirement {
+
+ private final String reputationType;
+ private final int reputation;
+ private final String description;
+
+ public ReputationRequirement(String reputationType, int reputation) {
+ this.reputationType = reputationType;
+ this.reputation = reputation;
+
+ String reputationName = StringUtils.firstUpperLetter(reputationType.toLowerCase());
+ description = Utils.formatNumberWithDots(reputation) + " §7" + reputationName + " Reputation";
+ }
+
+ public int getReputation() {
+ return reputation;
+ }
+
+ public String getReputationType() {
+ return reputationType;
+ }
+
+ @Override
+ public String printDescription(String color) {
+ return "Reputation: " + color + description;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/SlayerRequirement.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/SlayerRequirement.java
new file mode 100644
index 00000000..78c588b1
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/requirements/SlayerRequirement.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements;
+
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+
+public class SlayerRequirement extends MinionRequirement {
+
+ private final String slayer;
+ private final int level;
+
+ public SlayerRequirement(String slayer, int level) {
+ this.slayer = slayer;
+ this.level = level;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public String getSlayer() {
+ return slayer;
+ }
+
+ @Override
+ public String printDescription(String color) {
+ return "Slayer: " + color +StringUtils.firstUpperLetter(slayer)+ " level " + level;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CraftingSource.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CraftingSource.java
new file mode 100644
index 00000000..eca689d1
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CraftingSource.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources;
+
+import com.google.common.collect.ArrayListMultimap;
+
+public class CraftingSource extends MinionSource {
+ //name -> amount
+ private final ArrayListMultimap<String, Integer> items;
+
+ public CraftingSource(ArrayListMultimap<String, Integer> items) {
+ this.items = items;
+ }
+
+ public ArrayListMultimap<String, Integer> getItems() {
+ return items;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CustomSource.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CustomSource.java
new file mode 100644
index 00000000..cf260a88
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/CustomSource.java
@@ -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.miscgui.minionhelper.sources;
+
+public class CustomSource extends MinionSource {
+
+ private final String sourceName;
+
+ public CustomSource(String sourceName) {
+ this.sourceName = sourceName;
+ }
+
+ public String getSourceName() {
+ return sourceName;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/MinionSource.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/MinionSource.java
new file mode 100644
index 00000000..f54f0845
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/MinionSource.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources;
+
+public abstract class MinionSource {
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/NpcSource.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/NpcSource.java
new file mode 100644
index 00000000..941890fa
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/sources/NpcSource.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources;
+
+import com.google.common.collect.ArrayListMultimap;
+
+public class NpcSource extends MinionSource {
+ private final String npcName;
+ // name -> amount
+ private final ArrayListMultimap<String, Integer> items;
+ private final int coins;
+
+ public NpcSource(String npcName, int coins, ArrayListMultimap<String, Integer> items) {
+ this.npcName = npcName;
+ this.coins = coins;
+ this.items = items;
+ }
+
+ public String getNpcName() {
+ return npcName;
+ }
+
+ public ArrayListMultimap<String, Integer> getItems() {
+ return items;
+ }
+
+ public int getCoins() {
+ return coins;
+ }
+}
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
new file mode 100644
index 00000000..8f75b32c
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperPriceCalculation.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.util;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.CraftingSource;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.MinionSource;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.sources.NpcSource;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MinionHelperPriceCalculation {
+
+ private final MinionHelperManager manager;
+ private final Map<String, String> upgradeCostFormatCache = new HashMap<>();
+ private final Map<String, String> fullCostFormatCache = new HashMap<>();
+
+ public MinionHelperPriceCalculation(MinionHelperManager manager) {
+ this.manager = manager;
+ }
+
+ @SubscribeEvent
+ public void onGuiOpen(GuiOpenEvent event) {
+ resetCache();
+ }
+
+ public void resetCache() {
+ upgradeCostFormatCache.clear();
+ fullCostFormatCache.clear();
+ }
+
+ public String calculateUpgradeCostsFormat(Minion minion, boolean upgradeOnly) {
+ MinionSource source = minion.getMinionSource();
+
+ if (source == null) return "§c?";
+ String internalName = minion.getInternalName();
+ if (upgradeOnly) {
+ if (upgradeCostFormatCache.containsKey(internalName)) {
+ return upgradeCostFormatCache.get(internalName);
+ }
+ } else {
+ if (fullCostFormatCache.containsKey(internalName)) {
+ return fullCostFormatCache.get(internalName);
+ }
+ }
+
+ if (upgradeOnly) {
+ if (minion.getCustomSource() != null) {
+ return (minion.getCustomSource()).getSourceName();
+ }
+ }
+
+ double costs = calculateUpgradeCosts(minion, upgradeOnly);
+ String result = formatCoins(costs, !upgradeOnly ? "§o" : "");
+
+ if (source instanceof NpcSource) {
+ ArrayListMultimap<String, Integer> items = ((NpcSource) source).getItems();
+ if (items.containsKey("SKYBLOCK_PELT")) {
+ int amount = items.get("SKYBLOCK_PELT").get(0);
+ result += " §7+ §5" + amount + " Pelts";
+ }
+ }
+
+ if (upgradeOnly) {
+ upgradeCostFormatCache.put(internalName, result);
+ } else {
+ fullCostFormatCache.put(internalName, result);
+ }
+
+ return result;
+ }
+
+ public double calculateUpgradeCosts(Minion minion, boolean upgradeOnly) {
+ MinionSource source = minion.getMinionSource();
+
+ if (upgradeOnly) {
+ if (minion.getCustomSource() != null) {
+ return 0;
+ }
+ }
+
+ if (source instanceof CraftingSource) {
+ CraftingSource craftingSource = (CraftingSource) source;
+ return getCosts(minion, upgradeOnly, craftingSource.getItems());
+
+ } else if (source instanceof NpcSource) {
+ NpcSource npcSource = (NpcSource) source;
+ double upgradeCost = getCosts(minion, upgradeOnly, npcSource.getItems());
+ long coins = npcSource.getCoins();
+ upgradeCost += coins;
+
+ return upgradeCost;
+ }
+
+ return 0;
+ }
+
+ private double getCosts(Minion minion, boolean upgradeOnly, ArrayListMultimap<String, Integer> items) {
+ double upgradeCost = 0;
+ for (Map.Entry<String, Integer> entry : items.entries()) {
+ String internalName = entry.getKey();
+ if (internalName.equals("SKYBLOCK_PELT")) continue;
+ double price = getPrice(internalName);
+ int amount = entry.getValue();
+ upgradeCost += price * amount;
+ }
+ if (!upgradeOnly) {
+ Minion parent = minion.getParent();
+ if (parent != null) {
+ upgradeCost += calculateUpgradeCosts(parent, false);
+ }
+ }
+ return upgradeCost;
+ }
+
+ public double getPrice(String internalName) {
+ //Is minion
+ if (internalName.contains("_GENERATOR_")) {
+ return calculateUpgradeCosts(manager.getMinionById(internalName), false);
+ }
+
+ //Is bazaar item
+ JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalName);
+ if (bazaarInfo != null) {
+ String bazaarMode;
+ if (manager.getOverlay().isUseInstantBuyPrice()) {
+ bazaarMode = "curr_buy";
+ } else {
+ bazaarMode = "curr_sell";
+ }
+ if (!bazaarInfo.has(bazaarMode)) {
+
+ // Use buy order price when no sell offer exist. (e.g. inferno apex)
+ if (bazaarMode.equals("curr_buy")) {
+ bazaarMode = "curr_sell";
+ if (!bazaarInfo.has(bazaarMode)) {
+ System.err.println(bazaarMode + " does not exist for '" + internalName + "'");
+ return 0;
+ }
+ } else {
+ System.err.println(bazaarMode + " does not exist for '" + internalName + "'");
+ return 0;
+ }
+ }
+ return bazaarInfo.get(bazaarMode).getAsDouble();
+ }
+
+ //is ah bin
+ double avgBinPrice = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAvgBin(internalName);
+ if (avgBinPrice >= 1) return avgBinPrice;
+
+ //is ah without bin
+ JsonObject auctionInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalName);
+ if (auctionInfo == null) {
+ //only wood axe and similar useless items
+ return 1;
+ }
+ return (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat());
+ }
+
+ public String formatCoins(double coins) {
+ return formatCoins(coins, "");
+ }
+
+ public String formatCoins(double coins, String extraFormat) {
+ int i = coins < 3 ? 1 : 0;
+ String format = Utils.shortNumberFormat(coins, i);
+ return "§6" + extraFormat + format + " coins";
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperRequirementsManager.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperRequirementsManager.java
new file mode 100644
index 00000000..4a1b96b5
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/util/MinionHelperRequirementsManager.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscgui.minionhelper.util;
+
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.ApiData;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.Minion;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.CollectionRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.CustomRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.MinionRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.ReputationRequirement;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.requirements.SlayerRequirement;
+import io.github.moulberry.notenoughupdates.util.Utils;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class MinionHelperRequirementsManager {
+
+ private final MinionHelperManager manager;
+
+ public MinionHelperRequirementsManager(MinionHelperManager manager) {
+ this.manager = manager;
+ }
+
+ public List<MinionRequirement> getRequirements(Minion minion) {
+ if (!minion.getRequirements().isEmpty()) {
+ return minion.getRequirements();
+ }
+
+ Minion parent = minion.getParent();
+ if (parent != null) {
+ return getRequirements(parent);
+ }
+
+ return Collections.emptyList();
+ }
+
+ public boolean meetAllRequirements(Minion minion) {
+ List<MinionRequirement> list = getRequirements(minion);
+ for (MinionRequirement requirement : list) {
+ if (!meetRequirement(minion, requirement)) {
+ return false;
+ }
+ }
+
+ Minion parent = minion.getParent();
+ if (parent != null) {
+ return meetAllRequirements(parent);
+ }
+
+ return true;
+ }
+
+ public boolean meetRequirement(Minion minion, MinionRequirement requirement) {
+ ApiData apiData = manager.getApi().getApiData();
+ if (apiData == null) return false;
+
+ if (requirement instanceof CollectionRequirement) {
+ if (apiData.isCollectionApiDisabled()) return true;
+
+ CollectionRequirement collectionRequirement = (CollectionRequirement) requirement;
+ String collection = collectionRequirement.getCollection();
+ String internalName = manager.formatInternalName(collection);
+
+ int need = collectionRequirement.getLevel();
+ Map<String, Integer> highestCollectionTier = apiData.getHighestCollectionTier();
+ if (highestCollectionTier.containsKey(internalName)) {
+ int has = highestCollectionTier.get(internalName);
+
+ return has >= need;
+ }
+
+ } else if (requirement instanceof SlayerRequirement) {
+ SlayerRequirement slayerRequirement = (SlayerRequirement) requirement;
+ String slayer = slayerRequirement.getSlayer();
+ //Because the neu-repo uses 'eman' and the hypixel api is using 'enderman'
+ if (slayer.equals("eman")) {
+ slayer = "enderman";
+ }
+ int need = slayerRequirement.getLevel();
+ Map<String, Integer> slayerTiers = apiData.getSlayerTiers();
+ if (slayerTiers.containsKey(slayer)) {
+ return slayerTiers.get(slayer) >= need;
+ }
+
+ } else if (requirement instanceof ReputationRequirement) {
+ ReputationRequirement reputationRequirement = (ReputationRequirement) requirement;
+ int need = reputationRequirement.getReputation();
+ String reputationType = reputationRequirement.getReputationType();
+ if (reputationType.equals("BARBARIAN")) {
+ return apiData.getBarbariansReputation() >= need;
+ } else if (reputationType.equals("MAGE")) {
+ return apiData.getMagesReputation() >= need;
+ } else {
+ Utils.addChatMessage("§c[NEU] Minion Helper: Unknown reputation type: '" + reputationType + "'");
+ return false;
+ }
+ } else if (requirement instanceof CustomRequirement) {
+ return minion.doesMeetRequirements();
+ }
+
+ return false;
+ }
+
+ public void reloadRequirements() {
+ for (Minion minion : manager.getAllMinions().values()) {
+ minion.setMeetRequirements(meetAllRequirements(minion));
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/NeuTutorial.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/NeuTutorial.java
deleted file mode 100644
index c0a5d8c8..00000000
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/NeuTutorial.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2022 NotEnoughUpdates contributors
- *
- * This file is part of NotEnoughUpdates.
- *
- * NotEnoughUpdates is free software: you can redistribute it
- * and/or modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * NotEnoughUpdates is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package io.github.moulberry.notenoughupdates.miscgui.tutorials;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.util.ResourceLocation;
-
-public class NeuTutorial extends TutorialBase {
- static {
- title = "NEU Tutorial";
- }
-
- @Override
- public void setWorldAndResolution(Minecraft mc, int width, int height) {
- super.setWorldAndResolution(mc, width, height);
- screenshots = new ResourceLocation[18];
- for (int i = 0; i <= 17; i++) {
- screenshots[i] = new ResourceLocation("notenoughupdates:ss_small/ss" + (i + 1) + "-0.jpg");
- }
- }
-
- //static {
- // texts[0].put(new Vector2f(0.73f, 0.60f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "Here you will find a list of (most) skyblock items",
- // EnumChatFormatting.GRAY + "The itemlist can be accessed by opening your inventory or most menus while on skyblock"
- // ));
- // texts[1].put(new Vector2f(0.73f, 0.16f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "These are the page controls for the itemlist",
- // EnumChatFormatting.GRAY + "Clicking these controls will bring you to other pages of the itemlist"
- // ));
- // texts[2].put(new Vector2f(0.73f, 1.05f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "These are the sorting controls for the itemlist",
- // EnumChatFormatting.GRAY + "The buttons on the left control the ordering of the items",
- // EnumChatFormatting.GRAY + "The buttons on the right can be used to filter a certain type of item"
- // ));
- // texts[3].put(new Vector2f(0.39f, 1.04f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "This is the search bar for the itemlist",
- // EnumChatFormatting.GRAY + "Double-click the bar to enable inventory search mode",
- // EnumChatFormatting.GRAY + "The button on the left opens up the mod settings",
- // EnumChatFormatting.GRAY + "The button on the right displays this tutorial"
- // ));
- // texts[4].put(new Vector2f(0.39f, 0.99f), Utils.createList(
- // EnumChatFormatting.GOLD + "QuickCommands",
- // EnumChatFormatting.GRAY + "These are the QuickCommands",
- // EnumChatFormatting.GRAY + "They let you warp around or access certain menus more easily"
- // ));
- // texts[5].put(new Vector2f(0.7f, 0.71f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "Hover over an item in the list to display it's lore",
- // EnumChatFormatting.GRAY + "Left clicking some items will display the recipe for that item",
- // EnumChatFormatting.GRAY + "Right clicking some items will display a wiki page for that item",
- // EnumChatFormatting.GRAY + "'F' will favourite an item, putting it to the top of the itemlist"
- // ));
- // texts[6].put(new Vector2f(0.17f, 0.21f), Utils.createList(
- // EnumChatFormatting.GOLD + "Collection Log",
- // EnumChatFormatting.GRAY +
- // "This is the collection log. It can be accessed using the /neucl command, or via the QuickCommand",
- // EnumChatFormatting.GRAY +
- // "The collection log keeps track of all items that enter your inventory while you are playing skyblock",
- // EnumChatFormatting.GRAY + "If you are a completionist, this feature is for you"
- // ));
- // texts[7].put(new Vector2f(0.05f, 0.13f), Utils.createList(
- // EnumChatFormatting.GOLD + "Collection Log",
- // EnumChatFormatting.GRAY + "Clicking on 'Filter' will change the items that",
- // EnumChatFormatting.GRAY + "appear in the list"
- // ));
- // texts[8].put(new Vector2f(0.35f, 0.74f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "This is the NEU Auction House (NeuAH)",
- // EnumChatFormatting.GRAY +
- // "This AH can be accessed from anywhere using the /neuah command, or via the QuickCommand",
- // EnumChatFormatting.GRAY +
- // "The items here refresh automatically, so there is no need to close the GUI to see the latest auctions",
- // EnumChatFormatting.GRAY + "Sometimes, you might have to wait until the list is populated with items from the API"
- // ));
- // texts[9].put(new Vector2f(0.41f, 0.40f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "These tabs control the items that appear in NeuAH",
- // EnumChatFormatting.GRAY +
- // "You can find the main categories on the top of the GUI and subcategories appear on the side of the GUI once a main category is selected"
- // ));
- // texts[10].put(new Vector2f(0.57f, 0.38f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "Search for items using the search bar at the top",
- // EnumChatFormatting.GRAY + "Boolean operators such as &, | or ! work here."
- // ));
- // texts[10].put(new Vector2f(0.40f, 0.72f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "This toolbar contains many useful features",
- // EnumChatFormatting.GRAY + "which control the sorting and ordering of",
- // EnumChatFormatting.GRAY + "the auction house, similar to the normal AH"
- // ));
- // texts[11].put(new Vector2f(0.55f, 0.72f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "Clicking on an item will bring up the auction view",
- // EnumChatFormatting.GRAY + "Here you can viewer the buyer/seller and place bids or make purchases",
- // EnumChatFormatting.GRAY + "Trying to purchase an item will result in a confirmation GUI similar to the normal AH"
- // ));
- // texts[12].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "Access the profile viewer using /neuprofile (ign) or /pv (ign)",
- // EnumChatFormatting.GRAY + "This is the main page of the profile viewer",
- // EnumChatFormatting.GRAY + "This page contains basic information like stats and skill levels"
- // ));
- // texts[12].put(new Vector2f(0.72f, 0.55f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY +
- // "Click the button on the left to switch profiles and use the bar on the right to switch players"
- // ));
- // texts[13].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "This is the extra info page of the profile viewer",
- // EnumChatFormatting.GRAY +
- // "This page contains all the small bits of information about a player that don't fit anywhere else"
- // ));
- // texts[14].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "This is the inventories page of the profile viewer",
- // EnumChatFormatting.GRAY +
- // "Click on the inventory icons in the top-left or use your keyboard to switch the inventory type",
- // EnumChatFormatting.GRAY + "The bar on the bottom-left searches the current inventory for matching items"
- // ));
- // texts[15].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "This is the collections page of the profile viewer",
- // EnumChatFormatting.GRAY + "Click on the icons on the left or use the keyboard shortcut to switch collection type"
- // ));
- // texts[16].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "This is the pets page of the profile viewer",
- // EnumChatFormatting.GRAY + "Click to select the pet on the left",
- // EnumChatFormatting.GRAY + "The selected pet's stats will display on the right"
- // ));
- // texts[17].put(new Vector2f(0.27f, 0.40f), Utils.createList(
- // EnumChatFormatting.GOLD + "Overlay",
- // EnumChatFormatting.GRAY + "Rearrange certain GUI elements of the main overlay using /neuoverlay",
- // EnumChatFormatting.GRAY +
- // "If you accidentally move them off screen, use the button in the top left to reset the GUI"
- // ));
- //}
- //
- //static {
- // buttons = new ArrayList<JsonObject>() {{
- // add(createNewButton(0.27f, 0.40f, new int[]{1, 2}, "TESTSHIT", "neu"));
- // }};
- //}
-}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/TutorialBase.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/TutorialBase.java
deleted file mode 100644
index 27172ed8..00000000
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/tutorials/TutorialBase.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C) 2022 NotEnoughUpdates contributors
- *
- * This file is part of NotEnoughUpdates.
- *
- * NotEnoughUpdates is free software: you can redistribute it
- * and/or modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * NotEnoughUpdates is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package io.github.moulberry.notenoughupdates.miscgui.tutorials;
-
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
-import io.github.moulberry.notenoughupdates.util.Utils;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.GuiScreen;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraft.client.renderer.GlStateManager;
-import net.minecraft.util.EnumChatFormatting;
-import net.minecraft.util.ResourceLocation;
-import net.minecraftforge.client.ClientCommandHandler;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import static io.github.moulberry.notenoughupdates.miscgui.GuiEnchantColour.custom_ench_colour;
-
-public class TutorialBase extends GuiScreen {
- private int guiLeft = 0;
- private int guiTop = 0;
- private int sizeX = 0;
- private int sizeY = 0;
-
- protected static String title;
-
- private int page = 0;
- private final ResourceLocation screenshotBorder = new ResourceLocation("notenoughupdates:ss_border.jpg");
-
- protected ResourceLocation[] screenshots = null;
-
- int scaleFactor = 0;
-
- @Override
- public void setWorldAndResolution(Minecraft mc, int width, int height) {
- super.setWorldAndResolution(mc, width, height);
- }
-
- @Override
- protected void keyTyped(char typedChar, int keyCode) throws IOException {
- super.keyTyped(typedChar, keyCode);
- if (keyCode == Keyboard.KEY_LEFT) {
- page--;
- } else if (keyCode == Keyboard.KEY_RIGHT) {
- page++;
- }
- }
-
- @Override
- public void drawScreen(int mouseX, int mouseY, float partialTicks) {
- super.drawScreen(mouseX, mouseY, partialTicks);
-
- drawDefaultBackground();
-
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- scaleFactor = scaledResolution.getScaleFactor();
-
- sizeX = width / 2 + 40 / scaleFactor;
- sizeY = height / 2 + 40 / scaleFactor;
- guiLeft = width / 4 - 20 / scaleFactor;
- guiTop = height / 4 - 20 / scaleFactor;
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(screenshotBorder);
- Utils.drawTexturedRect(guiLeft, guiTop, sizeX, sizeY);
-
- page = Math.max(0, Math.min(17, page));
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(screenshots[page]);
- Utils.drawTexturedRect(
- guiLeft + 20f / scaleFactor,
- guiTop + 20f / scaleFactor,
- sizeX - 40f / scaleFactor,
- sizeY - 40f / scaleFactor
- );
-
- Utils.drawStringCentered(
- EnumChatFormatting.GOLD + title + " - Page " + (page + 1) + "/" + (texts.size()) + " - Use arrow keys",
- Minecraft.getMinecraft().fontRendererObj,
- width / 2,
- guiTop + 8,
- true,
- 0
- );
- if (scaleFactor != 2)
- Utils.drawStringCentered(
- EnumChatFormatting.GOLD + "Use GUI Scale normal for better reading experience",
- Minecraft.getMinecraft().fontRendererObj,
- width / 2,
- guiTop + 18,
- true,
- 0
- );
- JsonArray pageTexts = texts.get(page);
- for (int i = 0; i < pageTexts.size(); i++) {
- JsonObject textElement = pageTexts.get(i).getAsJsonObject();
- float oldX = textElement.get("x").getAsFloat();
- float oldY = textElement.get("y").getAsFloat();
-
- // List<String> text = entry.getValue();
- JsonArray textArray = textElement.getAsJsonArray("lines");
- List<String> text = new ArrayList<>();
- for (int j = 0; j < textArray.size(); j++) {
- text.add(textArray.get(j).getAsString());
- }
-
- float x = guiLeft + 20f / scaleFactor + (sizeX - 40f / scaleFactor) * oldX;
- float y = guiTop + 20f / scaleFactor + (sizeY - 40f / scaleFactor) * oldY;
-
- Utils.drawHoveringText(
- text,
- (int) x,
- (int) y + 12,
- 100000,
- 100000,
- 200,
- Minecraft.getMinecraft().fontRendererObj
- );
- }
-
- drawButtons();
- }
-
- protected void drawButtons() {
-
- for (JsonObject button : buttons) {
- JsonArray pages = button.get("pages").getAsJsonArray();
- boolean drawButton = false;
- for (int i1 = 0; i1 < pages.size(); i1++) {
- if (pages.get(i1).getAsInt() == page) {
- drawButton = true;
- break;
- }
- }
- if (!drawButton) {
- continue;
- }
- float x = button.get("x").getAsFloat();
- float y = button.get("y").getAsFloat();
- String text = button.get("text").getAsString();
- // String command = button.get("command").getAsString();
- Minecraft.getMinecraft().getTextureManager().bindTexture(custom_ench_colour);
- GlStateManager.color(1, 1, 1, 1);
- Utils.drawTexturedRect(
- guiLeft + 20f / scaleFactor + (sizeX - 40f / scaleFactor) * x,
- guiTop + 20f / scaleFactor + (sizeY - 40f / scaleFactor) * y,
- 88,
- 20,
- 64 / 217f,
- 152 / 217f,
- 48 / 78f,
- 68 / 78f,
- GL11.GL_NEAREST
- );
- Utils.drawStringCenteredScaledMaxWidth(
- text,
- fontRendererObj,
- (guiLeft + 20f / scaleFactor + (sizeX - 40f / scaleFactor) * x) + 44,
- (guiTop + 20f / scaleFactor + (sizeY - 40f / scaleFactor) * y) + 10,
- false,
- 86,
- 4210752
- );
-
- }
- }
-
- @Override
- protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
- super.mouseClicked(mouseX, mouseY, mouseButton);
- int width = 88;
- int height = 20;
-
- for (JsonObject button : buttons) {
- JsonArray pages = button.get("pages").getAsJsonArray();
- boolean drawButton = false;
- for (int i1 = 0; i1 < pages.size(); i1++) {
- if (pages.get(i1).getAsInt() == page) {
- drawButton = true;
- break;
- }
- }
- if (!drawButton) {
- continue;
- }
- float x = button.get("x").getAsFloat();
- float y = button.get("y").getAsFloat();
- // String text = button.get("text").getAsString();
- float realX = guiLeft + 20f / scaleFactor + (sizeX - 40f / scaleFactor) * x;
- float realY = guiTop + 20f / scaleFactor + (sizeY - 40f / scaleFactor) * y;
- if (mouseX > realX && mouseX < realX + width && mouseY > realY && mouseY < realY + height) {
- String command = button.get("command").getAsString();
- NotEnoughUpdates.INSTANCE.openGui = null;
- ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/" + command);
- return;
- }
- }
- }
-
- protected static List<JsonArray> texts = new ArrayList<>();
-
- protected static List<JsonObject> buttons = new ArrayList<>();
-
- protected static JsonObject createNewButton(float x, float y, int[] pages, String text, String command) {
- JsonObject button = new JsonObject();
- JsonArray pagesArray = new JsonArray();
- for (int j : pages) {
- pagesArray.add(new JsonPrimitive(j));
- }
- button.add("pages", pagesArray);
- button.add("x", new JsonPrimitive(x));
- button.add("y", new JsonPrimitive(y));
- button.add("text", new JsonPrimitive(text));
- button.add("command", new JsonPrimitive(command));
- return button;
- }
-
- protected static JsonArray createNewTexts(JsonObject... texts) {
- JsonArray textArray = new JsonArray();
- for (JsonObject text : texts) {
- textArray.add(text);
- }
- return textArray;
- }
-
- protected static JsonObject createNewText(float x, float y, String... texts) {
- JsonObject tooltip = new JsonObject();
- tooltip.add("x", new JsonPrimitive(x));
- tooltip.add("y", new JsonPrimitive(y));
- JsonArray lines = new JsonArray();
- for (String text : texts) {
- lines.add(new JsonPrimitive(text));
- }
- tooltip.add("lines", lines);
- return tooltip;
- }
-
- protected static JsonObject createNewText(float x, float y, List<String> texts) {
- JsonObject tooltip = new JsonObject();
- tooltip.add("x", new JsonPrimitive(x));
- tooltip.add("y", new JsonPrimitive(y));
- JsonArray lines = new JsonArray();
- for (String text : texts) {
- lines.add(new JsonPrimitive(text));
- }
- tooltip.add("lines", lines);
- return tooltip;
- }
-
- //static {
- // for (int i = 0; i < 18; i++) {
- // texts[i] = new HashMap<>();
- // }
- // texts[0].put(new Vector2f(0.73f, 0.60f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "Here you will find a list of (most) skyblock items",
- // EnumChatFormatting.GRAY + "The itemlist can be accessed by opening your inventory or most menus while on skyblock"
- // ));
- // texts[1].put(new Vector2f(0.73f, 0.16f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "These are the page controls for the itemlist",
- // EnumChatFormatting.GRAY + "Clicking these controls will bring you to other pages of the itemlist"
- // ));
- // texts[2].put(new Vector2f(0.73f, 1.05f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "These are the sorting controls for the itemlist",
- // EnumChatFormatting.GRAY + "The buttons on the left control the ordering of the items",
- // EnumChatFormatting.GRAY + "The buttons on the right can be used to filter a certain type of item"
- // ));
- // texts[3].put(new Vector2f(0.39f, 1.04f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "This is the search bar for the itemlist",
- // EnumChatFormatting.GRAY + "Double-click the bar to enable inventory search mode",
- // EnumChatFormatting.GRAY + "The button on the left opens up the mod settings",
- // EnumChatFormatting.GRAY + "The button on the right displays this tutorial"
- // ));
- // texts[4].put(new Vector2f(0.39f, 0.99f), Utils.createList(
- // EnumChatFormatting.GOLD + "QuickCommands",
- // EnumChatFormatting.GRAY + "These are the QuickCommands",
- // EnumChatFormatting.GRAY + "They let you warp around or access certain menus more easily"
- // ));
- // texts[5].put(new Vector2f(0.7f, 0.71f), Utils.createList(
- // EnumChatFormatting.GOLD + "Itemlist",
- // EnumChatFormatting.GRAY + "Hover over an item in the list to display it's lore",
- // EnumChatFormatting.GRAY + "Left clicking some items will display the recipe for that item",
- // EnumChatFormatting.GRAY + "Right clicking some items will display a wiki page for that item",
- // EnumChatFormatting.GRAY + "'F' will favourite an item, putting it to the top of the itemlist"
- // ));
- // texts[6].put(new Vector2f(0.17f, 0.21f), Utils.createList(
- // EnumChatFormatting.GOLD + "Collection Log",
- // EnumChatFormatting.GRAY +
- // "This is the collection log. It can be accessed using the /neucl command, or via the QuickCommand",
- // EnumChatFormatting.GRAY +
- // "The collection log keeps track of all items that enter your inventory while you are playing skyblock",
- // EnumChatFormatting.GRAY + "If you are a completionist, this feature is for you"
- // ));
- // texts[7].put(new Vector2f(0.05f, 0.13f), Utils.createList(
- // EnumChatFormatting.GOLD + "Collection Log",
- // EnumChatFormatting.GRAY + "Clicking on 'Filter' will change the items that",
- // EnumChatFormatting.GRAY + "appear in the list"
- // ));
- // texts[8].put(new Vector2f(0.35f, 0.74f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "This is the NEU Auction House (NeuAH)",
- // EnumChatFormatting.GRAY +
- // "This AH can be accessed from anywhere using the /neuah command, or via the QuickCommand",
- // EnumChatFormatting.GRAY +
- // "The items here refresh automatically, so there is no need to close the GUI to see the latest auctions",
- // EnumChatFormatting.GRAY + "Sometimes, you might have to wait until the list is populated with items from the API"
- // ));
- // texts[9].put(new Vector2f(0.41f, 0.40f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "These tabs control the items that appear in NeuAH",
- // EnumChatFormatting.GRAY +
- // "You can find the main categories on the top of the GUI and subcategories appear on the side of the GUI once a main category is selected"
- // ));
- // texts[10].put(new Vector2f(0.57f, 0.38f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "Search for items using the search bar at the top",
- // EnumChatFormatting.GRAY + "Boolean operators such as &, | or ! work here."
- // ));
- // texts[10].put(new Vector2f(0.40f, 0.72f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "This toolbar contains many useful features",
- // EnumChatFormatting.GRAY + "which control the sorting and ordering of",
- // EnumChatFormatting.GRAY + "the auction house, similar to the normal AH"
- // ));
- // texts[11].put(new Vector2f(0.55f, 0.72f), Utils.createList(
- // EnumChatFormatting.GOLD + "NeuAH",
- // EnumChatFormatting.GRAY + "Clicking on an item will bring up the auction view",
- // EnumChatFormatting.GRAY + "Here you can viewer the buyer/seller and place bids or make purchases",
- // EnumChatFormatting.GRAY + "Trying to purchase an item will result in a confirmation GUI similar to the normal AH"
- // ));
- // texts[12].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "Access the profile viewer using /neuprofile (ign) or /pv (ign)",
- // EnumChatFormatting.GRAY + "This is the main page of the profile viewer",
- // EnumChatFormatting.GRAY + "This page contains basic information like stats and skill levels"
- // ));
- // texts[12].put(new Vector2f(0.72f, 0.55f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY +
- // "Click the button on the left to switch profiles and use the bar on the right to switch players"
- // ));
- // texts[13].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "This is the extra info page of the profile viewer",
- // EnumChatFormatting.GRAY +
- // "This page contains all the small bits of information about a player that don't fit anywhere else"
- // ));
- // texts[14].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "This is the inventories page of the profile viewer",
- // EnumChatFormatting.GRAY +
- // "Click on the inventory icons in the top-left or use your keyboard to switch the inventory type",
- // EnumChatFormatting.GRAY + "The bar on the bottom-left searches the current inventory for matching items"
- // ));
- // texts[15].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "This is the collections page of the profile viewer",
- // EnumChatFormatting.GRAY + "Click on the icons on the left or use the keyboard shortcut to switch collection type"
- // ));
- // texts[16].put(new Vector2f(0.28f, 0.82f), Utils.createList(
- // EnumChatFormatting.GOLD + "Profile Viewer",
- // EnumChatFormatting.GRAY + "This is the pets page of the profile viewer",
- // EnumChatFormatting.GRAY + "Click to select the pet on the left",
- // EnumChatFormatting.GRAY + "The selected pet's stats will display on the right"
- // ));
- // texts[17].put(new Vector2f(0.27f, 0.40f), Utils.createList(
- // EnumChatFormatting.GOLD + "Overlay",
- // EnumChatFormatting.GRAY + "Rearrange certain GUI elements of the main overlay using /neuoverlay",
- // EnumChatFormatting.GRAY +
- // "If you accidentally move them off screen, use the button in the top left to reset the GUI"
- // ));
- //}
-}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java
index 765ed372..581a2c17 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityPlayerSP.java
@@ -21,10 +21,10 @@ package io.github.moulberry.notenoughupdates.mixins;
import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking;
import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.item.EntityItem;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -42,8 +42,7 @@ public class MixinEntityPlayerSP {
int slot = Minecraft.getMinecraft().thePlayer.inventory.currentItem;
if (SlotLocking.getInstance().isSlotIndexLocked(slot) || SlotLocking.getInstance().isSwapedSlotLocked()) {
ci.cancel();
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "NotEnoughUpdates has prevented you from dropping that locked item!"));
+ Utils.addChatMessage(EnumChatFormatting.RED + "NotEnoughUpdates has prevented you from dropping that locked item!");
}
}
}
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 81918939..cb4cfa6c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
@@ -27,6 +27,7 @@ import io.github.moulberry.notenoughupdates.miscfeatures.AbiphoneWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.AuctionBINWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.AuctionSortModeWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.BetterContainers;
+import io.github.moulberry.notenoughupdates.miscfeatures.DungeonNpcProfitOverlay;
import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers;
import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking;
import io.github.moulberry.notenoughupdates.miscgui.GuiCustomEnchant;
@@ -72,6 +73,7 @@ public abstract class MixinGuiContainer extends GuiScreen {
@Inject(method = "drawSlot", at = @At("RETURN"))
public void drawSlotRet(Slot slotIn, CallbackInfo ci) {
SlotLocking.getInstance().drawSlot(slotIn);
+ DungeonNpcProfitOverlay.onDrawSlot(slotIn);
}
@Inject(method = "drawSlot", at = @At("HEAD"), cancellable = true)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiTextField.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiTextField.java
index 55a5a098..039256e5 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiTextField.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiTextField.java
@@ -80,7 +80,7 @@ public abstract class MixinGuiTextField {
}
}
- @Inject(method = "deleteFromCursor", at = @At(value = "INVOKE", target = "Lcom/google/common/base/Predicate;apply(Ljava/lang/Object;)Z"), locals = LocalCapture.PRINT)
+ @Inject(method = "deleteFromCursor", at = @At(value = "INVOKE", target = "Lcom/google/common/base/Predicate;apply(Ljava/lang/Object;)Z", remap = false), locals = LocalCapture.CAPTURE_FAILSOFT)
public void deleteFromCursor_stringStack(int i, CallbackInfo ci, boolean bl, int j, int k, String string) {
if (NotEnoughUpdates.INSTANCE.config.misc.textFieldTweaksEnabled) {
addToStack(string);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
index 8242c095..75ae33a1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
@@ -51,6 +51,7 @@ import io.github.moulberry.notenoughupdates.options.seperateSections.ItemOverlay
import io.github.moulberry.notenoughupdates.options.seperateSections.Itemlist;
import io.github.moulberry.notenoughupdates.options.seperateSections.LocationEdit;
import io.github.moulberry.notenoughupdates.options.seperateSections.Mining;
+import io.github.moulberry.notenoughupdates.options.seperateSections.MinionHelper;
import io.github.moulberry.notenoughupdates.options.seperateSections.Misc;
import io.github.moulberry.notenoughupdates.options.seperateSections.MiscOverlays;
import io.github.moulberry.notenoughupdates.options.seperateSections.NeuAuctionHouse;
@@ -414,6 +415,13 @@ public class NEUConfig extends Config {
@Expose
@Category(
+ name = "Minion Helper",
+ desc = "Minion Helper"
+ )
+ public MinionHelper minionHelper = new MinionHelper();
+
+ @Expose
+ @Category(
name = "Apis",
desc = "Api Data"
)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java
index cf5635ec..9179c6ea 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Dungeons.java
@@ -130,7 +130,7 @@ public class Dungeons {
)
@ConfigEditorBoolean
@ConfigAccordionId(id = 1)
- public boolean shouldWarningDerpy = true;
+ public boolean shouldWarningDerpy = true;
@ConfigOption(
name = "Dungeon Win Overlay",
@@ -168,6 +168,7 @@ public class Dungeons {
@ConfigEditorAccordion(id = 2)
public boolean dungeonBlocksAccordion = false;
+
@ConfigOption(
name = "\u00A7cWarning",
desc = "You need Fast Render and Antialiasing off for these settings to work\n" +
@@ -281,4 +282,38 @@ public class Dungeons {
@ConfigAccordionId(id = 2)
public String dungBatColour = "0:255:12:255:0";
+ @ConfigOption(
+ name = "Croesus Overlay",
+ desc = ""
+ )
+ @ConfigEditorAccordion(id = 4)
+ public boolean croesusAccordion = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Enable Croesus Overlay",
+ desc = "Shows a profit overlay next to your inventory when viewing chest previews at the Croesus NPC"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 4)
+ public boolean croesusProfitOverlay = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Sort by profit",
+ desc = "Lists the chest by profit (descending)"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 4)
+ public boolean croesusSortByProfit = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Highlight highest profit",
+ desc = "Highlight the chest which has the most profit"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 4)
+ public boolean croesusHighlightHighestProfit = true;
+
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MinionHelper.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MinionHelper.java
new file mode 100644
index 00000000..089b2ae7
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/MinionHelper.java
@@ -0,0 +1,45 @@
+/*
+ * 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.options.seperateSections;
+
+import com.google.gson.annotations.Expose;
+import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean;
+import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption;
+
+//TODO jani rename message format
+public class MinionHelper {
+ @Expose
+ @ConfigOption(
+ name = "Enable gui",
+ desc =
+ "Shows a list in the crafted minions inventory of every available to craft or all missing minion, in multiple pages " +
+ "that you need to get the next minion slot, sorted by upgrade cost"
+ )
+
+ @ConfigEditorBoolean
+ public boolean gui = true;
+ @Expose
+ @ConfigOption(
+ name = "Enable tooltip",
+ desc = "Shows the price per minion at the crafted minions "
+ )
+ @ConfigEditorBoolean
+ public boolean tooltip = true;
+}
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 ededb5da..78bb0f95 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
@@ -83,6 +83,15 @@ public class Misc {
@Expose
@ConfigOption(
+ name = "Show Waypoint Distance",
+ desc = "Show the distance to each fairy soul waypoint"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 0)
+ public boolean fairySoulWaypointDistance = false;
+
+ @Expose
+ @ConfigOption(
name = "Mark All As Found",
desc = "Mark all fairy souls in current location as found"
)
@@ -141,14 +150,23 @@ public class Misc {
@ConfigEditorButton(runnableId = 13, buttonText = "Open")
public boolean openPV = true;
- @Expose
@ConfigOption(
+ name = "Custom Enchant Colours",
+ desc = ""
+ )
+ @ConfigEditorAccordion(
+ id = 1
+ )
+ public boolean neuEnchantsAccordion = true;
+ @Expose
+ @ConfigOption(
name = "Edit Enchant Colours",
desc = "Change the colours of certain SkyBlock enchants (/neuec)",
searchTags = "color"
)
@ConfigEditorButton(runnableId = 8, buttonText = "Open")
+ @ConfigAccordionId(id = 1)
public boolean editEnchantColoursButton = true;
@Expose
@@ -162,10 +180,20 @@ public class Misc {
maxValue = 500,
minStep = 10
)
+ @ConfigAccordionId(id = 1)
public int chromaSpeed = 100;
@Expose
@ConfigOption(
+ name = "Cache Tooltip Enchants",
+ desc = "Caches item enchants in tooltip to only use the neuec config once per item lookup.\nNOTE: It doesn't work on items without a uuid"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean cacheItemEnchant = true;
+
+ @Expose
+ @ConfigOption(
name = "Disable Skull retexturing",
desc = "Disables the skull retexturing."
)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Notifications.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Notifications.java
index 85ad2093..3541860d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Notifications.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Notifications.java
@@ -20,7 +20,10 @@
package io.github.moulberry.notenoughupdates.options.seperateSections;
import com.google.gson.annotations.Expose;
+import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigAccordionId;
+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.ConfigEditorColour;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorSlider;
import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption;
@@ -86,4 +89,43 @@ public class Notifications {
minStep = 25
)
public int boosterCookieWarningMins = 1440;
+
+ @Expose
+ @ConfigOption(
+ name = "Ender Nodes",
+ desc = ""
+ )
+ @ConfigEditorAccordion(id = 1)
+ public boolean enderNodeAccordion = false;
+
+ @Expose
+ @ConfigOption(
+ name = "Nested Endermite Alert",
+ desc = "It will alert the user if a nested endermite gets spawned"
+ )
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean endermiteAlert = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Nested Endermite Alert Color",
+ desc = "The color the alert will be shown"
+ )
+ @ConfigEditorColour
+ @ConfigAccordionId(id = 1)
+ public String endermiteAlertColor = "0:255:194:0:174";
+
+ @Expose
+ @ConfigOption(
+ name = "Nested Endermite Alert Display Time",
+ desc = "How long the display would stay for in ticks"
+ )
+ @ConfigEditorSlider(
+ minValue = 1,
+ maxValue = 200,
+ minStep = 20
+ )
+ @ConfigAccordionId(id = 1)
+ public int endermiteAlertTicks = 20;
}
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 60d9b607..7d0b9a0a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/MiningOverlay.java
@@ -19,8 +19,6 @@
package io.github.moulberry.notenoughupdates.overlays;
-import com.google.common.collect.ComparisonChain;
-import com.google.common.collect.Ordering;
import com.google.gson.annotations.Expose;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.core.config.Position;
@@ -29,16 +27,15 @@ import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils;
import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns;
import io.github.moulberry.notenoughupdates.options.NEUConfig;
import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.TabListUtils;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiChest;
-import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.init.Items;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
-import net.minecraft.scoreboard.ScorePlayerTeam;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.WorldSettings;
import net.minecraftforge.fml.relauncher.Side;
@@ -47,7 +44,6 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.util.vector.Vector2f;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
@@ -263,11 +259,8 @@ public class MiningOverlay extends TextTabOverlay {
int forgeInt = 0;
boolean commissions = false;
boolean forges = false;
- List<NetworkPlayerInfo> players =
- playerOrdering.sortedCopy(Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap());
- for (NetworkPlayerInfo info : players) {
- String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info);
+ for (String name : TabListUtils.getTabList()) {
if (name.contains("Mithril Powder:")) {
mithrilPowder = DARK_AQUA + Utils.trimWhitespaceAndFormatCodes(name).replaceAll("\u00a7[f|F|r]", "");
continue;
@@ -584,27 +577,6 @@ public class MiningOverlay extends TextTabOverlay {
}
}
- private static final Ordering<NetworkPlayerInfo> playerOrdering = Ordering.from(new PlayerComparator());
-
- @SideOnly(Side.CLIENT)
- static class PlayerComparator implements Comparator<NetworkPlayerInfo> {
- private PlayerComparator() {}
-
- public int compare(NetworkPlayerInfo o1, NetworkPlayerInfo o2) {
- ScorePlayerTeam team1 = o1.getPlayerTeam();
- ScorePlayerTeam team2 = o2.getPlayerTeam();
- return ComparisonChain.start().compareTrueFirst(
- o1.getGameType() != WorldSettings.GameType.SPECTATOR,
- o2.getGameType() != WorldSettings.GameType.SPECTATOR
- )
- .compare(
- team1 != null ? team1.getRegisteredName() : "",
- team2 != null ? team2.getRegisteredName() : ""
- )
- .compare(o1.getGameProfile().getName(), o2.getGameProfile().getName()).result();
- }
- }
-
@Override
protected Vector2f getSize(List<String> strings) {
if (NotEnoughUpdates.INSTANCE.config.mining.dwarvenOverlayIcons)
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 9ef9e474..e5c17a1a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
@@ -284,7 +284,8 @@ public class BasicPage extends GuiProfileViewerPage {
.get("avg_buy")
.getAsDouble()
);
- String networthIRLMoney = GuiProfileViewer.numberFormat.format(Math.round(((networthInCookies * 325) / 675) * 4.99));
+ String networthIRLMoney = GuiProfileViewer.numberFormat.format(Math.round(
+ ((networthInCookies * 325) / 675) * 4.99));
if (
mouseX > guiLeft + 8 &&
mouseX < guiLeft + 8 + fr.getStringWidth("Net Worth: " + GuiProfileViewer.numberFormat.format(networth))
@@ -302,6 +303,17 @@ public class BasicPage extends GuiProfileViewerPage {
);
getInstance().tooltipToDisplay.add("");
+ if (NotEnoughUpdates.INSTANCE.config.profileViewer.useSoopyNetworth
+ && profile.getSoopyNetworthLeaderboardPosition() >= 0
+ && profile.isProfileMaxSoopyNetworth(profileId)) {
+
+ String lbPosStr =
+ EnumChatFormatting.DARK_GREEN + "#" + EnumChatFormatting.GOLD + GuiProfileViewer.numberFormat.format(
+ profile.getSoopyNetworthLeaderboardPosition());
+ getInstance().tooltipToDisplay.add(lbPosStr + EnumChatFormatting.GREEN + " on the networth leaderboard!");
+ getInstance().tooltipToDisplay.add("");
+ }
+
if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
getInstance().tooltipToDisplay.addAll(nwCategoryHover);
getInstance().tooltipToDisplay.add(EnumChatFormatting.RED + "This is calculated using the current");
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 6d59db27..cbebb6f4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
@@ -223,6 +223,7 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance().tooltipToDisplay =
Lists.newArrayList(
+ 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),
@@ -370,6 +371,7 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance().tooltipToDisplay =
Lists.newArrayList(
+ 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),
@@ -668,6 +670,8 @@ public class DungeonPage extends GuiProfileViewerPage {
activeClass = activeClassElement.getAsString();
}
+ ProfileViewer.Level classAverage = new ProfileViewer.Level();
+
for (int i = 0; i < dungSkillsName.length; i++) {
String skillName = dungSkillsName[i];
@@ -683,9 +687,19 @@ public class DungeonPage extends GuiProfileViewerPage {
50,
false
);
+
+ if (levelObj.level == 50) {
+ levelObj.level = 50 + (cataXp - 569809640) / 200000000;
+ }
+
levelObjClasses.put(skillName, levelObj);
}
+ classAverage.level = (float) (levelObjClasses.values().stream().mapToDouble(l -> l.level).sum() / 5);
+ if (classAverage.level >= 50) {
+ classAverage.maxed = true;
+ }
+
String colour = EnumChatFormatting.WHITE.toString();
if (skillName.toLowerCase().equals(activeClass)) {
colour = EnumChatFormatting.GREEN.toString();
@@ -694,8 +708,17 @@ public class DungeonPage extends GuiProfileViewerPage {
ProfileViewer.Level levelObj = levelObjClasses.get(skillName);
getInstance()
- .renderXpBar(colour + skillName, dungSkillsStack[i], x, y + 20 + 29 * i, sectionWidth, levelObj, mouseX, mouseY);
+ .renderXpBar(colour + skillName, dungSkillsStack[i], x, y + 20 + 24 * i, sectionWidth, levelObj, mouseX, mouseY);
}
+
+ getInstance().renderXpBar(
+ EnumChatFormatting.WHITE + "Class Average",
+ new ItemStack(Items.nether_star),
+ x,
+ y + 20 + 24 * 5,
+ sectionWidth,
+ classAverage,
+ mouseX, mouseY);
}
drawSideButtons();
@@ -707,7 +730,7 @@ public class DungeonPage extends GuiProfileViewerPage {
int guiLeft = GuiProfileViewer.getGuiLeft();
int guiTop = GuiProfileViewer.getGuiTop();
- if (mouseX >= guiLeft + 50 && mouseX <= guiLeft + 70 && mouseY >= guiTop + 54 && mouseY <= guiTop + 64) {
+ if (mouseX >= guiLeft + 45 && mouseX <= guiLeft + 65 && mouseY >= guiTop + 54 && mouseY <= guiTop + 64) {
dungeonLevelTextField.mouseClicked(mouseX, mouseY, mouseButton);
} else {
dungeonLevelTextField.otherComponentClick();
@@ -829,7 +852,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 a0af254c..1936e9c3 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
@@ -58,7 +58,6 @@ public class ExtraPage extends GuiProfileViewerPage {
private int killScroll = 0;
private int mouseDWheel = 0;
-
public ExtraPage(GuiProfileViewer instance) {
super(instance);
getInstance().killDeathSearchTextField.setSize(80, 12);
@@ -109,7 +108,8 @@ public class ExtraPage extends GuiProfileViewerPage {
float xStart,
float yStartTop,
float xOffset,
- float yOffset) {
+ float yOffset
+ ) {
int guiLeft = GuiProfileViewer.getGuiLeft();
int guiTop = GuiProfileViewer.getGuiTop();
yStartTop = yStartTop + 78;
@@ -131,17 +131,16 @@ public class ExtraPage extends GuiProfileViewerPage {
return;
}
String displayName = itemInformation.get(essenceName).getAsJsonObject().get("displayname").getAsString();
- if (profileInfo.has(essenceName.toLowerCase())) {
- int essenceNumber = profileInfo.get(essenceName.toLowerCase()).getAsInt();
+ int essenceNumber =
+ (profileInfo.has(essenceName.toLowerCase()) ? profileInfo.get(essenceName.toLowerCase()).getAsInt() : 0);
- Utils.renderAlignedString(
- EnumChatFormatting.GOLD + displayName,
- EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(essenceNumber, 0),
- guiLeft + xStart + xOffset,
- guiTop + yStartTop + yOffset * i,
- 76
- );
- }
+ Utils.renderAlignedString(
+ EnumChatFormatting.GOLD + displayName,
+ EnumChatFormatting.WHITE + StringUtils.shortNumberFormat(essenceNumber, 0),
+ guiLeft + xStart + xOffset,
+ guiTop + yStartTop + yOffset * i,
+ 76
+ );
}
}
@@ -448,31 +447,28 @@ public class ExtraPage extends GuiProfileViewerPage {
}
}
- getInstance().killDeathSearchTextField.render((int) (guiLeft + xStart + xOffset * 3), (int) (guiTop + yStartBottom + 77));
+ getInstance().killDeathSearchTextField.render(
+ (int) (guiLeft + xStart + xOffset * 3),
+ (int) (guiTop + yStartBottom + 77)
+ );
float killDeathX = guiLeft + xStart + xOffset * 3;
- if(mouseX >= killDeathX && mouseX <= killDeathX+76) {
- if(mouseY >= guiTop + yStartTop && mouseY <= guiTop + yStartTop + 65) {
- if(mouseDWheel != 0) {if(mouseDWheel > 0) {killScroll-=1;} else {killScroll+=1;}} mouseDWheel = Mouse.getDWheel();
- if(killScroll < 0) {killScroll = 0;}
- } else if(mouseY >= guiTop + yStartBottom && mouseY <= guiTop + yStartBottom + 65) {
- if(mouseDWheel != 0) {if(mouseDWheel > 0) {deathScroll-=1;} else {deathScroll+=1;}} mouseDWheel = Mouse.getDWheel();
- if(deathScroll < 0) {deathScroll = 0;}
- }
-
- }
int index = 0;
int skipCount = 0;
+ int renderedKills = 0;
for (int killCount : topKills.descendingKeySet()) {
Set<String> kills = topKills.get(killCount);
for (String killType : kills) {
- boolean isSearch = getInstance().killDeathSearchTextField.getText().isEmpty() || killType.toLowerCase(Locale.ROOT).contains(getInstance().killDeathSearchTextField.getText().toLowerCase(Locale.ROOT));
- float killY = guiTop + yStartTop + yOffset * ((index-skipCount) - killScroll);
- if(!isSearch) skipCount++;
- if(isSearch && killY+6 < guiTop+yStartTop+65 && killY >= guiTop + yStartTop) {
+ boolean isSearch =
+ getInstance().killDeathSearchTextField.getText().isEmpty() || killType.toLowerCase(Locale.ROOT).contains(
+ getInstance().killDeathSearchTextField.getText().toLowerCase(Locale.ROOT));
+ float killY = guiTop + yStartTop + yOffset * ((index - skipCount) - killScroll);
+ if (!isSearch) skipCount++;
+ if (isSearch && killY + 6 < guiTop + yStartTop + 65 && killY >= guiTop + yStartTop) {
+ renderedKills++;
Utils.renderAlignedString(
- EnumChatFormatting.YELLOW + killType + " Kills",
+ EnumChatFormatting.YELLOW + "K: " + killType,
EnumChatFormatting.WHITE.toString() + killCount,
killDeathX,
killY,
@@ -480,21 +476,25 @@ public class ExtraPage extends GuiProfileViewerPage {
);
}
-
index++;
}
}
+
index = 0;
skipCount = 0;
+ int renderedDeaths = 0;
for (int deathCount : topDeaths.descendingKeySet()) {
Set<String> deaths = topDeaths.get(deathCount);
for (String deathType : deaths) {
- boolean isSearch = getInstance().killDeathSearchTextField.getText().isEmpty() || deathType.toLowerCase(Locale.ROOT).contains(getInstance().killDeathSearchTextField.getText().toLowerCase(Locale.ROOT));
- float deathY = guiTop + yStartBottom + yOffset * ((index-skipCount) - deathScroll);
- if(!isSearch) skipCount++;
- if(isSearch && deathY+6 < guiTop+yStartBottom+65 && deathY >= guiTop + yStartBottom) {
+ boolean isSearch =
+ getInstance().killDeathSearchTextField.getText().isEmpty() || deathType.toLowerCase(Locale.ROOT).contains(
+ getInstance().killDeathSearchTextField.getText().toLowerCase(Locale.ROOT));
+ float deathY = guiTop + yStartBottom + yOffset * ((index - skipCount) - deathScroll);
+ if (!isSearch) skipCount++;
+ if (isSearch && deathY + 6 < guiTop + yStartBottom + 65 && deathY >= guiTop + yStartBottom) {
+ renderedDeaths++;
Utils.renderAlignedString(
- EnumChatFormatting.YELLOW + "Deaths: " + deathType,
+ EnumChatFormatting.YELLOW + "D: " + deathType,
EnumChatFormatting.WHITE.toString() + deathCount,
killDeathX,
deathY,
@@ -504,6 +504,38 @@ public class ExtraPage extends GuiProfileViewerPage {
index++;
}
}
+
+ mouseDWheel = Mouse.getDWheel();
+ if (mouseX >= killDeathX && mouseX <= killDeathX + 76) {
+ if (mouseY >= guiTop + yStartTop && mouseY <= guiTop + yStartTop + 65) {
+ if (mouseDWheel > 0) {
+ killScroll -= 1;
+ } else if (mouseDWheel < 0) {
+ killScroll += 1;
+ }
+
+ if (killScroll < 0) {
+ killScroll = 0;
+ }
+ } else if (mouseY >= guiTop + yStartBottom && mouseY <= guiTop + yStartBottom + 65) {
+ if (mouseDWheel > 0) {
+ deathScroll -= 1;
+ } else if (mouseDWheel < 0) {
+ deathScroll += 1;
+ }
+ if (deathScroll < 0) {
+ deathScroll = 0;
+ }
+
+ }
+ }
+
+ if (killScroll > renderedDeaths) {
+ killScroll = renderedDeaths;
+ }
+ if (deathScroll > renderedKills) {
+ deathScroll = renderedKills;
+ }
}
private String getTimeSinceString(JsonObject profileInfo, String path) {
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 f327dae5..37605595 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -1039,15 +1039,27 @@ public class GuiProfileViewer extends GuiScreen {
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
if (levelObj.maxed) {
- levelStr = EnumChatFormatting.GOLD + "MAXED!";
+ levelStr = levelObj.maxLevel != 7 ?
+ EnumChatFormatting.GOLD + "MAXED!" + EnumChatFormatting.GRAY + " (Overflow level: " + String.format("%.2f", levelObj.level) + ")" :
+ EnumChatFormatting.GOLD + "MAXED!";
} else {
- int maxXp = (int) levelObj.maxXpForLevel;
- levelStr =
- EnumChatFormatting.DARK_PURPLE +
- StringUtils.shortNumberFormat(Math.round((level % 1) * maxXp)) +
- "/" +
- StringUtils.shortNumberFormat(maxXp);
+ if (skillName.contains("Class Average")) {
+ levelStr = "Progress: " + EnumChatFormatting.DARK_PURPLE + String.format("%.1f", (level % 1 * 100)) + "%";
+ totalXpStr = "Exact Class Average: " + EnumChatFormatting.WHITE + String.format("%.2f", levelObj.level);
+ } else {
+ int maxXp = (int) levelObj.maxXpForLevel;
+ levelStr =
+ EnumChatFormatting.DARK_PURPLE +
+ StringUtils.shortNumberFormat(Math.round((level % 1) * maxXp)) +
+ "/" +
+ StringUtils.shortNumberFormat(maxXp) +
+ // Since catacombs isn't considered 'maxed' at level 50 (since the cap is '99'), we can add
+ // a conditional here to add the overflow level rather than above
+ ((skillName.contains("Catacombs") && levelObj.level >= 50) ?
+ EnumChatFormatting.GRAY + " (Overflow level: " + String.format("%.2f", levelObj.level) + ")" : "");
+ }
}
if (totalXpStr != null) {
tooltipToDisplay = Utils.createList(levelStr, totalXpStr);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java
index 41217201..af904e1d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java
@@ -21,8 +21,6 @@ package io.github.moulberry.notenoughupdates.profileviewer;
import io.github.moulberry.notenoughupdates.util.TexLoc;
import io.github.moulberry.notenoughupdates.util.Utils;
-import java.io.IOException;
-import java.util.HashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.GlStateManager;
@@ -36,6 +34,9 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.Project;
+import java.io.IOException;
+import java.util.HashMap;
+
public class Panorama {
private static final TexLoc tl = new TexLoc(97, 19, Keyboard.KEY_P);
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 b32d3648..347ee660 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java
@@ -654,6 +654,7 @@ public class ProfileViewer {
private final AtomicBoolean updatingSoopyNetworth = new AtomicBoolean(false);
private final AtomicBoolean updatingBingoInfo = new AtomicBoolean(false);
private final Pattern COLL_TIER_PATTERN = Pattern.compile("_(-?\\d+)");
+ private long soopyNetworthLeaderboardPosition = -1; //-1 = default, -2 = loading, -3 = error
private String latestProfile = null;
private JsonArray skyblockProfiles = null;
private JsonObject guildInformation = null;
@@ -748,7 +749,11 @@ public class ProfileViewer {
}
//Sort keys based on category value
- keys = categoryWorth.keySet().stream().sorted(Comparator.comparingLong(k->getCategory((String) k)).reversed()).toArray(String[]::new);
+ keys = categoryWorth
+ .keySet()
+ .stream()
+ .sorted(Comparator.comparingLong(k -> getCategory((String) k)).reversed())
+ .toArray(String[]::new);
}
private SoopyNetworthData setLoading() {
@@ -771,6 +776,32 @@ public class ProfileViewer {
}
/**
+ * -1 = default, -2 = loading, -3 = error
+ * >= 0 = actual position
+ */
+ public long getSoopyNetworthLeaderboardPosition() {
+ if ("d0e05de76067454dbeaec6d19d886191".equals(uuid)) return 1;
+ return soopyNetworthLeaderboardPosition;
+ }
+
+ public boolean isProfileMaxSoopyNetworth(String profileName) {
+ String highestProfileName = "";
+ long largestProfileNetworth = 0;
+
+ for (String pName : soopyNetworth.keySet()) {
+ if (soopyNetworth.get(pName) == null) continue;
+
+ long pNet = soopyNetworth.get(pName).totalWorth;
+ if (pNet < largestProfileNetworth) continue;
+
+ highestProfileName = pName;
+ largestProfileNetworth = pNet;
+ }
+
+ return highestProfileName.equals(profileName);
+ }
+
+ /**
* Returns SoopyNetworthData with total = -1 if error
* Returns null if still loading
*/
@@ -782,10 +813,33 @@ public class ProfileViewer {
}
JsonArray playerInfo = getSkyblockProfiles(() -> {});
- if (playerInfo == null) return null; //Not sure how to support the callback in these cases
- if (updatingSoopyNetworth.get()) return new SoopyNetworthData(null).setLoading(); //It shouldent really matter tho as these should never occur in /peek
+ if (playerInfo == null)
+ return null; //Not sure how to support the callback in these cases
+ if (updatingSoopyNetworth.get())
+ return new SoopyNetworthData(null).setLoading(); //It shouldent really matter tho as these should never occur in /peek
updatingSoopyNetworth.set(true);
+ soopyNetworthLeaderboardPosition = -2; //loading
+ manager.apiUtils
+ .request()
+ .url("https://soopy.dev/api/v2/leaderboard/networth/user/" + this.uuid)
+ .requestJson()
+ .handle((jsonObject, throwable) -> {
+ if (throwable != null) throwable.printStackTrace();
+ if (throwable != null || !jsonObject.has("success") || !jsonObject.get("success").getAsBoolean()
+ || !jsonObject.has("data")
+ || !jsonObject.get("data").getAsJsonObject().has("data")
+ || !jsonObject.get("data").getAsJsonObject().get("data").getAsJsonObject().has("position")) {
+ //Something went wrong
+ //Set profile lb position to -3 to indicate that
+ soopyNetworthLeaderboardPosition = -3; //error
+ return null;
+ }
+ soopyNetworthLeaderboardPosition = jsonObject.get("data").getAsJsonObject().get("data").getAsJsonObject().get(
+ "position").getAsLong();
+ return null;
+ });
+
manager.apiUtils
.request()
.url("https://soopy.dev/api/v2/player_networth/" + this.uuid)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java
index 7df88964..36fc07aa 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryData.java
@@ -20,14 +20,15 @@
package io.github.moulberry.notenoughupdates.profileviewer.bestiary;
import io.github.moulberry.notenoughupdates.util.Utils;
-import java.util.LinkedHashMap;
-import java.util.List;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
+import java.util.LinkedHashMap;
+import java.util.List;
+
public class BestiaryData {
private static final LinkedHashMap<ItemStack, List<String>> bestiaryLocations = new LinkedHashMap<ItemStack, List<String>>() {
@@ -109,7 +110,7 @@ public class BestiaryData {
"family_ghast",
"family_mage_outlaw",
"family_magma_cube",
- "family_magma_cube_boss",
+ "family_magma_boss",
"family_matcho",
"family_charging_mushroom_cow",
"family_pigman",
@@ -505,9 +506,9 @@ public class BestiaryData {
)
);
put(
- "family_magma_cube_boss",
+ "family_magma_boss",
Utils.createSkull(
- EnumChatFormatting.AQUA + "§a§6§lMagma Cube Boss",
+ EnumChatFormatting.AQUA + "§a§4§lMagma Boss",
"35f02923-7bec-3869-9ef5-b42a4794cac8",
"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzg5NTdkNTAyM2M5MzdjNGM0MWFhMjQxMmQ0MzQxMGJkYTIzY2Y3OWE5ZjZhYjM2Yjc2ZmVmMmQ3YzQyOSJ9fX0="
)
@@ -1010,7 +1011,7 @@ public class BestiaryData {
put("family_ghast", "MOB");
put("family_mage_outlaw", "BOSS");
put("family_magma_cube", "MOB");
- put("family_magma_cube_boss", "BOSS");
+ put("family_magma_boss", "BOSS");
put("family_matcho", "MOB");
put("family_charging_mushroom_cow", "MOB");
put("family_pigman", "MOB");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java
index 3ceabaf5..819c16de 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyDungeonsWeight.java
@@ -26,6 +26,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Dungeons
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class LilyDungeonsWeight extends DungeonsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java
index 8ed43f6e..f47032a4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySkillsWeight.java
@@ -19,16 +19,17 @@
package io.github.moulberry.notenoughupdates.profileviewer.weight.lily;
-import static io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Weight.SKILL_NAMES;
-
import com.google.gson.JsonArray;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SkillsWeight;
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
+import static io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Weight.SKILL_NAMES;
+
public class LilySkillsWeight extends SkillsWeight {
public LilySkillsWeight(Map<String, ProfileViewer.Level> player) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java
index d26597a1..12cb01e2 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilySlayerWeight.java
@@ -24,6 +24,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SlayerWe
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class LilySlayerWeight extends SlayerWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java
index 4ffc9fdd..03c5cfbf 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/lily/LilyWeight.java
@@ -22,6 +22,7 @@ package io.github.moulberry.notenoughupdates.profileviewer.weight.lily;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Weight;
+
import java.util.Map;
public class LilyWeight extends Weight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java
index 3b5adae5..e41b0ff4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherDungeonsWeight.java
@@ -24,6 +24,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Dungeons
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class SenitherDungeonsWeight extends DungeonsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java
index 2a4ee48c..7ac717f7 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSkillsWeight.java
@@ -25,6 +25,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SkillsWe
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class SenitherSkillsWeight extends SkillsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java
index 80853853..e9fd5b41 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherSlayerWeight.java
@@ -25,6 +25,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.SlayerWe
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.WeightStruct;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.Utils;
+
import java.util.Map;
public class SenitherSlayerWeight extends SlayerWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java
index 2f813576..532db942 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/senither/SenitherWeight.java
@@ -21,6 +21,7 @@ package io.github.moulberry.notenoughupdates.profileviewer.weight.senither;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
import io.github.moulberry.notenoughupdates.profileviewer.weight.weight.Weight;
+
import java.util.Map;
public class SenitherWeight extends Weight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java
index 9c233554..c915d3be 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/DungeonsWeight.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.profileviewer.weight.weight;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+
import java.util.Map;
public abstract class DungeonsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java
index 5c372591..84d3f551 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SkillsWeight.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.profileviewer.weight.weight;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+
import java.util.Map;
public abstract class SkillsWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java
index 20b2762d..bab8a154 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/weight/weight/SlayerWeight.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.profileviewer.weight.weight;
import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+
import java.util.Map;
public abstract class SlayerWeight {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
index d63ea42c..54daf42d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
@@ -33,7 +33,6 @@ import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagList;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
@@ -91,32 +90,30 @@ public class RecipeGenerator {
if (uiTitle.equals("Confirm Process") && saveRecipe) {
ForgeRecipe recipe = parseSingleForgeRecipe(menu);
if (recipe == null) {
- p.addChatMessage(new ChatComponentText(
- "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "Could not parse recipe for this UI"));
+ Utils.addChatMessage(
+ "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "Could not parse recipe for this UI");
} else {
- p.addChatMessage(new ChatComponentText(
- "" + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + "Parsed recipe:"));
- p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Inputs:"));
+ Utils.addChatMessage("" + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + "Parsed recipe:");
+ Utils.addChatMessage("" + EnumChatFormatting.AQUA + " Inputs:");
for (Ingredient i : recipe.getInputs())
- p.addChatMessage(new ChatComponentText(
- " - " + EnumChatFormatting.AQUA + i.getInternalItemId() + " x " + i.getCount()));
- p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Output: " + EnumChatFormatting.GOLD +
- recipe.getOutput().getInternalItemId() + " x " + recipe.getOutput().getCount()));
- p.addChatMessage(new ChatComponentText(
+ Utils.addChatMessage(" - " + EnumChatFormatting.AQUA + i.getInternalItemId() + " x " + i.getCount());
+ Utils.addChatMessage("" + EnumChatFormatting.AQUA + " Output: " + EnumChatFormatting.GOLD +
+ recipe.getOutput().getInternalItemId() + " x " + recipe.getOutput().getCount());
+ Utils.addChatMessage(
"" + EnumChatFormatting.AQUA + " Time: " + EnumChatFormatting.GRAY + recipe.getTimeInSeconds() +
- " seconds (no QF) ."));
+ " seconds (no QF) .");
boolean saved = false;
try {
saved = saveRecipes(recipe.getOutput().getInternalItemId(), Collections.singletonList(recipe));
- } catch (IOException e) {
+ } catch (IOException ignored) {
}
if (!saved)
- p.addChatMessage(new ChatComponentText("" +
- EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
- EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " +
- EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
- EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD +
- " Failed to save recipe. Does the item already exist?"));
+ Utils.addChatMessage(
+ "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
+ EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " +
+ EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
+ EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD +
+ " Failed to save recipe. Does the item already exist?");
}
}
if (saveRecipe) attemptToSaveBestiary(menu);
@@ -171,8 +168,7 @@ public class RecipeGenerator {
for (String loreLine : mobLore) {
Matcher loreMatcher = LORE_PATTERN.matcher(loreLine);
if (!loreMatcher.matches()) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "[WARNING] Unknown lore line: " + loreLine));
+ Utils.addChatMessage("[WARNING] Unknown lore line: " + loreLine);
continue;
}
if (loreMatcher.group("coins") != null)
@@ -186,8 +182,7 @@ public class RecipeGenerator {
List<JsonObject> possibleItems = neu.manager.getItemInformation().values().stream().filter(it -> it.get(
"displayname").getAsString().equals(dropName)).collect(Collectors.toList());
if (possibleItems.size() != 1) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "[WARNING] Could not parse drop, ambiguous or missing item information: " + loreLine));
+ Utils.addChatMessage("[WARNING] Could not parse drop, ambiguous or missing item information: " + loreLine);
continue;
}
Ingredient item = new Ingredient(neu.manager, possibleItems.get(0).get("internalname").getAsString());
@@ -197,9 +192,7 @@ public class RecipeGenerator {
drops.add(new MobLootRecipe.MobDrop(item, chance, new ArrayList<>()));
}
if (loreMatcher.group("missing") != null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
- "[WARNING] You are missing Bestiary levels for drop: " + loreLine));
-
+ Utils.addChatMessage("[WARNING] You are missing Bestiary levels for drop: " + loreLine);
}
}
recipes.add(new MobLootRecipe(
@@ -218,15 +211,15 @@ public class RecipeGenerator {
boolean saved = false;
try {
saved = saveRecipes(internalMobName, recipes);
- } catch (IOException e) {
+ } catch (IOException ignored) {
}
if (!saved)
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("" +
- EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
- EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " +
- EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
- EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD +
- " Failed to save recipe. Does the item already exist?")); // TODO: MERGE CODE OVER
+ Utils.addChatMessage(
+ "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
+ EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " +
+ EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
+ EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD +
+ " Failed to save recipe. Does the item already exist?"); // TODO: MERGE CODE OVER
}
private int parseIntIgnoringCommas(String text) {
@@ -307,7 +300,7 @@ public class RecipeGenerator {
);
}
- private static Map<Character, Integer> durationSuffixLengthMap = new HashMap<Character, Integer>() {{
+ private static final Map<Character, Integer> durationSuffixLengthMap = new HashMap<Character, Integer>() {{
put('d', 60 * 60 * 24);
put('h', 60 * 60);
put('m', 60);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeHistory.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeHistory.java
new file mode 100644
index 00000000..c4a0f6e4
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeHistory.java
@@ -0,0 +1,74 @@
+/*
+ * 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.recipes;
+
+import net.minecraft.client.gui.GuiScreen;
+
+import java.util.ArrayList;
+
+public class RecipeHistory {
+
+ private static final int MAX_HISTORY_SIZE = 50;
+
+ private static ArrayList<GuiScreen> history = new ArrayList<>();
+ private static int historyIndex = 0;
+
+ public static void add(GuiScreen recipe) {
+ if (history.size() == MAX_HISTORY_SIZE) {
+ history.remove(0);
+ historyIndex--;
+ } else {
+ if (history.size() == 0) {
+ history.add(recipe);
+ } else {
+ if (historyIndex < history.size() - 1) {
+ history = new ArrayList<>(history.subList(0, historyIndex + 1));
+ }
+ history.add(recipe);
+ historyIndex++;
+ }
+ }
+ }
+
+ public static GuiScreen getPrevious() {
+ if (history.size() > 0) {
+ if (historyIndex - 1 < 0) {
+ return null;
+ }
+ historyIndex--;
+ return history.get(historyIndex);
+ }
+ return null;
+ }
+
+ public static GuiScreen getNext() {
+ if (historyIndex < history.size() - 1) {
+ historyIndex++;
+ return history.get(historyIndex);
+ }
+ return null;
+ }
+
+ public static void clear() {
+ history = new ArrayList<>();
+ historyIndex = 0;
+ }
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java
index 7818c3c0..e84c1c43 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java
@@ -22,6 +22,8 @@ package io.github.moulberry.notenoughupdates.util;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.events.ProfileDataLoadedEvent;
+import net.minecraft.client.Minecraft;
import org.apache.commons.io.IOUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URIBuilder;
@@ -48,7 +50,9 @@ import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -59,6 +63,7 @@ public class ApiUtil {
private static final ExecutorService executorService = Executors.newFixedThreadPool(3);
private static final String USER_AGENT = "NotEnoughUpdates/" + NotEnoughUpdates.VERSION;
private static SSLContext ctx;
+ private final Map<String, CompletableFuture<Void>> updateTasks = new HashMap<>();
static {
try {
@@ -77,6 +82,23 @@ public class ApiUtil {
}
}
+ public void updateProfileData() {
+ updateProfileData(Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""));
+ }
+
+ public void updateProfileData(String playerUuid) {
+ if (!updateTasks.getOrDefault(playerUuid, CompletableFuture.completedFuture(null)).isDone()) return;
+
+ updateTasks.put(playerUuid, newHypixelApiRequest("skyblock/profiles")
+ .queryArgument("uuid", Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""))
+ .requestJson()
+ .handle((jsonObject, throwable) -> {
+ new ProfileDataLoadedEvent(jsonObject).post();
+ return null;
+ }));
+
+ }
+
public static class Request {
private final List<NameValuePair> queryArguments = new ArrayList<>();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java
index 1968b51e..57c4ae3b 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HotmInformation.java
@@ -23,6 +23,7 @@ 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.events.ProfileDataLoadedEvent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.inventory.ContainerChest;
@@ -135,7 +136,7 @@ public class HotmInformation {
public synchronized void onLobbyJoin(WorldEvent.Load event) {
if (shouldReloadSoon) {
shouldReloadSoon = false;
- requestUpdate(false);
+ neu.manager.apiUtils.updateProfileData();
}
}
@@ -154,17 +155,7 @@ public class HotmInformation {
@SubscribeEvent
public synchronized void onChat(ClientChatReceivedEvent event) {
if (event.message.getUnformattedText().equals("Welcome to Hypixel SkyBlock!"))
- requestUpdate(false);
- }
-
- public synchronized void requestUpdate(boolean force) {
- if (updateTask.isDone() || force) {
- updateTask = neu.manager.apiUtils
- .newHypixelApiRequest("skyblock/profiles")
- .queryArgument("uuid", Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""))
- .requestJson()
- .thenAccept(this::updateInformation);
- }
+ neu.manager.apiUtils.updateProfileData();
}
/*
@@ -176,10 +167,13 @@ public class HotmInformation {
if (level > 20) return -1;
return QUICK_FORGE_MULTIPLIERS[level - 1];
}
+ @SubscribeEvent
+ public void onApiDataLoaded(ProfileDataLoadedEvent event) {
+ JsonObject data = event.getData();
+ if (data == null) return;
- public void updateInformation(JsonObject entireApiResponse) {
- if (!entireApiResponse.has("success") || !entireApiResponse.get("success").getAsBoolean()) return;
- JsonArray profiles = entireApiResponse.getAsJsonArray("profiles");
+ if (!data.has("success") || !data.get("success").getAsBoolean()) return;
+ JsonArray profiles = data.getAsJsonArray("profiles");
for (JsonElement element : profiles) {
JsonObject profile = element.getAsJsonObject();
String profileName = profile.get("cute_name").getAsString();
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java
index 3692602a..ea5e13ab 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java
@@ -116,6 +116,9 @@ public class ItemResolutionQuery {
case "PARTY_HAT_CRAB_ANIMATED":
resolvedName = resolveCrabHatName();
break;
+ case "ABICASE":
+ resolvedName = resolvePhoneCase();
+ break;
}
}
@@ -235,6 +238,11 @@ public class ItemResolutionQuery {
return "PARTY_HAT_CRAB_" + color.toUpperCase(Locale.ROOT) + (crabHatYear == 2022 ? "_ANIMATED" : "");
}
+ private String resolvePhoneCase() {
+ String model = getExtraAttributes().getString("model");
+ return "ABICASE_" + model.toUpperCase(Locale.ROOT);
+ }
+
private String resolveEnchantedBookNameFromNBT() {
NBTTagCompound enchantments = getExtraAttributes().getCompoundTag("enchantments");
String enchantName = IteratorUtils.getOnlyElement(enchantments.getKeySet(), null);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java b/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java
index 230b8ae5..e5d00a66 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java
@@ -34,7 +34,7 @@ public class NEUDebugLogger {
public static boolean allFlagsEnabled = false;
private static void chatLogger(String message) {
- mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "[NEU DEBUG] " + message));
+ Utils.addChatMessage(EnumChatFormatting.YELLOW + "[NEU DEBUG] " + message);
}
public static boolean isFlagEnabled(NEUDebugFlag flag) {
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 b5e6c391..b8e8312d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java
@@ -24,6 +24,7 @@ import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.listener.ScoreboardLocationChangeListener;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent;
+import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
import io.github.moulberry.notenoughupdates.overlays.OverlayManager;
import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay;
import net.minecraft.client.Minecraft;
@@ -38,7 +39,6 @@ import net.minecraft.scoreboard.Score;
import net.minecraft.scoreboard.ScoreObjective;
import net.minecraft.scoreboard.ScorePlayerTeam;
import net.minecraft.scoreboard.Scoreboard;
-import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
@@ -158,8 +158,7 @@ public class SBInfo {
public boolean checkForSkyblockLocation() {
if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || getLocation() == null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
- "[NEU] This command is not available outside SkyBlock"));
+ Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] This command is not available outside SkyBlock");
return false;
}
@@ -316,6 +315,7 @@ public class SBInfo {
String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info);
if (name.startsWith(profilePrefix)) {
String newProfile = Utils.cleanColour(name.substring(profilePrefix.length()));
+ setCurrentProfile(newProfile);
if (!Objects.equals(currentProfile, newProfile)) {
currentProfile = newProfile;
if (NotEnoughUpdates.INSTANCE.config != null)
@@ -458,4 +458,11 @@ public class SBInfo {
public JsonObject getMayorJson() {
return mayorJson;
}
+
+ public void setCurrentProfile(String newProfile) {
+ if (!newProfile.equals(currentProfile)) {
+ currentProfile = newProfile;
+ MinionHelperManager.getInstance().onProfileSwitch();
+ }
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/TabListUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/TabListUtils.java
new file mode 100644
index 00000000..a0266122
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/TabListUtils.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util;
+
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.Ordering;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.network.NetworkPlayerInfo;
+import net.minecraft.scoreboard.ScorePlayerTeam;
+import net.minecraft.world.WorldSettings;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+public class TabListUtils {
+
+ private static final Ordering<NetworkPlayerInfo> playerOrdering = Ordering.from(new PlayerComparator());
+
+ @SideOnly(Side.CLIENT)
+ static class PlayerComparator implements Comparator<NetworkPlayerInfo> {
+ private PlayerComparator() {}
+
+ public int compare(NetworkPlayerInfo o1, NetworkPlayerInfo o2) {
+ ScorePlayerTeam team1 = o1.getPlayerTeam();
+ ScorePlayerTeam team2 = o2.getPlayerTeam();
+ return ComparisonChain.start().compareTrueFirst(
+ o1.getGameType() != WorldSettings.GameType.SPECTATOR,
+ o2.getGameType() != WorldSettings.GameType.SPECTATOR
+ )
+ .compare(
+ team1 != null ? team1.getRegisteredName() : "",
+ team2 != null ? team2.getRegisteredName() : ""
+ )
+ .compare(o1.getGameProfile().getName(), o2.getGameProfile().getName()).result();
+ }
+ }
+
+ public static List<String> getTabList() {
+ List<NetworkPlayerInfo> players =
+ playerOrdering.sortedCopy(Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap());
+
+ List<String> result = new ArrayList<>();
+
+ for (NetworkPlayerInfo info : players) {
+ String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info);
+ result.add(name);
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java b/src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java
new file mode 100644
index 00000000..59db7cac
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/TitleUtil.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraftforge.client.event.RenderGameOverlayEvent;
+import net.minecraftforge.fml.common.eventhandler.EventPriority;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class TitleUtil {
+
+ private static final TitleUtil INSTANCE = new TitleUtil();
+
+ public static TitleUtil getInstance() {
+ return INSTANCE;
+ }
+
+ private String title = null;
+ private long titleLifetime = 0;
+ private int color = 0xFF0000;
+
+ public void createTitle(String title, int ticks, int color) {
+ this.title = title;
+ this.titleLifetime = System.nanoTime() + (ticks * 50000000L);
+ this.color = color;
+ }
+ /**
+ * Adapted from SkyblockAddons under MIT license
+ * @link https://github.com/BiscuitDevelopment/SkyblockAddons/blob/master/LICENSE
+ * @author BiscuitDevelopment
+ */
+ private void renderTitles (ScaledResolution scaledResolution) {
+ Minecraft mc = Minecraft.getMinecraft();
+ if (mc.theWorld == null || mc.thePlayer == null || !NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return;
+
+ int scaledWidth = scaledResolution.getScaledWidth();
+ int scaledHeight = scaledResolution.getScaledHeight();
+
+ if (this.title != null) {
+ int stringWidth = mc.fontRendererObj.getStringWidth(this.title);
+ float scale = 4f; // Scale is normally 4, but if it's larger than the screen, scale it down...
+ if (stringWidth * scale > scaledWidth * 0.9f) {
+ scale = scaledWidth * 0.9f / (float) stringWidth;
+ }
+ GlStateManager.pushMatrix();
+ GlStateManager.translate((float)(scaledWidth / 2),(float)(scaledHeight / 2), 0.0f);
+ GlStateManager.enableBlend();
+ GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
+ GlStateManager.pushMatrix();
+ GlStateManager.scale(scale, scale, scale);
+ mc.fontRendererObj.drawString(
+ this.title,
+ ((float)-mc.fontRendererObj.getStringWidth(this.title) / 2),
+ -20.0f,
+ color,
+ true
+ );
+ GlStateManager.popMatrix();
+ GlStateManager.popMatrix();
+ }
+ }
+
+ @SubscribeEvent(priority = EventPriority.HIGHEST)
+ public void onRenderHUD(RenderGameOverlayEvent event) {
+ if (event.type != RenderGameOverlayEvent.ElementType.HOTBAR) return;
+ if (System.nanoTime() >= titleLifetime) {
+ titleLifetime = 0;
+ title = null;
+ }
+ renderTitles(event.resolution);
+ }
+}
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 1ee24ec8..57f24370 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
@@ -78,6 +78,7 @@ import java.math.BigInteger;
import java.nio.FloatBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -117,7 +118,6 @@ public class Utils {
"VERY SPECIAL",
"SUPREME",
"^^ THAT ONE IS DIVINE ^^"
-//, "DIVINE"
};
public static String[] rarityArrC = new String[]{
EnumChatFormatting.WHITE + EnumChatFormatting.BOLD.toString() + "COMMON",
@@ -129,8 +129,6 @@ public class Utils {
EnumChatFormatting.RED + EnumChatFormatting.BOLD.toString() + "SPECIAL",
EnumChatFormatting.RED + EnumChatFormatting.BOLD.toString() + "VERY SPECIAL",
EnumChatFormatting.AQUA + EnumChatFormatting.BOLD.toString() + "DIVINE",
- EnumChatFormatting.AQUA + EnumChatFormatting.BOLD.toString() + "DIVINE",
- //EnumChatFormatting.AQUA+EnumChatFormatting.BOLD.toString()+"DIVINE",
};
public static final HashMap<String, String> rarityArrMap = new HashMap<String, String>() {{
put("COMMON", rarityArrC[0]);
@@ -142,11 +140,11 @@ public class Utils {
put("SPECIAL", rarityArrC[6]);
put("VERY SPECIAL", rarityArrC[7]);
put("DIVINE", rarityArrC[8]);
- // put("DIVINE", rarityArrC[9]);
}};
public static Splitter PATH_SPLITTER = Splitter.on(".").omitEmptyStrings().limit(2);
private static ScaledResolution lastScale = new ScaledResolution(Minecraft.getMinecraft());
private static long startTime = 0;
+ private static DecimalFormat simpleDoubleFormat = new DecimalFormat("0.0");
public static <T> ArrayList<T> createList(T... values) {
ArrayList<T> list = new ArrayList<>();
@@ -329,6 +327,11 @@ public class Utils {
}
public static String shortNumberFormat(double n, int iteration) {
+ if (n < 3 && n > 0) {
+ return simpleDoubleFormat.format(n);
+ }
+
+ if (n < 1000 && iteration == 0) return "" + (int) n;
double d = ((long) n / 100) / 10.0;
boolean isRound = (d * 10) % 10 == 0;
return (d < 1000 ?
@@ -1228,7 +1231,6 @@ public class Utils {
while ((lines++ < maxLines) || maxLines < 0) {
if (trimmed.length() == str.length()) {
drawStringScaled(trimmed, fr, x, y + yOff, shadow, colour, scale);
- //fr.drawString(trimmed, x, y + yOff, colour, shadow);
break;
} else if (trimmed.isEmpty()) {
yOff -= 12 * scale;
@@ -1946,13 +1948,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"
),
@@ -2016,4 +2018,13 @@ public class Utils {
}
return username;
}
+
+ public static void addChatMessage(String message) {
+ EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer;
+ if (thePlayer != null) {
+ thePlayer.addChatMessage(new ChatComponentText(message));
+ } else {
+ System.out.println(message);
+ }
+ }
}
diff --git a/src/main/resources/assets/notenoughupdates/minion_overlay.png b/src/main/resources/assets/notenoughupdates/minion_overlay.png
new file mode 100644
index 00000000..a9bd91ab
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/minion_overlay.png
Binary files differ