aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--FEATURES.md3
-rw-r--r--build.gradle.kts2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt33
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Diana.java6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/GUI.java14
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Minions.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Misc.java37
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt34
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt15
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/HyPixelData.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt (renamed from src/main/java/at/hannibal2/skyhanni/data/InventoryData.kt)2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt129
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/InventoryOpenEvent.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt18
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt20
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt13
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenInventoryNumbers.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt31
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt66
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/minion/MinionData.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt82
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt527
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt51
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt12
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt283
50 files changed, 1360 insertions, 233 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bc66c1f29..90cbd240b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@
+ Added **Hide Repeated Catches** - Delete past catches of the same trophy fish from chat. - (Thanks appable0)
+ Added **Trophy Counter Design** - Change the way trophy fish messages gets displayed in the chat. - (Thanks appable0)
+ Added **CH Join** - Helps buy a Pass for accessing the Crystal Hollows if needed.
++ Added **Estimated Item Value** - Displays an estimated item value for the item you hover over.
### Garden Features
+ Added **Copper Price** - Show copper to coin prices inside the Sky Mart inventory.
diff --git a/FEATURES.md b/FEATURES.md
index 1e393809d..aedf7ea42 100644
--- a/FEATURES.md
+++ b/FEATURES.md
@@ -230,4 +230,5 @@
+ **Particle Hider** - Hide blaze particles, fire block particles, fireball particles, near redstone particles, far particles or smoke particles.
+ Chicken Head Timer.
+ **rancher boots** speed display.
-+ **CH Join** - Helps buy a Pass for accessing the Crystal Hollows if needed. \ No newline at end of file
++ **CH Join** - Helps buy a Pass for accessing the Crystal Hollows if needed.
++ **Estimated Item Value** - Displays an estimated item value for the item you hover over. \ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index f62bc6d21..291d66a20 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -10,7 +10,7 @@ plugins {
}
group = "at.hannibal2.skyhanni"
-version = "0.17.Beta.27"
+version = "0.17.Beta.28"
// Toolchains:
java {
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
index 72fec9e44..5a1a92a4b 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
@@ -28,6 +28,7 @@ import at.hannibal2.skyhanni.features.garden.*;
import at.hannibal2.skyhanni.features.inventory.*;
import at.hannibal2.skyhanni.features.itemabilities.FireVeilWandParticles;
import at.hannibal2.skyhanni.features.itemabilities.abilitycooldown.ItemAbilityCooldown;
+import at.hannibal2.skyhanni.features.minion.MinionCollectLogic;
import at.hannibal2.skyhanni.features.minion.MinionFeatures;
import at.hannibal2.skyhanni.features.misc.*;
import at.hannibal2.skyhanni.features.misc.tiarelay.TiaRelayHelper;
@@ -74,7 +75,7 @@ import java.util.List;
public class SkyHanniMod {
public static final String MODID = "skyhanni";
- public static final String VERSION = "0.17.Beta.27";
+ public static final String VERSION = "0.17.Beta.28";
public static final String DEPENDENCIES = "after:notenoughupdates@[2.1.1,);";
@@ -116,7 +117,7 @@ public class SkyHanniMod {
loadModule(new ItemTipHelper());
loadModule(new RenderLivingEntityHelper());
loadModule(new SkillExperience());
- loadModule(new InventoryData());
+ loadModule(new OtherInventoryData());
loadModule(new TabListData());
loadModule(new RenderGuiData());
loadModule(new GardenCropMilestones());
@@ -238,6 +239,9 @@ public class SkyHanniMod {
loadModule(new AnitaMedalProfit());
loadModule(new ComposterDisplay());
loadModule(new GardenComposterInventoryFeatures());
+ loadModule(new MinionCollectLogic());
+ loadModule(new PasteIntoSigns());
+ loadModule(new EstimatedItemValue());
Commands.INSTANCE.init();
diff --git a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt
index d8c5f35de..733e8709f 100644
--- a/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/api/CollectionAPI.kt
@@ -8,6 +8,7 @@ import at.hannibal2.skyhanni.features.bazaar.BazaarApi
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.regex.Pattern
@@ -27,7 +28,7 @@ class CollectionAPI {
@SubscribeEvent
fun onProfileDataLoad(event: ProfileApiDataLoadedEvent) {
val profileData = event.profileData
- val jsonElement = profileData["collection"]?: return
+ val jsonElement = profileData["collection"] ?: return
val asJsonObject = jsonElement.asJsonObject ?: return
for ((rawName, rawCounter) in asJsonObject.entrySet()) {
val counter = rawCounter.asLong
@@ -116,5 +117,15 @@ class CollectionAPI {
}
return null
}
+
+ // TODO add support for replenish (higher collection than actual items in inv)
+ fun addFromInventory(internalName: String, amount: Int) {
+ val name = NEUItems.getItemStack(internalName).name?.removeColor() ?: return
+
+ val oldValue = collectionValue[name] ?: return
+
+ val newValue = oldValue + amount
+ collectionValue[name] = newValue
+ }
}
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt
index 75e31ab2a..dd10d8482 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigManager.kt
@@ -2,6 +2,7 @@ package at.hannibal2.skyhanni.config
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.ConfigLoadEvent
+import at.hannibal2.skyhanni.features.garden.CropType
import com.google.gson.GsonBuilder
import io.github.moulberry.moulconfig.observer.PropertyTypeAdapterFactory
import io.github.moulberry.moulconfig.processor.BuiltinMoulConfigGuis
@@ -36,14 +37,24 @@ class ConfigManager {
if (configFile!!.exists()) {
try {
- BufferedReader(InputStreamReader(FileInputStream(configFile!!), StandardCharsets.UTF_8)).use { reader ->
- SkyHanniMod.feature = gson.fromJson(
- reader,
- Features::class.java
- )
+ val inputStreamReader = InputStreamReader(FileInputStream(configFile!!), StandardCharsets.UTF_8)
+ val bufferedReader = BufferedReader(inputStreamReader)
+ val builder = StringBuilder()
+ for (line in bufferedReader.lines()) {
+ val result = fixConfig(line)
+ builder.append(result)
+ builder.append("\n")
}
+
+
+ SkyHanniMod.feature = gson.fromJson(
+ builder.toString(),
+ Features::class.java
+ )
logger.info("Loaded config from file")
} catch (e: Exception) {
+ println("config error")
+ e.printStackTrace()
val backupFile = configFile!!.resolveSibling("config-${System.currentTimeMillis()}-backup.json")
logger.error(
"Exception while reading $configFile. Will load blank config and save backup to $backupFile",
@@ -75,6 +86,18 @@ class ConfigManager {
)
}
+ private fun fixConfig(line: String): String {
+ var result = line
+ for (type in CropType.values()) {
+ val normal = "\"${type.cropName}\""
+ val enumName = "\"${type.name}\""
+ while (result.contains(normal)) {
+ result = result.replace(normal, enumName)
+ }
+ }
+ return result
+ }
+
fun saveConfig() {
try {
logger.info("Saving config file")
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Diana.java b/src/main/java/at/hannibal2/skyhanni/config/features/Diana.java
index deac9d9c3..37032d25b 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Diana.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Diana.java
@@ -25,6 +25,7 @@ public class Diana {
@Expose
@ConfigOption(name = "Griffin Burrows", desc = "")
+ @ConfigEditorBoolean
public boolean griffinBurrows = false;
@Expose
@@ -33,10 +34,7 @@ public class Diana {
public boolean burrowNearestWarp = false;
@Expose
- @ConfigOption(
- name = "Warp Key",
- desc = "Press this key to warp to nearest burrow waypoint."
- )
+ @ConfigOption(name = "Warp Key", desc = "Press this key to warp to nearest burrow waypoint.")
@ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
public int keyBindWarp = Keyboard.KEY_NONE;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/GUI.java b/src/main/java/at/hannibal2/skyhanni/config/features/GUI.java
index eba1feea8..957f12f8f 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/GUI.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/GUI.java
@@ -9,20 +9,12 @@ import org.lwjgl.input.Keyboard;
public class GUI {
- @ConfigOption(
- name = "Edit GUI Locations",
- desc = "Change the position of SkyHanni's overlays"
- )
- @ConfigEditorButton(
- buttonText = "Edit"
- )
+ @ConfigOption(name = "Edit GUI Locations", desc = "Change the position of SkyHanni's overlays")
+ @ConfigEditorButton(buttonText = "Edit")
public Runnable positions = GuiEditManager::openGuiEditor;
@Expose
- @ConfigOption(
- name = "Open Hotkey",
- desc = "Press this key to open the GUI Editor."
- )
+ @ConfigOption(name = "Open Hotkey", desc = "Press this key to open the GUI Editor.")
@ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
public int keyBindOpen = Keyboard.KEY_NONE;
}
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
index 2414d4c35..e48d0eee7 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
@@ -639,19 +639,20 @@ public class Garden {
@Expose
@ConfigOption(name = "Farming Armor Drops", desc = "")
- @ConfigEditorAccordion(id = 12)
+
+ @ConfigEditorAccordion(id = 18)
public boolean farmingArmorDrops = false;
@Expose
@ConfigOption(name = "Show Counter", desc = "Count all §9Cropie§7, §5Squash §7and §6Fermento §7dropped.")
@ConfigEditorBoolean
- @ConfigAccordionId(id = 12)
+ @ConfigAccordionId(id = 18)
public boolean farmingArmorDropsEnabled = true;
@Expose
@ConfigOption(name = "Hide Chat", desc = "Hide the chat message when receiving a farming armor drop.")
@ConfigEditorBoolean
- @ConfigAccordionId(id = 12)
+ @ConfigAccordionId(id = 18)
public boolean farmingArmorDropsHideChat = false;
@Expose
@@ -659,13 +660,13 @@ public class Garden {
@Expose
@ConfigOption(name = "Teleport Pads", desc = "")
- @ConfigEditorAccordion(id = 12)
+ @ConfigEditorAccordion(id = 19)
public boolean teleportPads = false;
@Expose
@ConfigOption(name = "Compact Name", desc = "Hide the 'Warp to' and 'No Destination' texts over teleport pads.")
@ConfigEditorBoolean
- @ConfigAccordionId(id = 12)
+ @ConfigAccordionId(id = 19)
public boolean teleportPadsCompactName = false;
@Expose
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Minions.java b/src/main/java/at/hannibal2/skyhanni/config/features/Minions.java
index ce09318e9..593a95ba9 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Minions.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Minions.java
@@ -11,6 +11,11 @@ public class Minions {
@ConfigEditorBoolean
public boolean nameDisplay = true;
+ @Expose
+ @ConfigOption(name = "Only Tier", desc = "Show only the tier number over the minion. (Useful for bingo)")
+ @ConfigEditorBoolean
+ public boolean nameOnlyTier = false;
+
@ConfigOption(name = "Last Clicked", desc = "")
@ConfigEditorAccordion(id = 0)
public boolean lastClickedMinion = false;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java
index 54e63c904..8b9ea625a 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java
@@ -2,11 +2,9 @@ package at.hannibal2.skyhanni.config.features;
import at.hannibal2.skyhanni.config.core.config.Position;
import com.google.gson.annotations.Expose;
-import io.github.moulberry.moulconfig.annotations.ConfigAccordionId;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorAccordion;
-import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
-import io.github.moulberry.moulconfig.annotations.ConfigOption;
+import io.github.moulberry.moulconfig.annotations.*;
import io.github.moulberry.moulconfig.observer.Property;
+import org.lwjgl.input.Keyboard;
public class Misc {
@@ -211,6 +209,32 @@ public class Misc {
public Position chickenHeadTimerPosition = new Position(-372, 73, false, true);
@Expose
+ @ConfigOption(name = "Estimated Item Value", desc = "(Enchantments, reforging stone prices, gemstones, gemstones, drill parts and more)")
+ @ConfigEditorAccordion(id = 11)
+ public boolean estimatedItemValue = false;
+
+ @Expose
+ @ConfigOption(name = "Enable Estimated Price", desc = "Displays an estimated item value for the item you hover over.")
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 11)
+ public boolean estimatedIemValueEnabled = false;
+
+ @Expose
+ @ConfigOption(name = "Hotkey", desc = "Press this key to show the estimated item value.")
+ @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE)
+ @ConfigAccordionId(id = 11)
+ public int estimatedItemValueHotkey = Keyboard.KEY_NONE;
+
+ @Expose
+ @ConfigOption(name = "Show always", desc = "Ignore the hotkey and always display the item value.")
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 11)
+ public boolean estimatedIemValueAlwaysEnabled = true;
+
+ @Expose
+ public Position itemPriceDataPos = new Position(140, 90, false, true);
+
+ @Expose
@ConfigOption(name = "Exp Bottles", desc = "Hides all the experience orbs lying on the ground.")
@ConfigEditorBoolean
public boolean hideExpBottles = false;
@@ -244,6 +268,11 @@ public class Misc {
public boolean hideFireOverlay = false;
@Expose
+ @ConfigOption(name = "Paste Into Signs", desc = "Allows you to paste the clipboard into Sings when you press Ctrl + V")
+ @ConfigEditorBoolean
+ public boolean pasteIntoSigns = true;
+
+ @Expose
@ConfigOption(name = "Config Button", desc = "Add a button to the pause menu to configure SkyHanni.")
@ConfigEditorBoolean
public boolean configButtonOnPause = true;
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java b/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java
index 0338f713c..eb9bd078a 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Slayer.java
@@ -95,4 +95,9 @@ public class Slayer {
@ConfigOption(name = "Quest Warning", desc = "Warning when wrong slayer quest is selected, or killing mobs for the wrong slayer.")
@ConfigEditorBoolean
public boolean questWarning = true;
+
+ @Expose
+ @ConfigOption(name = "Quest Warning Title", desc = "Sends a Title when warning.")
+ @ConfigEditorBoolean
+ public boolean questWarningTitle = true;
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt
index b55840b39..a21b9e133 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/ChatManager.kt
@@ -7,7 +7,9 @@ import at.hannibal2.skyhanni.events.SeaCreatureFishEvent
import at.hannibal2.skyhanni.features.fishing.SeaCreatureManager
import at.hannibal2.skyhanni.utils.LorenzLogger
import at.hannibal2.skyhanni.utils.LorenzUtils
+import net.minecraft.event.HoverEvent
import net.minecraft.network.play.server.S02PacketChat
+import net.minecraft.util.IChatComponent
import net.minecraftforge.client.event.ClientChatReceivedEvent
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -43,7 +45,7 @@ class ChatManager {
if (message.startsWith("§f{\"server\":\"")) return
val chatEvent = LorenzChatEvent(message, original)
- if (!event.message.toString().contains("(held item preview from soopy using [hand])")) {
+ if (!isSoopyMessage(event.message)) {
chatEvent.postAndCatch()
}
@@ -68,6 +70,36 @@ class ChatManager {
}
}
+ private fun isSoopyMessage(message: IChatComponent): Boolean {
+ for (sibling in message.siblings) {
+ if (isSoopyMessage(sibling)) return true
+ }
+
+ val style = message.chatStyle ?: return false
+ val hoverEvent = style.chatHoverEvent ?: return false
+ if (hoverEvent.action != HoverEvent.Action.SHOW_TEXT) return false
+ val text = hoverEvent.value?.formattedText ?: return false
+
+ val lines = text.split("\n")
+ if (lines.isEmpty()) return false
+
+ val last = lines.last()
+ if (last.startsWith("§f§lCOMMON")) return true
+ if (last.startsWith("§f§lCOMMON")) return true
+ if (last.startsWith("§a§lUNCOMMON")) return true
+ if (last.startsWith("§9§lRARE")) return true
+ if (last.startsWith("§5§lEPIC")) return true
+ if (last.startsWith("§6§lLEGENDARY")) return true
+ if (last.startsWith("§c§lSPECIAL")) return true
+
+ // TODO confirm this format is correct
+ if (last.startsWith("§c§lVERY SPECIAL")) return true
+
+ if (last.startsWith("§d§lMYTHIC")) return true
+
+ return false
+ }
+
@SubscribeEvent
fun onChatMessage(chatEvent: LorenzChatEvent) {
if (!LorenzUtils.inSkyBlock) return
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
index 5294d79a1..5d9fb4713 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GardenCropMilestones.kt
@@ -3,9 +3,9 @@ package at.hannibal2.skyhanni.data
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.events.CropMilestoneUpdateEvent
import at.hannibal2.skyhanni.events.InventoryOpenEvent
-import at.hannibal2.skyhanni.events.ProfileJoinEvent
import at.hannibal2.skyhanni.features.garden.CropType
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import net.minecraftforge.event.world.WorldEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.regex.Pattern
@@ -27,7 +27,7 @@ class GardenCropMilestones {
// }
@SubscribeEvent
- fun onProfileJoin(event: ProfileJoinEvent) {
+ fun onWorldChange(event: WorldEvent.Load) {
if (cropCounter.isEmpty()) {
for (crop in CropType.values()) {
crop.setCounter(0)
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt b/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt
index 7beaff605..cf4b0498e 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt
@@ -6,6 +6,8 @@ import at.hannibal2.skyhanni.config.core.config.gui.GuiPositionEditor
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import io.github.moulberry.notenoughupdates.NEUOverlay
+import io.github.moulberry.notenoughupdates.overlays.AuctionSearchOverlay
+import io.github.moulberry.notenoughupdates.overlays.BazaarSearchOverlay
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiChest
import net.minecraft.client.gui.inventory.GuiEditSign
@@ -30,11 +32,14 @@ class GuiEditManager {
if (!Keyboard.getEventKeyState()) return
val key = if (Keyboard.getEventKey() == 0) Keyboard.getEventCharacter().code + 256 else Keyboard.getEventKey()
- if (SkyHanniMod.feature.gui.keyBindOpen == key) {
- if (NEUOverlay.searchBarHasFocus) return
- if (isInGui()) return
- openGuiEditor()
- }
+ if (SkyHanniMod.feature.gui.keyBindOpen != key) return
+
+ if (NEUOverlay.searchBarHasFocus) return
+ if (AuctionSearchOverlay.shouldReplace()) return
+ if (BazaarSearchOverlay.shouldReplace()) return
+
+ if (isInGui()) return
+ openGuiEditor()
}
@SubscribeEvent(priority = EventPriority.LOWEST)
diff --git a/src/main/java/at/hannibal2/skyhanni/data/HyPixelData.kt b/src/main/java/at/hannibal2/skyhanni/data/HyPixelData.kt
index 3d5232dff..2b5c3569f 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/HyPixelData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/HyPixelData.kt
@@ -104,7 +104,7 @@ class HyPixelData {
for (line in ScoreboardData.sidebarLinesFormatted) {
when (line) {
" §7Ⓑ §7Bingo", // No Rank
- " §bⒷ §bBingo", // Rank 1
+ " §aⒷ §aBingo", // Rank 1
" §9Ⓑ §9Bingo", // Rank 2
" §5Ⓑ §5Bingo", // Rank 3
" §6Ⓑ §6Bingo", // Rank 4
diff --git a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt
index fc68e1a52..eb6e20590 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt
@@ -23,12 +23,13 @@ class ItemClickData {
val position = packet.position.toLorenzVec()
BlockClickEvent(ClickType.RIGHT_CLICK, position, packet.stack).postAndCatch()
}
- val itemInHand = Minecraft.getMinecraft().thePlayer.heldItem
if (packet is C07PacketPlayerDigging && packet.status == C07PacketPlayerDigging.Action.START_DESTROY_BLOCK) {
+ val itemInHand = Minecraft.getMinecraft().thePlayer.heldItem
val position = packet.position.toLorenzVec()
BlockClickEvent(ClickType.LEFT_CLICK, position, itemInHand).postAndCatch()
}
if (packet is C0APacketAnimation) {
+ val itemInHand = Minecraft.getMinecraft().thePlayer.heldItem
ItemClickEvent(itemInHand).postAndCatch()
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/data/InventoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt
index d3630c159..580383e0c 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/InventoryData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/OtherInventoryData.kt
@@ -7,7 +7,7 @@ import net.minecraft.network.play.server.S2FPacketSetSlot
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
-class InventoryData {
+class OtherInventoryData {
private var currentInventory: Inventory? = null
private var acceptItems = false
private var lateEvent: LateInventoryOpenEvent? = null
diff --git a/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt b/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt
index 1572468d8..5bafff0ba 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/OwnInventoryData.kt
@@ -1,19 +1,29 @@
package at.hannibal2.skyhanni.data
+import at.hannibal2.skyhanni.api.CollectionAPI
+import at.hannibal2.skyhanni.events.InventoryCloseEvent
import at.hannibal2.skyhanni.events.OwnInventorItemUpdateEvent
import at.hannibal2.skyhanni.events.PacketEvent
+import at.hannibal2.skyhanni.features.bazaar.BazaarApi
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUItems
+import net.minecraft.item.ItemStack
import net.minecraft.network.play.server.S2FPacketSetSlot
+import net.minecraftforge.event.world.WorldEvent
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class OwnInventoryData {
-// private var itemNames = mutableMapOf<Int, String>()
-// private var itemAmount = mutableMapOf<Int, Int>()
-// private var counter = mutableMapOf<String, Int>()
+ private var itemNames = mutableMapOf<Int, String>()
+ private var itemAmount = mutableMapOf<Int, Int>()
@SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true)
fun onChatPacket(event: PacketEvent.ReceiveEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+
val packet = event.packet
if (packet is S2FPacketSetSlot) {
val windowId = packet.func_149175_c()
@@ -22,57 +32,68 @@ class OwnInventoryData {
OwnInventorItemUpdateEvent(item).postAndCatch()
}
}
-// if (packet is S2FPacketSetSlot) {
-//// println("S2FPacketSetSlot")
-// val windowId = packet.func_149175_c()
-// val item = packet.func_149174_e()
-// val slot = packet.func_149173_d()
-// if (windowId != 0) return
-//
-// val name = item?.name ?: "null"
-//
-// val oldItem = itemNames.getOrDefault(slot, "null")
-// val oldAmount = itemAmount.getOrDefault(slot, 0)
-//
-//// println(" ")
-//// println("windowId: $windowId")
-// val amount = item?.stackSize ?: 0
-// if (name == oldItem) {
-// if (amount > oldAmount) {
-// val diff = amount - oldAmount
-//// println("added $diff $name")
-// add(name, diff)
-// }
-// } else {
-// if (name != "null") {
-//// println("added new $amount $name")
-// add(name, amount)
-// }
-// }
-//// println("$slot $oldItem x$oldAmount -> $name x$amount")
-// itemNames[slot] = name
-// itemAmount[slot] = amount
-// }
+ if (packet is S2FPacketSetSlot) {
+ val windowId = packet.func_149175_c()
+ val item = packet.func_149174_e()
+ val slot = packet.func_149173_d()
+ if (windowId != 0) return
+ val name = item?.name ?: "null"
+
+ val oldItem = itemNames.getOrDefault(slot, "null")
+ val oldAmount = itemAmount.getOrDefault(slot, 0)
+
+ val amount = item?.stackSize ?: 0
+ if (name == oldItem) {
+ val diff = amount - oldAmount
+ if (amount > oldAmount) {
+ add(item, diff)
+ }
+ } else {
+ if (name != "null") {
+ add(item, amount)
+ }
+ }
+ itemNames[slot] = name
+ itemAmount[slot] = amount
+ }
+ }
+
+ @SubscribeEvent
+ fun onInventoryClose(event: InventoryCloseEvent) {
+ BazaarApi.inBazaarInventory = false
+ lastClose = System.currentTimeMillis()
+ }
+
+ @SubscribeEvent
+ fun onWorldLoad(event: WorldEvent.Load) {
+ lastWorldSwitch = System.currentTimeMillis()
}
-// private fun add(name: String, add: Int) {
-// if (name == "§fHay Bale") return
-// if (name == "§fSeeds") return
-// if (name.contains("Hoe")) return
-//
-// // TODO remove later
-// if (name.contains("Mushroom")) return
-//
-//// println("added $add $name")
-// val old = counter.getOrDefault(name, 0)
-//// if (name == "§fWheat") {
-//// if (old == 1502) {
-//// old = 2504173
-//// }
-//// }
-// val new = old + add
-// val format = LorenzUtils.formatInteger(new)
-// println("have $name $format")
-// counter[name] = new
-// }
+ private var lastClose = 0L
+ private var lastWorldSwitch = 0L
+
+ private fun add(item: ItemStack?, add: Int) {
+ if (item == null) return
+
+ val diffClose = System.currentTimeMillis() - lastClose
+ if (diffClose < 500) return
+
+ val diffWorld = System.currentTimeMillis() - lastWorldSwitch
+ if (diffWorld < 3_000) return
+
+ val internalName = item.getInternalName()
+ val (_, amount) = NEUItems.getMultiplier(internalName)
+ if (amount > 1) return
+
+ if (internalName == "") {
+ LorenzUtils.debug("OwnInventoryData add is empty for: '$internalName'")
+ return
+ }
+
+ addMultiplier(internalName, add)
+ }
+
+ private fun addMultiplier(internalName: String, amount: Int) {
+ CollectionAPI.addFromInventory(internalName, amount)
+ }
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt
index 8ff1f481b..2aa1ec65a 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/InventoryCloseEvent.kt
@@ -1,5 +1,11 @@
package at.hannibal2.skyhanni.events
-import at.hannibal2.skyhanni.data.InventoryData
+import at.hannibal2.skyhanni.data.OtherInventoryData
+import net.minecraft.item.ItemStack
-class InventoryCloseEvent(val inventory: InventoryData.Inventory): LorenzEvent() \ No newline at end of file
+class InventoryCloseEvent(val inventory: OtherInventoryData.Inventory): LorenzEvent() {
+ val inventoryId: Int by lazy { inventory.windowId }
+ val inventoryName: String by lazy {inventory.title }
+ val inventorySize: Int by lazy {inventory.slotCount }
+ val inventoryItems: MutableMap<Int, ItemStack> by lazy {inventory.items }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/events/InventoryOpenEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/InventoryOpenEvent.kt
index aec3e6542..3c95e4507 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/InventoryOpenEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/InventoryOpenEvent.kt
@@ -1,16 +1,16 @@
package at.hannibal2.skyhanni.events
-import at.hannibal2.skyhanni.data.InventoryData
+import at.hannibal2.skyhanni.data.OtherInventoryData
import net.minecraft.item.ItemStack
-open class BaseInventoryOpenEvent(inventory: InventoryData.Inventory): LorenzEvent() {
+open class BaseInventoryOpenEvent(inventory: OtherInventoryData.Inventory): LorenzEvent() {
val inventoryId: Int by lazy { inventory.windowId }
val inventoryName: String by lazy {inventory.title }
val inventorySize: Int by lazy {inventory.slotCount }
val inventoryItems: MutableMap<Int, ItemStack> by lazy {inventory.items }
}
-class InventoryOpenEvent(inventory: InventoryData.Inventory): BaseInventoryOpenEvent(inventory)
+class InventoryOpenEvent(inventory: OtherInventoryData.Inventory): BaseInventoryOpenEvent(inventory)
// Firing with items that are added later
-class LateInventoryOpenEvent(inventory: InventoryData.Inventory): BaseInventoryOpenEvent(inventory) \ No newline at end of file
+class LateInventoryOpenEvent(inventory: OtherInventoryData.Inventory): BaseInventoryOpenEvent(inventory) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt
index eae5215ba..b00a7de19 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoCardDisplay.kt
@@ -127,7 +127,7 @@ class BingoCardDisplay {
private fun drawDisplay(): MutableList<String> {
val newList = mutableListOf<String>()
- newList.add("Community Goals")
+ newList.add("§6Community Goals:")
if (communityGoals.isEmpty()) {
newList.add("§cOpen the §e/bingo §ccard.")
} else {
@@ -136,7 +136,7 @@ class BingoCardDisplay {
val todo = personalGoals.filter { !it.done }
val done = MAX_PERSONAL_GOALS - todo.size
newList.add(" ")
- newList.add("Personal Goals: ($done/$MAX_PERSONAL_GOALS done)")
+ newList.add("§6Personal Goals: ($done/$MAX_PERSONAL_GOALS done)")
todo.mapTo(newList) { " " + it.description }
}
return newList
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt
index af909605e..791680545 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/BingoNextStepHelper.kt
@@ -47,7 +47,7 @@ class BingoNextStepHelper {
private fun drawDisplay(print: Boolean): MutableList<String> {
val newCurrentHelp = mutableListOf<String>()
- newCurrentHelp.add("Bingo Step Helper")
+ newCurrentHelp.add("§6Bingo Step Helper:")
if (currentSteps.isEmpty()) {
newCurrentHelp.add("§cOpen the §e/bingo §ccard.")
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt
index db4989621..bb1721397 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/CompactBingoChat.kt
@@ -96,6 +96,8 @@ class CompactBingoChat {
private fun onBestiarityUpgrade(event: LorenzChatEvent) {
val message = event.message
+ if (message.contains("§r§6§lBESTIARY MILESTONE")) return
+
if (message.startsWith(" §r§3§lBESTIARY §b§l")) {
blockedBestiarity = true
return
diff --git a/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt
index 88d69a672..fca965c15 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/bingo/MinionCraftHelper.kt
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.bingo
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.SendTitleHelper
import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.InventoryOpenEvent
import at.hannibal2.skyhanni.events.ProfileJoinEvent
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.name
@@ -21,7 +22,6 @@ import net.minecraftforge.fml.common.gameevent.TickEvent
import java.util.regex.Pattern
class MinionCraftHelper {
-
private var minionNamePattern = Pattern.compile("(.*) Minion (.*)")
private var tick = 0
private var display = listOf<String>()
@@ -267,4 +267,20 @@ class MinionCraftHelper {
}
private fun isMinionName(itemName: String) = itemName.contains(" Minion ") && !itemName.contains(" Minion Skin")
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryOpenEvent) {
+ if (!LorenzUtils.isBingoProfile) return
+ if (event.inventoryName != "Crafted Minions") return
+
+ for ((_, b) in event.inventoryItems) {
+ val name = b.name?: continue
+ if (!name.startsWith("§e")) continue
+
+ val internalName = NEUItems.getInternalName("$name I")
+ if (!tierOneMinionsDone.contains(internalName)) {
+ tierOneMinionsDone.add(internalName)
+ }
+ }
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
index fa6500bcb..0f51e65aa 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/AnitaMedalProfit.kt
@@ -42,12 +42,18 @@ class AnitaMedalProfit {
fun onInventoryOpen(event: InventoryOpenEvent) {
if (!config.anitaMedalProfitEnabled) return
if (event.inventoryName != "Anita") return
+ if (GardenVisitorFeatures.inVisitorInventory) return
inInventory = true
val table = mutableMapOf<Pair<String, String>, Pair<Double, String>>()
for ((_, item) in event.inventoryItems) {
- readItem(item, table)
+ try {
+ readItem(item, table)
+ } catch (e: Throwable) {
+ LorenzUtils.error("Error in AnitaMedalProfit while reading item '$item'")
+ e.printStackTrace()
+ }
}
val newList = mutableListOf<List<Any>>()
@@ -59,6 +65,10 @@ class AnitaMedalProfit {
private fun readItem(item: ItemStack, table: MutableMap<Pair<String, String>, Pair<Double, String>>) {
var itemName = item.name ?: return
if (itemName == " ") return
+ if (itemName == "§cClose") return
+ if (itemName == "§eUnique Gold Medals") return
+ if (itemName == "§aMedal Trades") return
+
if (itemName.endsWith("Enchanted Book")) {
itemName = item.getLore()[0]
}
@@ -69,11 +79,9 @@ class AnitaMedalProfit {
val (name, amount) = ItemUtils.readItemAmount(itemName)
if (name == null) return
- val internalName = try {
- NEUItems.getInternalName(name)
- } catch (e: Exception) {
- // TODO make a better alternative
- item.getInternalName()
+ var internalName = NEUItems.getInternalNameOrNull(name)
+ if (internalName == null) {
+ internalName = item.getInternalName()
}
val itemPrice = NEUItems.getPrice(internalName) * amount
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt
index 57cf15aa9..7f37c6867 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/ComposterDisplay.kt
@@ -56,6 +56,10 @@ class ComposterDisplay {
val newList = mutableListOf<List<Any>>()
newList.addAsSingletonList("§bComposter")
+ for (type in DataType.values()) {
+ if (!data.containsKey(type)) return
+ }
+
newList.add(DataType.TIME_LEFT.addToList(data))
val list = mutableListOf<Any>()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt
index bfc20a7cd..a09102033 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropMoneyDisplay.kt
@@ -202,7 +202,7 @@ class CropMoneyDisplay {
val (newId, amount) = NEUItems.getMultiplier(internalName)
if (amount < 10) continue
val itemName = NEUItems.getItemStack(newId).name?.removeColor() ?: continue
- val crop = GardenAPI.itemNameToCropName(itemName)
+ val crop = CropType.getByItemName(itemName)
crop?.let {
multipliers[internalName] = amount
cropNames[internalName] = it
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
index 1d71c8553..d83399c77 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
@@ -19,14 +19,19 @@ enum class CropType(val cropName: String, val toolName: String, iconSupplier: ()
;
val icon by lazy { iconSupplier() }
- override fun toString(): String {
- return cropName
- }
companion object {
- fun getByName(name: String) = values().firstOrNull { it.cropName == name }
+ fun getByName(cropName: String) = values().firstOrNull { it.cropName == cropName }
// TODO find better name for this method
fun getByNameNoNull(name: String) = getByName(name) ?: throw RuntimeException("No valid crop type '$name'")
+
+
+ fun getByItemName(itemName: String): CropType? {
+ if (itemName == "Red Mushroom" || itemName == "Brown Mushroom") {
+ return MUSHROOM
+ }
+ return getByName(itemName)
+ }
}
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt
index b5a7b0720..6b94e0707 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt
@@ -53,6 +53,7 @@ class EliteFarmingWeight {
@SubscribeEvent
fun onTick(event: TickEvent.ClientTickEvent) {
+ if (!isEnabled()) return
if (tick++ % 5 != 0) return
update()
}
@@ -230,8 +231,7 @@ class EliteFarmingWeight {
result["rank"].asInt
} catch (e: Exception) {
- apiError = true
- LorenzUtils.error("[SkyHanni] Failed to load farming weight data from elitebot.dev! please report this on discord!")
+ error()
e.printStackTrace()
-1
}
@@ -262,8 +262,13 @@ class EliteFarmingWeight {
println("url: '$url'")
e.printStackTrace()
}
+ error()
+ }
+
+ private fun error() {
apiError = true
- LorenzUtils.error("[SkyHanni] Failed to load farming weight data from elitebot.dev! please report this on discord!")
+ LorenzUtils.error("[SkyHanni] Loading the farming weight data from elitebot.dev failed!")
+ LorenzUtils.chat("§eYou can re-enter the garden to try to fix the problem. If this message repeats itself, please report it on Discord!")
}
private fun calculateCollectionWeight(round: Boolean = true): MutableMap<CropType, Double> {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
index 67b543c03..534c88ac4 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
@@ -2,10 +2,10 @@ package at.hannibal2.skyhanni.features.garden
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.data.ScoreboardData
import at.hannibal2.skyhanni.events.*
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.NEUItems
import net.minecraft.client.Minecraft
import net.minecraft.item.ItemStack
import net.minecraft.network.play.client.C09PacketHeldItemChange
@@ -35,6 +35,8 @@ class GardenAPI {
if (!inGarden()) return
tick++
if (tick % 10 == 0) {
+ onBarnPlot = ScoreboardData.sidebarLinesFormatted.contains(" §7⏣ §aThe Garden")
+
// We ignore random hypixel moments
Minecraft.getMinecraft().currentScreen ?: return
checkItemInHand()
@@ -80,6 +82,7 @@ class GardenAPI {
private val cropsPerSecond: MutableMap<CropType, Int> get() = SkyHanniMod.feature.hidden.gardenCropsPerSecond
var cropInHand: CropType? = null
var mushroomCowPet = false
+ var onBarnPlot = false
fun inGarden() = LorenzUtils.inSkyBlock && LorenzUtils.skyBlockIsland == IslandType.GARDEN
@@ -121,13 +124,6 @@ class GardenAPI {
cropsPerSecond[this] = speed
}
- fun itemNameToCropName(itemName: String): CropType? {
- if (itemName == "Red Mushroom" || itemName == "Brown Mushroom") {
- return CropType.MUSHROOM
- }
- return CropType.getByName(itemName)
- }
-
fun addGardenCropToList(crop: CropType, list: MutableList<Any>) {
try {
list.add(crop.icon)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt
index b1186f533..ca118f665 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenCropMilestoneDisplay.kt
@@ -316,7 +316,7 @@ class GardenCropMilestoneDisplay {
lastPlaySoundTime = System.currentTimeMillis()
sound.playSound()
}
- SendTitleHelper.sendTitle("§b$crop $nextTier in $duration", 1_500)
+ SendTitleHelper.sendTitle("§b${crop.cropName} $nextTier in $duration", 1_500)
}
}
lineMap[3] = Collections.singletonList("§7In §b$duration")
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenInventoryNumbers.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenInventoryNumbers.kt
index 76770e182..708a50be9 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenInventoryNumbers.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenInventoryNumbers.kt
@@ -12,7 +12,7 @@ import java.util.regex.Pattern
class GardenInventoryNumbers {
private var patternTierProgress = Pattern.compile("§7Progress to Tier (.*): §e(?:.*)")
- private var patternUpgradeTier = Pattern.compile("§7Current Tier: §e(.*)§7/§a.*")
+ private var patternUpgradeTier = Pattern.compile("§7Current Tier: §[ea](.*)§7/§a.*")
private val patternComposterUpgrades =
Pattern.compile("§a(?:Composter Speed|Multi Drop|Fuel Cap|Organic Matter Cap|Cost Reduction) ?(.*)?")
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
index 2a1f8b4dc..5c1b83610 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
@@ -13,7 +13,6 @@ import at.hannibal2.skyhanni.utils.renderables.Renderable
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiEditSign
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiEditSign
-import net.minecraft.util.ChatComponentText
import net.minecraftforge.client.event.GuiOpenEvent
import net.minecraftforge.client.event.GuiScreenEvent.DrawScreenEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -39,15 +38,11 @@ class GardenOptimalSpeed {
}
}
-
@SubscribeEvent
fun onGuiOpen(event: GuiOpenEvent) {
rancherOverlayList = CropType.values().map { crop ->
listOf(crop.icon, Renderable.link("${crop.cropName} - ${crop.getOptimalSpeed()}") {
- val gui = Minecraft.getMinecraft().currentScreen
- if (gui !is GuiEditSign) return@link
- gui as AccessorGuiEditSign
- gui.tileSign.signText[0] = ChatComponentText("${crop.getOptimalSpeed()}")
+ LorenzUtils.setTextIntoSign("${crop.getOptimalSpeed()}")
})
}
}
@@ -92,27 +87,31 @@ class GardenOptimalSpeed {
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) {
if (!isEnabled()) return
- if (!Minecraft.getMinecraft().thePlayer.onGround) return
if (optimalSpeed == -1) return
val text = "Optimal Speed: §f$optimalSpeed"
if (optimalSpeed != currentSpeed) {
config.optimalSpeedPos.renderString("§c$text", posLabel = "Garden Optimal Speed")
- if (config.optimalSpeedWarning) {
- if (System.currentTimeMillis() > lastWarnTime + 20_000) {
- lastWarnTime = System.currentTimeMillis()
- SendTitleHelper.sendTitle("§cWrong speed!", 3_000)
- cropInHand?.let {
- LorenzUtils.chat("§e[SkyHanni] Wrong speed for $it: §f$currentSpeed §e(§f$optimalSpeed §eis optimal)")
- }
- }
- }
+ warn()
} else {
config.optimalSpeedPos.renderString("§a$text", posLabel = "Garden Optimal Speed")
}
}
+ private fun warn() {
+ if (!config.optimalSpeedWarning) return
+ if (!Minecraft.getMinecraft().thePlayer.onGround) return
+ if (GardenAPI.onBarnPlot) return
+ if (System.currentTimeMillis() < lastWarnTime + 20_000) return
+
+ lastWarnTime = System.currentTimeMillis()
+ SendTitleHelper.sendTitle("§cWrong speed!", 3_000)
+ cropInHand?.let {
+ LorenzUtils.chat("§e[SkyHanni] Wrong speed for ${it.cropName}: §f$currentSpeed §e(§f$optimalSpeed §eis optimal)")
+ }
+ }
+
private fun isRancherOverlayEnabled() = GardenAPI.inGarden() && config.optimalSpeedSignEnabled
private fun isEnabled() = GardenAPI.inGarden() && config.optimalSpeedEnabled
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt
index 917b40b85..25495a596 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt
@@ -1,7 +1,6 @@
package at.hannibal2.skyhanni.features.garden
import at.hannibal2.skyhanni.SkyHanniMod
-import at.hannibal2.skyhanni.data.ScoreboardData.Companion.sidebarLinesFormatted
import at.hannibal2.skyhanni.data.SendTitleHelper
import at.hannibal2.skyhanni.events.*
import at.hannibal2.skyhanni.features.garden.GardenAPI.Companion.getSpeed
@@ -29,11 +28,9 @@ import net.minecraftforge.fml.common.gameevent.TickEvent
import java.util.regex.Pattern
class GardenVisitorFeatures {
-
private val visitors = mutableMapOf<String, Visitor>()
private var display = listOf<List<Any>>()
private var lastClickedNpc = 0
- private var onBarnPlot = false
private var tick = 0
private val copperPattern = Pattern.compile(" §8\\+§c(.*) Copper")
private val gardenExperiencePattern = Pattern.compile(" §8\\+§2(.*) §7Garden Experience")
@@ -180,6 +177,7 @@ class GardenVisitorFeatures {
@SubscribeEvent(priority = EventPriority.HIGH)
fun onStackClick(event: SlotClickEvent) {
if (!inVisitorInventory) return
+ if (event.slot.stack?.name != "§cRefuse Offer") return
if (event.slotId != 33) return
getVisitor(lastClickedNpc)?.let {
@@ -195,7 +193,7 @@ class GardenVisitorFeatures {
@SubscribeEvent
fun onCheckRender(event: CheckRenderEntityEvent<*>) {
if (!GardenAPI.inGarden()) return
- if (!onBarnPlot) return
+ if (!GardenAPI.onBarnPlot) return
if (config.visitorHighlightStatus != 1 && config.visitorHighlightStatus != 2) return
val entity = event.entity
@@ -209,7 +207,7 @@ class GardenVisitorFeatures {
@SubscribeEvent
fun onRenderWorld(event: RenderWorldLastEvent) {
if (!GardenAPI.inGarden()) return
- if (!onBarnPlot) return
+ if (!GardenAPI.onBarnPlot) return
if (config.visitorHighlightStatus != 1 && config.visitorHighlightStatus != 2) return
for (visitor in visitors.values) {
@@ -274,7 +272,7 @@ class GardenVisitorFeatures {
if (config.visitorExactAmountAndTime) {
val multiplier = NEUItems.getMultiplier(internalName)
val rawName = NEUItems.getItemStack(multiplier.first).name?.removeColor() ?: continue
- CropType.getByName(rawName)?.let {
+ CropType.getByItemName(rawName)?.let {
val speed = it.getSpeed()
val cropAmount = multiplier.second.toLong() * amount
val formatAmount = LorenzUtils.formatInteger(cropAmount)
@@ -318,11 +316,9 @@ class GardenVisitorFeatures {
fun onTick(event: TickEvent.ClientTickEvent) {
if (!GardenAPI.inGarden()) return
if (!config.visitorNeedsDisplay && config.visitorHighlightStatus == 3) return
- if (tick++ % 30 != 0) return
-
- onBarnPlot = sidebarLinesFormatted.contains(" §7⏣ §aThe Garden")
+ if (tick++ % 10 != 0) return
- if (onBarnPlot && config.visitorHighlightStatus != 3) {
+ if (GardenAPI.onBarnPlot && config.visitorHighlightStatus != 3) {
checkVisitorsReady()
}
}
@@ -510,10 +506,7 @@ class GardenVisitorFeatures {
if (!GardenAPI.inGarden()) return
if (!config.visitorNeedsDisplay) return
- if (config.visitorNeedsOnlyWhenClose) {
- //TODO check if on barn plot (sidebar)
- if (!onBarnPlot) return
- }
+ if (config.visitorNeedsOnlyWhenClose && !GardenAPI.onBarnPlot) return
config.visitorNeedsPos.renderStringsAndItems(display, posLabel = "Visitor Items Needed")
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt
new file mode 100644
index 000000000..d6f971ec3
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionCollectLogic.kt
@@ -0,0 +1,66 @@
+package at.hannibal2.skyhanni.features.minion
+
+import at.hannibal2.skyhanni.api.CollectionAPI
+import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.events.GuiContainerEvent
+import at.hannibal2.skyhanni.events.InventoryOpenEvent
+import at.hannibal2.skyhanni.utils.InventoryUtils
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.NEUItems
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class MinionCollectLogic {
+ private var oldMap = mapOf<String, Int>()
+
+ @SubscribeEvent
+ fun onInventoryOpen(event: InventoryOpenEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+ if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return
+ if (!event.inventoryName.contains(" Minion ")) return
+
+ event.inventoryItems[48]?.let {
+ if ("§aCollect All" == it.name) {
+ openMinion()
+ }
+ }
+ }
+
+ private fun openMinion() {
+ if (oldMap.isNotEmpty()) return
+ oldMap = count()
+ }
+
+ private fun count(): MutableMap<String, Int> {
+ val map = mutableMapOf<String, Int>()
+ for (stack in InventoryUtils.getItemsInOwnInventory()) {
+ val internalName = stack.getInternalName()
+ val (newId, amount) = NEUItems.getMultiplier(internalName)
+ val old = map[newId] ?: 0
+ map[newId] = old + amount * stack.stackSize
+ }
+ return map
+ }
+
+ // hypixel opens a new inventory after clicking on an item in minion inventory, InventoryCloseEvent is not usable here
+ @SubscribeEvent
+ fun onCloseWindow(event: GuiContainerEvent.CloseWindowEvent) {
+ closeMinion()
+ }
+
+ private fun closeMinion() {
+ if (oldMap.isEmpty()) return
+
+ for ((internalId, amount) in count()) {
+ val old = oldMap[internalId] ?: 0
+ val diff = amount - old
+
+ if (diff > 0) {
+ CollectionAPI.addFromInventory(internalId, diff)
+ }
+ }
+
+ oldMap = emptyMap()
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionData.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionData.kt
index 02ee25b51..e05e56544 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionData.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionData.kt
@@ -2,4 +2,4 @@ package at.hannibal2.skyhanni.features.minion
import scala.Serializable
-class MinionData(var name: String,var lastClicked: Long) : Serializable \ No newline at end of file
+class MinionData(var displayName: String, var lastClicked: Long) : Serializable \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt
index b6daa011f..e17e54263 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/minion/MinionFeatures.kt
@@ -10,6 +10,7 @@ import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.ItemUtils.name
import at.hannibal2.skyhanni.utils.LorenzUtils.formatInteger
import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal
+import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNeeded
import at.hannibal2.skyhanni.utils.RenderUtils.drawString
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
@@ -26,9 +27,10 @@ import net.minecraftforge.fml.common.gameevent.InputEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
import org.lwjgl.input.Mouse
import java.awt.Color
+import java.util.regex.Pattern
class MinionFeatures {
-
+ private val config get() = SkyHanniMod.feature.minions
private var lastClickedEntity: LorenzVec? = null
private var lastMinion: LorenzVec? = null
private var lastMinionOpened = 0L
@@ -38,6 +40,7 @@ class MinionFeatures {
private var lastMinionPickedUp = 0L
private val minions = mutableMapOf<LorenzVec, MinionData>()
private var coinsPerDay = ""
+ private val minionUpgradePattern = Pattern.compile("§aYou have upgraded your Minion to Tier (.*)")
@SubscribeEvent
fun onConfigLoad(event: ConfigLoadEvent) {
@@ -69,14 +72,14 @@ class MinionFeatures {
fun onRenderLastClickedMinion(event: RenderWorldLastEvent) {
if (!LorenzUtils.inSkyBlock) return
if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return
- if (!SkyHanniMod.feature.minions.lastClickedMinionDisplay) return
+ if (!config.lastClickedMinionDisplay) return
- val special = SkyHanniMod.feature.minions.lastOpenedMinionColor
+ val special = config.lastOpenedMinionColor
val color = Color(SpecialColour.specialToChromaRGB(special), true)
val loc = lastMinion
if (loc != null) {
- val time = SkyHanniMod.feature.minions.lastOpenedMinionTime * 1_000
+ val time = config.lastOpenedMinionTime * 1_000
if (lastMinionOpened + time > System.currentTimeMillis()) {
event.drawWaypointFilled(
loc.add(-0.5, 0.0, -0.5),
@@ -102,8 +105,8 @@ class MinionFeatures {
minions[it] = MinionData(name, 0)
saveConfig()
} else {
- if (minions[it]!!.name != name) {
- minions[it]!!.name = name
+ if (minions[it]!!.displayName != name) {
+ minions[it]!!.displayName = name
saveConfig()
}
}
@@ -136,19 +139,17 @@ class MinionFeatures {
}
}
- if (SkyHanniMod.feature.minions.hopperProfitDisplay) {
+ if (config.hopperProfitDisplay) {
coinsPerDay = if (minionInventoryOpen) {
updateCoinsPerDay()
- } else {
- ""
- }
+ } else ""
}
}
- private fun getMinionName(inventoryName: String): String {
- var list = inventoryName.split(" ").toList()
+ private fun getMinionName(oldName: String, newTier: Int = 0): String {
+ var list = oldName.split(" ").toList()
val last = list.last()
- val number = last.romanToDecimal()
+ val number = if (newTier != 0) newTier else last.romanToDecimal()
list = list.dropLast(1)
return list.joinToString(" ") + " $number"
@@ -189,7 +190,7 @@ class MinionFeatures {
val coordinates = minion.key.encodeToString()
val data = minion.value
minionConfig[coordinates] = data.lastClicked
- minionName[coordinates] = data.name
+ minionName[coordinates] = data.displayName
}
}
@@ -206,12 +207,23 @@ class MinionFeatures {
if (!LorenzUtils.inSkyBlock) return
if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return
- if (event.message.matchRegex("§aYou received §r§6(.*) coins§r§a!")) {
+ val message = event.message
+ if (message.matchRegex("§aYou received §r§6(.*) coins§r§a!")) {
lastCoinsRecived = System.currentTimeMillis()
}
- if (event.message.startsWith("§aYou picked up a minion!")) {
+ if (message.startsWith("§aYou picked up a minion!")) {
lastMinionPickedUp = System.currentTimeMillis()
}
+
+ val matcher = minionUpgradePattern.matcher(message)
+ if (matcher.matches()) {
+ val newTier = matcher.group(1).romanToDecimalIfNeeded()
+ minions[lastMinion]?.let {
+ val minionName = getMinionName(it.displayName, newTier)
+ it.displayName = minionName
+ saveConfig()
+ }
+ }
}
@SubscribeEvent
@@ -223,23 +235,25 @@ class MinionFeatures {
val playerEyeLocation = LocationUtils.playerEyeLocation()
for (minion in minions) {
val location = minion.key.add(0.0, 1.0, 0.0)
- if (LocationUtils.canSee(playerEyeLocation, location)) {
- val lastEmptied = minion.value.lastClicked
- if (playerLocation.distance(location) < SkyHanniMod.feature.minions.distance) {
+ if (!LocationUtils.canSee(playerEyeLocation, location)) continue
- if (SkyHanniMod.feature.minions.nameDisplay) {
- val name = "§9" + minion.value.name
- event.drawString(location.add(0.0, 0.65, 0.0), name, true)
- }
+ val lastEmptied = minion.value.lastClicked
+ if (playerLocation.distance(location) >= config.distance) continue
- if (SkyHanniMod.feature.minions.emptiedTimeDisplay) {
- if (lastEmptied != 0L) {
- val duration = System.currentTimeMillis() - lastEmptied
- val format = TimeUtils.formatDuration(duration, longName = true) + " ago"
- val text = "§eHopper Emptied: $format"
- event.drawString(location.add(0.0, 1.15, 0.0), text, true)
- }
- }
+ if (config.nameDisplay) {
+ val displayName = minion.value.displayName
+ val name = "§6" + if (config.nameOnlyTier) {
+ displayName.split(" ").last()
+ } else displayName
+ event.drawString(location.add(0.0, 0.65, 0.0), name, true)
+ }
+
+ if (config.emptiedTimeDisplay) {
+ if (lastEmptied != 0L) {
+ val duration = System.currentTimeMillis() - lastEmptied
+ val format = TimeUtils.formatDuration(duration, longName = true) + " ago"
+ val text = "§eHopper Emptied: $format"
+ event.drawString(location.add(0.0, 1.15, 0.0), text, true)
}
}
}
@@ -249,7 +263,7 @@ class MinionFeatures {
fun onRenderLiving(event: RenderLivingEvent.Specials.Pre<EntityLivingBase>) {
if (!LorenzUtils.inSkyBlock) return
if (LorenzUtils.skyBlockIsland != IslandType.PRIVATE_ISLAND) return
- if (!SkyHanniMod.feature.minions.hideMobsNametagNearby) return
+ if (!config.hideMobsNametagNearby) return
val entity = event.entity
if (entity !is EntityArmorStand) return
@@ -266,8 +280,8 @@ class MinionFeatures {
@SubscribeEvent(priority = EventPriority.LOWEST)
fun renderOverlay(event: GuiScreenEvent.BackgroundDrawnEvent) {
- if (SkyHanniMod.feature.minions.hopperProfitDisplay) {
- SkyHanniMod.feature.minions.hopperProfitPos.renderString(coinsPerDay, posLabel = "Minion Coins Per Day")
+ if (config.hopperProfitDisplay) {
+ config.hopperProfitPos.renderString(coinsPerDay, posLabel = "Minion Coins Per Day")
}
}
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt
new file mode 100644
index 000000000..a92dcf231
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/EstimatedItemValue.kt
@@ -0,0 +1,527 @@
+package at.hannibal2.skyhanni.features.misc
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.events.GuiRenderEvent
+import at.hannibal2.skyhanni.events.InventoryCloseEvent
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
+import at.hannibal2.skyhanni.utils.LorenzUtils.sortedDesc
+import at.hannibal2.skyhanni.utils.NEUItems
+import at.hannibal2.skyhanni.utils.NumberUtil
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getAbilityScrolls
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getDrillUpgrades
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFarmingForDummiesCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getGemstones
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getHotPotatoCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getManaDisintegrators
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getMasterStars
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPowerScroll
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getReforgeName
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getSilexCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getTransmissionTunerCount
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfPiece
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasArtOfWar
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasBookOfStats
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasEtherwarp
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasJalapenoBook
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.hasWoodSingularity
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import io.github.moulberry.moulconfig.internal.KeybindHelper
+import io.github.moulberry.notenoughupdates.util.Constants
+import net.minecraft.init.Items
+import net.minecraft.item.ItemStack
+import net.minecraftforge.event.entity.player.ItemTooltipEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+class EstimatedItemValue {
+ private val config get() = SkyHanniMod.feature.misc
+ private var display = listOf<List<Any>>()
+ private val cache = mutableMapOf<ItemStack, List<List<Any>>>()
+ private var lastToolTipTime = 0L
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: GuiRenderEvent.ChestBackgroundRenderEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+ if (!config.estimatedIemValueEnabled) return
+ if (!KeybindHelper.isKeyDown(config.estimatedItemValueHotkey) && !config.estimatedIemValueAlwaysEnabled) return
+ if (System.currentTimeMillis() > lastToolTipTime + 200) return
+
+ config.itemPriceDataPos.renderStringsAndItems(display, posLabel = "Estimated Item Value")
+ }
+
+ @SubscribeEvent
+ fun onInventoryClose(event: InventoryCloseEvent) {
+ cache.clear()
+ }
+
+ @SubscribeEvent
+ fun onItemTooltipLow(event: ItemTooltipEvent) {
+ if (!LorenzUtils.inSkyBlock) return
+ if (!config.estimatedIemValueEnabled) return
+
+ val item = event.itemStack
+ val oldData = cache[item]
+ if (oldData != null) {
+ display = oldData
+ lastToolTipTime = System.currentTimeMillis()
+ return
+ }
+
+ val newDisplay = try {
+ draw(item)
+ } catch (e: Exception) {
+ LorenzUtils.debug("Estimated Item Value error: ${e.message}")
+ e.printStackTrace()
+ listOf()
+ }
+
+ cache[item] = newDisplay
+ display = newDisplay
+ lastToolTipTime = System.currentTimeMillis()
+ }
+
+ private fun draw(stack: ItemStack): MutableList<List<Any>> {
+ val list = mutableListOf<String>()
+ list.add("§aEstimated Item Value:")
+
+ val internalName = stack.getInternalName()
+ if (internalName == "") return mutableListOf()
+
+ //FIX neu item list
+ if (internalName.startsWith("ULTIMATE_ULTIMATE_")) return mutableListOf()
+ if (stack.item == Items.enchanted_book) return mutableListOf()
+
+ var totalPrice = 0.0
+ val basePrice = addBaseItem(stack, list)
+ totalPrice += basePrice
+ totalPrice += addReforgeStone(stack, list)
+
+ // once
+ totalPrice += addRecomb(stack, list)
+ totalPrice += addArtOfWar(stack, list)
+ totalPrice += addArtOfPiece(stack, list)
+ totalPrice += addEtherwarp(stack, list)
+ totalPrice += addPowerScrolls(stack, list)
+ totalPrice += addWoodSingularity(stack, list)
+ totalPrice += addJalapenoBook(stack, list)
+
+ // counted
+ totalPrice += addMasterStars(stack, list)
+ totalPrice += addHotPotatoBooks(stack, list)
+ totalPrice += addFarmingForDummies(stack, list)
+ totalPrice += addSilex(stack, list)
+ totalPrice += addStatsBook(stack, list)
+ totalPrice += addTransmissionTuners(stack, list)
+ totalPrice += addManaDisintegrators(stack, list)
+
+ // dynamic
+ totalPrice += addAbilityScrolls(stack, list)
+ totalPrice += addDrillUpgrades(stack, list)
+ totalPrice += addGemstones(stack, list)
+ totalPrice += addEnchantments(stack, list)
+
+ if (basePrice == totalPrice) return mutableListOf()
+
+ list.add("§aTotal: §6§l" + NumberUtil.format(totalPrice))
+
+ val newDisplay = mutableListOf<List<Any>>()
+ for (line in list) {
+ newDisplay.addAsSingletonList(line)
+ }
+ return newDisplay
+ }
+
+ private fun addReforgeStone(stack: ItemStack, list: MutableList<String>): Double {
+ val rawReforgeName = stack.getReforgeName() ?: return 0.0
+
+ for ((internalName, values) in Constants.REFORGESTONES.entrySet()) {
+ val stone = values.asJsonObject
+ val reforgeName = stone.get("reforgeName").asString
+ if (rawReforgeName == reforgeName.lowercase()) {
+ val price = NEUItems.getPrice(internalName)
+ val name = NEUItems.getItemStack(internalName).name
+ list.add("§7Reforge: §9$reforgeName")
+ list.add(" §7($name §6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+ }
+
+ return 0.0
+ }
+
+ private fun addRecomb(stack: ItemStack, list: MutableList<String>): Double {
+ if (stack.isRecombobulated()) {
+ val wtfHardcodedRecomb = "RECOMBOBULATOR_3000"
+ val price = NEUItems.getPrice(wtfHardcodedRecomb)
+ list.add("§7Recombobulated: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ return 0.0
+ }
+
+ private fun addJalapenoBook(stack: ItemStack, list: MutableList<String>): Double {
+ if (stack.hasJalapenoBook()) {
+ val wtfHardcodedJalapeno = "JALAPENO_BOOK"
+
+ val price = NEUItems.getPrice(wtfHardcodedJalapeno)
+ list.add("§7Jalapeno Book: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ return 0.0
+ }
+
+ private fun addEtherwarp(stack: ItemStack, list: MutableList<String>): Double {
+ if (stack.hasEtherwarp()) {
+ val wtfHardcodedConduit = "ETHERWARP_CONDUIT"
+ val wtfHardcodedMerger = "ETHERWARP_MERGER"
+ val price = NEUItems.getPrice(wtfHardcodedConduit) + NEUItems.getPrice(wtfHardcodedMerger)
+ list.add("§7Etherwarp: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ return 0.0
+ }
+
+ private fun addWoodSingularity(stack: ItemStack, list: MutableList<String>): Double {
+ if (stack.hasWoodSingularity()) {
+ val wtfHardcodedSingularity = "WOOD_SINGULARITY"
+ val price = NEUItems.getPrice(wtfHardcodedSingularity)
+ list.add("§7Wood Singularity: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ return 0.0
+ }
+
+ private fun addArtOfWar(stack: ItemStack, list: MutableList<String>): Double {
+ if (stack.hasArtOfWar()) {
+ val ripTechno = "THE_ART_OF_WAR"
+ val price = NEUItems.getPrice(ripTechno)
+ list.add("§7The Art of War: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ return 0.0
+ }
+
+ private fun addStatsBook(stack: ItemStack, list: MutableList<String>): Double {
+ if (stack.hasBookOfStats()) {
+ val ripTechno = "BOOK_OF_STATS"
+ val price = NEUItems.getPrice(ripTechno)
+ list.add("§7Book of Stats: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ return 0.0
+ }
+
+ // TODO untested
+ private fun addArtOfPiece(stack: ItemStack, list: MutableList<String>): Double {
+ if (stack.hasArtOfPiece()) {
+ val ripTechno = "THE_ART_OF_PEACE"
+ val price = NEUItems.getPrice(ripTechno)
+ list.add("§7The Art Of Piece: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ return 0.0
+ }
+
+ private fun addHotPotatoBooks(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getHotPotatoCount()
+ if (count == 0) return 0.0
+
+ val hpb: Int
+ val fuming: Int
+ if (count <= 10) {
+ hpb = count
+ fuming = 0
+ } else {
+ hpb = 10
+ fuming = count - 10
+ }
+
+ var totalPrice = 0.0
+
+ val wtfHardcodedHpb = "HOT_POTATO_BOOK"
+ val hpbPrice = NEUItems.getPrice(wtfHardcodedHpb) * hpb
+ list.add("§7HPB's: §e$hpb§7/§e10 §7(§6" + NumberUtil.format(hpbPrice) + "§7)")
+ totalPrice += hpbPrice
+
+ if (fuming > 0) {
+ val wtfHardcodedFuming = "FUMING_POTATO_BOOK"
+ val fumingPrice = NEUItems.getPrice(wtfHardcodedFuming) * fuming
+ list.add("§7Fuming: §e$fuming§7/§e5 §7(§6" + NumberUtil.format(fumingPrice) + "§7)")
+ totalPrice += fumingPrice
+ }
+
+ return totalPrice
+ }
+
+ private fun addFarmingForDummies(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getFarmingForDummiesCount()
+ if (count == 0) return 0.0
+
+ val wtfHardcodedDumbFarmers = "FARMING_FOR_DUMMIES"
+ val price = NEUItems.getPrice(wtfHardcodedDumbFarmers) * count
+ list.add("§7Farming for Dummies: §e$count§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addSilex(stack: ItemStack, list: MutableList<String>): Double {
+ val tier = stack.getSilexCount()
+ if (tier == 0) return 0.0
+
+ val internalName = stack.getInternalName()
+ val maxTier = if (internalName == "STONK_PICKAXE") 4 else 5
+
+ val wtfHardcodedSilex = "SIL_EX"
+ val price = NEUItems.getPrice(wtfHardcodedSilex) * tier
+ list.add("§7Silex: §e$tier§7/§e$maxTier §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addTransmissionTuners(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getTransmissionTunerCount()
+ if (count == 0) return 0.0
+
+ val wtfHardcodedTuner = "TRANSMISSION_TUNER"
+ val price = NEUItems.getPrice(wtfHardcodedTuner) * count
+ list.add("§7Transmission Tuners: §e$count§7/§e4 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addManaDisintegrators(stack: ItemStack, list: MutableList<String>): Double {
+ val count = stack.getManaDisintegrators()
+ if (count == 0) return 0.0
+
+ val wtfHardcodedTuner = "MANA_DISINTEGRATOR"
+ val price = NEUItems.getPrice(wtfHardcodedTuner) * count
+ list.add("§7Mana Disintegrators: §e$count§7/§e10 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addMasterStars(stack: ItemStack, list: MutableList<String>): Double {
+ val masterStars = stack.getMasterStars()
+ if (masterStars == 0) return 0.0
+
+ var price = 0.0
+
+ val stars = mapOf(
+ "FIRST" to 1,
+ "SECOND" to 2,
+ "THIRD" to 3,
+ "FOURTH" to 4,
+ "FIFTH" to 5,
+ )
+
+ for ((prefix, number) in stars) {
+ if (masterStars >= number) {
+ val internalName = "${prefix}_MASTER_STAR"
+ price += NEUItems.getPrice(internalName)
+ }
+ }
+
+ list.add("§7Master Stars: §e$masterStars§7/§e5 §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addDrillUpgrades(stack: ItemStack, list: MutableList<String>): Double {
+ var totalPrice = 0.0
+ val map = mutableMapOf<String, Double>()
+ for (internalName in stack.getDrillUpgrades()) {
+ val name = NEUItems.getItemStackOrNull(internalName)!!.name
+ val price = NEUItems.getPriceOrNull(internalName) ?: continue
+
+ totalPrice += price
+ val format = NumberUtil.format(price)
+ map[" $name §7(§6$format§7)"] = price
+ }
+ if (map.isNotEmpty()) {
+ list.add("§7Drill upgrades: §6" + NumberUtil.format(totalPrice))
+ list += map.sortedDesc().keys
+ }
+ return totalPrice
+ }
+
+ private fun addPowerScrolls(stack: ItemStack, list: MutableList<String>): Double {
+ val internalName = stack.getPowerScroll() ?: return 0.0
+
+ val price = NEUItems.getPrice(internalName)
+ val name = NEUItems.getItemStack(internalName).name!!.removeColor()
+ list.add("§7$name: §a§l✔ §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addAbilityScrolls(stack: ItemStack, list: MutableList<String>): Double {
+ var totalPrice = 0.0
+ val map = mutableMapOf<String, Double>()
+ for (internalName in stack.getAbilityScrolls()) {
+ val name = NEUItems.getItemStackOrNull(internalName)!!.name
+ val price = NEUItems.getPriceOrNull(internalName) ?: continue
+
+ totalPrice += price
+ val format = NumberUtil.format(price)
+ map[" $name §7(§6$format§7)"] = price
+ }
+ if (map.isNotEmpty()) {
+ list.add("§7Ability Scrolls: §6" + NumberUtil.format(totalPrice))
+ list += map.sortedDesc().keys
+ }
+ return totalPrice
+ }
+
+ private fun addBaseItem(stack: ItemStack, list: MutableList<String>): Double {
+ val internalName = stack.getInternalName()
+ var price = NEUItems.getPrice(internalName)
+ if (price == -1.0) {
+ price = 0.0
+ }
+
+ val name = NEUItems.getItemStack(internalName).name
+ if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) {
+ list.add("§7Base item: $name")
+ return 0.0
+ }
+
+ list.add("§7Base item: $name §7(§6" + NumberUtil.format(price) + "§7)")
+ return price
+ }
+
+ private fun addEnchantments(stack: ItemStack, list: MutableList<String>): Double {
+ var totalPrice = 0.0
+ val map = mutableMapOf<String, Double>()
+
+ val tieredEnchants = listOf("compact", "cultivating", "champion", "expertise", "hecatomb")
+ val hasAlwaysScavenger = listOf(
+ "CRYPT_DREADLORD_SWORD",
+ "ZOMBIE_SOLDIER_CUTLASS",
+ "CONJURING_SWORD",
+ "EARTH_SHARD",
+ "ZOMBIE_KNIGHT_SWORD",
+ "SILENT_DEATH",
+ "ZOMBIE_COMMANDER_WHIP",
+ )
+
+ val internalName = stack.getInternalName()
+ for ((rawName, rawLevel) in stack.getEnchantments()) {
+ // efficiency 1-5 is cheap, 6-10 is handled by silex
+ if (rawName == "efficiency") continue
+
+ if (rawName == "scavenger" && rawLevel == 5) {
+ if (internalName in hasAlwaysScavenger) continue
+ }
+
+ var level = rawLevel
+ if (rawName in tieredEnchants) level = 1
+
+ val enchantmentName = "$rawName;$level".uppercase()
+ val itemStack = NEUItems.getItemStackOrNull(enchantmentName) ?: continue
+ var name = itemStack.getLore()[0]
+ val singlePrice = NEUItems.getPriceOrNull(enchantmentName) ?: continue
+ val multiplier = if (internalName.startsWith("ENCHANTED_BOOK_BUNDLE_")) {
+ name = "§85x $name"
+ 5
+ } else 1
+ val price = singlePrice * multiplier
+
+ totalPrice += price
+ val format = NumberUtil.format(price)
+
+
+ map[" $name §7(§6$format§7)"] = price
+ }
+ if (map.isNotEmpty()) {
+ list.add("§7Enchantments: §6" + NumberUtil.format(totalPrice))
+ var i = 0
+ val size = map.size
+ for (entry in map.sortedDesc().keys) {
+ if (i == 7) {
+ val missing = size - i
+ list.add(" §7§o$missing more enchantments..")
+ break
+ }
+ list.add(entry)
+ i++
+ }
+ }
+ return totalPrice
+ }
+
+ private fun addGemstones(stack: ItemStack, list: MutableList<String>): Double {
+ val gemstones = stack.getGemstones()
+ if (gemstones.isEmpty()) return 0.0
+
+ var totalPrice = 0.0
+ val counterMap = mutableMapOf<String, Int>()
+ for (gemstone in gemstones) {
+ val internalName = gemstone.getInternalName()
+ val old = counterMap[internalName] ?: 0
+ counterMap[internalName] = old + 1
+ }
+
+ val priceMap = mutableMapOf<String, Double>()
+ for ((internalName, amount) in counterMap) {
+
+ val name = NEUItems.getItemStack(internalName).name
+ val price = NEUItems.getPrice(internalName) * amount
+
+ totalPrice += price
+ val format = NumberUtil.format(price)
+
+ val text = if (amount == 1) {
+ " $name §7(§6$format§7)"
+ } else {
+ " §8${amount}x $name §7(§6$format§7)"
+ }
+ priceMap[text] = price
+ }
+
+ if (priceMap.isNotEmpty()) {
+ list.add("§7Gemstones: §6" + NumberUtil.format(totalPrice))
+ list += priceMap.sortedDesc().keys
+ }
+ return totalPrice
+ }
+
+ class GemstoneSlot(val type: GemstoneType, val tier: GemstoneTier) {
+ fun getInternalName() = "${tier}_${type}_GEM"
+ }
+
+ enum class GemstoneTier(val displayName: String) {
+ ROUGH("Rough"),
+ FLAWED("Flawed"),
+ FINE("Fine"),
+ FLAWLESS("Flawless"),
+ PERFECT("Perfect"),
+ ;
+
+ companion object {
+ fun getByName(name: String) = GemstoneTier.values().firstOrNull { it.name == name }
+ }
+ }
+
+ enum class GemstoneType(val displayName: String) {
+ JADE("Jade"),
+ AMBER("Amber"),
+ TOPAZ("Topaz"),
+ SAPPHIRE("Sapphire"),
+ AMETHYST("Amethyst"),
+ JASPER("Jasper"),
+ RUBY("Ruby"),
+ OPAL("Opal"),
+ ;
+
+ companion object {
+ fun getByName(name: String) = values().firstOrNull { it.name == name }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt
new file mode 100644
index 000000000..e77db7969
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/PasteIntoSigns.kt
@@ -0,0 +1,23 @@
+package at.hannibal2.skyhanni.features.misc
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.HyPixelData
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.OSUtils
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+import org.lwjgl.input.Keyboard
+
+class PasteIntoSigns {
+
+ @SubscribeEvent
+ fun onTick(event: TickEvent.ClientTickEvent) {
+ if (!HyPixelData.hypixel) return
+ if (!SkyHanniMod.feature.misc.pasteIntoSigns) return
+
+ if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && Keyboard.isKeyDown(Keyboard.KEY_V)) {
+ val clipboard = OSUtils.readFromClipboard() ?: return
+ LorenzUtils.setTextIntoSign(clipboard.take(15))
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt
index 16ae900a5..d699b04e1 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/slayer/SlayerQuestWarning.kt
@@ -16,7 +16,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.TickEvent
class SlayerQuestWarning {
-
+ private val config get() = SkyHanniMod.feature.slayer
private var needSlayerQuest = false
private var lastWarning = 0L
private var currentReason = ""
@@ -118,7 +118,7 @@ class SlayerQuestWarning {
@SubscribeEvent
fun onWorldChange(event: WorldEvent.Load) {
- if (!SkyHanniMod.feature.slayer.questWarning) return
+ if (!config.questWarning) return
if (!needSlayerQuest) {
dirtySidebar = true
@@ -135,7 +135,10 @@ class SlayerQuestWarning {
lastWarning = System.currentTimeMillis()
LorenzUtils.chat("§e[SkyHanni] $chatMessage")
- SendTitleHelper.sendTitle("§e$titleMessage", 2_000)
+
+ if (config.questWarningTitle) {
+ SendTitleHelper.sendTitle("§e$titleMessage", 2_000)
+ }
}
@SubscribeEvent
@@ -170,6 +173,6 @@ class SlayerQuestWarning {
}
private fun isEnabled(): Boolean {
- return LorenzUtils.inSkyBlock && SkyHanniMod.feature.slayer.questWarning
+ return LorenzUtils.inSkyBlock && config.questWarning
}
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt b/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt
index 02feac91c..45748339c 100644
--- a/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt
+++ b/src/main/java/at/hannibal2/skyhanni/test/LorenzTest.kt
@@ -92,7 +92,7 @@ class LorenzTest {
try {
val internalName = NEUItems.getInternalName(itemName)
list.add(NEUItems.getItemStack(internalName))
- } catch (e: Exception) {
+ } catch (e: Error) {
LorenzUtils.debug("itemName '$itemName' is invalid for visitor '$name'")
errors++
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt
index 41da163b0..91f54e6a3 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/APIUtil.kt
@@ -45,7 +45,7 @@ object APIUtil {
return parser.parse(retSrc) as JsonObject
} catch (e: JsonSyntaxException) {
if (retSrc.contains("<center><h1>502 Bad Gateway</h1></center>")) {
- LorenzUtils.error("[SkyHanni] HyPixel API is down :(")
+ LorenzUtils.error("[SkyHanni] Hypixel API is down :(")
} else {
println("JsonSyntaxException at getJSONResponse '$urlString'")
LorenzUtils.error("[SkyHanni] JsonSyntaxException at getJSONResponse!")
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
index 53e39e575..c05b9e0cd 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt
@@ -40,20 +40,25 @@ object InventoryUtils {
val chestName = if (guiChest is GuiChest) {
val chest = guiChest.inventorySlots as ContainerChest
chest.getInventoryName()
- } else {
- ""
- }
+ } else ""
return chestName
}
- fun ContainerChest.getInventoryName(): String {
- return this.lowerChestInventory.displayName.unformattedText.trim()
+ fun ContainerChest.getInventoryName() = this.lowerChestInventory.displayName.unformattedText.trim()
+
+ fun getItemsInOwnInventory(): MutableList<ItemStack> {
+ val list = mutableListOf<ItemStack>()
+ for (itemStack in Minecraft.getMinecraft().thePlayer.inventory.mainInventory) {
+ itemStack?.let {
+ list.add(it)
+ }
+ }
+
+ return list
}
fun countItemsInLowerInventory(predicate: (ItemStack) -> Boolean) =
- Minecraft.getMinecraft().thePlayer.inventory.mainInventory
- .filter { it != null && predicate(it) }
- .sumOf { it.stackSize }
+ getItemsInOwnInventory().filter { predicate(it) }.sumOf { it.stackSize }
fun getArmor(): Array<ItemStack?> =
Minecraft.getMinecraft().thePlayer.inventory.armorInventory
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
index 43799dc50..049caf3d1 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.utils
+import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.isRecombobulated
import at.hannibal2.skyhanni.utils.StringUtils.matchRegex
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import com.google.gson.GsonBuilder
@@ -28,15 +29,17 @@ object ItemUtils {
return list
}
+ // TODO change else janni is sad
fun isCoopSoulBound(stack: ItemStack): Boolean =
stack.getLore().any {
it == "§8§l* §8Co-op Soulbound §8§l*" || it == "§8§l* §8Soulbound §8§l*"
}
+ // TODO change else janni is sad
fun isSoulBound(stack: ItemStack): Boolean =
stack.getLore().any { it == "§8§l* §8Soulbound §8§l*" }
- fun isRecombobulated(stack: ItemStack): Boolean = stack.getLore().any { it.contains("§k") }//TODO use item api
+ fun isRecombobulated(stack: ItemStack) = stack.isRecombobulated()
fun isPet(name: String): Boolean = name.matchRegex("\\[Lvl (.*)] (.*)") && !listOf(
"Archer",
@@ -152,7 +155,7 @@ object ItemUtils {
val itemName = matcher.group("name")
if (!itemName.contains("§8x")) {
val amount = matcher.group("amount")?.replace(",", "")?.toInt() ?: 1
- val pair = Pair(itemName, amount)
+ val pair = Pair(itemName.trim(), amount)
itemAmountCache[input] = pair
return pair
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
index 921229e05..938a0326f 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
@@ -6,8 +6,10 @@ import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.features.dungeon.DungeonData
import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import at.hannibal2.skyhanni.utils.StringUtils.toDashlessUUID
+import io.github.moulberry.notenoughupdates.mixins.AccessorGuiEditSign
import io.github.moulberry.notenoughupdates.util.SkyBlockTime
import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.inventory.GuiEditSign
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.SharedMonsterAttributes
import net.minecraft.util.ChatComponentText
@@ -51,8 +53,6 @@ object LorenzUtils {
if (internalChat(DEBUG_PREFIX + message)) {
consoleLog("[Debug] $message")
}
- } else {
- consoleLog("[Debug] $message")
}
}
@@ -191,4 +191,11 @@ object LorenzUtils {
}
}
}
+
+ fun setTextIntoSign(text: String) {
+ val gui = Minecraft.getMinecraft().currentScreen
+ if (gui !is GuiEditSign) return
+ gui as AccessorGuiEditSign
+ gui.tileSign.signText[0] = ChatComponentText(text)
+ }
} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
index 1ce7c9e22..25d67bb07 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
@@ -21,15 +21,21 @@ object NEUItems {
private val recipesCache = mutableMapOf<String, Set<NeuRecipe>>()
fun getInternalName(itemName: String): String {
+ return getInternalNameOrNull(itemName) ?: throw Error("getInternalName is null for '$itemName'")
+ }
+
+ fun getInternalNameOrNull(itemName: String): String? {
if (itemNameCache.containsKey(itemName)) {
return itemNameCache[itemName]!!
}
- var internalName = ItemResolutionQuery.findInternalNameByDisplayName(itemName, false)
+ var internalName = ItemResolutionQuery.findInternalNameByDisplayName(itemName, false) ?: return null
+
// This fixes a NEU bug with §9Hay Bale (cosmetic item)
// TODO remove workaround when this is fixed in neu
if (internalName == "HAY_BALE") {
internalName = "HAY_BLOCK"
}
+
itemNameCache[itemName] = internalName
return internalName
}
@@ -41,6 +47,14 @@ object NEUItems {
.resolveInternalName() ?: ""
}
+ fun getPriceOrNull(internalName: String, useSellingPrice: Boolean = false): Double? {
+ val price = getPrice(internalName, useSellingPrice)
+ if (price == -1.0) {
+ return null
+ }
+ return price
+ }
+
fun getPrice(internalName: String, useSellingPrice: Boolean = false): Double {
val bazaarData = BazaarApi.getBazaarDataForInternalName(internalName)
bazaarData?.let {
@@ -82,7 +96,7 @@ object NEUItems {
fun getItemStack(internalName: String): ItemStack {
val stack = getItemStackOrNull(internalName)
if (stack == null) {
- val error = "ItemResolutionQuery returns null for internalName $internalName"
+ val error = "ItemResolutionQuery returns null for internalName '$internalName'"
LorenzUtils.error(error)
throw RuntimeException(error)
}
@@ -120,17 +134,17 @@ object NEUItems {
GlStateManager.popMatrix()
}
- fun getMultiplier(rawId: String, tryCount: Int = 0): Pair<String, Int> {
- if (multiplierCache.contains(rawId)) {
- return multiplierCache[rawId]!!
+ fun getMultiplier(internalName: String, tryCount: Int = 0): Pair<String, Int> {
+ if (multiplierCache.contains(internalName)) {
+ return multiplierCache[internalName]!!
}
if (tryCount == 10) {
- val message = "Error reading getMultiplier for item '$rawId'"
+ val message = "Error reading getMultiplier for item '$internalName'"
Error(message).printStackTrace()
LorenzUtils.error(message)
- return Pair(rawId, 1)
+ return Pair(internalName, 1)
}
- for (recipe in getRecipes(rawId)) {
+ for (recipe in getRecipes(internalName)) {
if (recipe !is CraftingRecipe) continue
val map = mutableMapOf<String, Int>()
@@ -138,26 +152,33 @@ object NEUItems {
val count = ingredient.count.toInt()
var internalItemId = ingredient.internalItemId
// ignore cactus green
- if (rawId == "ENCHANTED_CACTUS_GREEN") {
+ if (internalName == "ENCHANTED_CACTUS_GREEN") {
if (internalItemId == "INK_SACK-2") {
internalItemId = "CACTUS"
}
}
// ignore wheat in enchanted cookie
- if (rawId == "ENCHANTED_COOKIE") {
+ if (internalName == "ENCHANTED_COOKIE") {
if (internalItemId == "WHEAT") {
continue
}
}
// ignore golden carrot in enchanted golden carrot
- if (rawId == "ENCHANTED_GOLDEN_CARROT") {
+ if (internalName == "ENCHANTED_GOLDEN_CARROT") {
if (internalItemId == "GOLDEN_CARROT") {
continue
}
}
+ // ignore rabbit hide in leather
+ if (internalName == "LEATHER") {
+ if (internalItemId == "RABBIT_HIDE") {
+ continue
+ }
+ }
+
// println("")
// println("rawId: $rawId")
// println("internalItemId: $internalItemId")
@@ -171,15 +192,15 @@ object NEUItems {
return if (current.second > 1) {
val child = getMultiplier(id, tryCount + 1)
val result = Pair(child.first, child.second * current.second)
- multiplierCache[rawId] = result
+ multiplierCache[internalName] = result
result
} else {
- Pair(rawId, 1)
+ Pair(internalName, 1)
}
}
- val result = Pair(rawId, 1)
- multiplierCache[rawId] = result
+ val result = Pair(internalName, 1)
+ multiplierCache[internalName] = result
return result
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
index 397613f40..a3c86c0f4 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NumberUtil.kt
@@ -1,6 +1,5 @@
package at.hannibal2.skyhanni.utils
-import at.hannibal2.skyhanni.utils.NumberUtil.addSuffix
import java.text.NumberFormat
import java.util.*
import java.util.regex.Pattern
@@ -51,7 +50,8 @@ object NumberUtil {
if (value < 1000) return value.toString() //deal with easy case
val (divideBy, suffix) = suffixes.floorEntry(value)
val truncated = value / (divideBy / 10) //the number part of the output times 10
- val hasDecimal = truncated < 100 && truncated / 10.0 != (truncated / 10).toDouble()
+ val truncatedAt = if (suffix == "M") 1000 else 100
+ val hasDecimal = truncated < truncatedAt && truncated / 10.0 != (truncated / 10).toDouble()
return if (hasDecimal) (truncated / 10.0).toString() + suffix else (truncated / 10).toString() + suffix
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt
index 3819573c3..5089b4d82 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/OSUtils.kt
@@ -4,7 +4,9 @@ import net.minecraft.client.settings.KeyBinding
import org.lwjgl.input.Keyboard
import java.awt.Desktop
import java.awt.Toolkit
+import java.awt.datatransfer.DataFlavor
import java.awt.datatransfer.StringSelection
+import java.awt.datatransfer.UnsupportedFlavorException
import java.io.IOException
import java.net.URI
@@ -27,6 +29,16 @@ object OSUtils {
Toolkit.getDefaultToolkit().systemClipboard.setContents(StringSelection(text), null)
}
+ fun readFromClipboard(): String? {
+ val systemClipboard = Toolkit.getDefaultToolkit().systemClipboard ?: return null
+ try {
+ val data = systemClipboard.getData(DataFlavor.stringFlavor) ?: return null
+ return data.toString()
+ } catch (e: UnsupportedFlavorException) {
+ return null
+ }
+ }
+
fun KeyBinding.isActive() : Boolean {
if (!Keyboard.isCreated()) return false
try {
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
new file mode 100644
index 000000000..4229a80df
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockItemModifierUtils.kt
@@ -0,0 +1,283 @@
+package at.hannibal2.skyhanni.utils
+
+import at.hannibal2.skyhanni.features.misc.EstimatedItemValue
+import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import net.minecraft.item.ItemStack
+
+object SkyBlockItemModifierUtils {
+ private val drillPartTypes = listOf("drill_part_upgrade_module", "drill_part_engine", "drill_part_fuel_tank")
+
+ fun ItemStack.getHotPotatoCount(): Int {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes != "hot_potato_count") continue
+ return extraAttributes.getInteger(attributes)
+ }
+ }
+ return 0
+ }
+
+ fun ItemStack.getFarmingForDummiesCount(): Int {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes != "farming_for_dummies_count") continue
+ return extraAttributes.getInteger(attributes)
+ }
+ }
+ return 0
+ }
+
+ fun ItemStack.getSilexCount(): Int {
+ var silexTier = 0
+ for ((name, amount) in getEnchantments()) {
+ if (name == "efficiency") {
+ if (amount > 5) {
+ silexTier = amount - 5
+ }
+ }
+ }
+
+ if (getInternalName() == "STONK_PICKAXE") {
+ silexTier--
+ }
+
+ return silexTier
+ }
+
+ fun ItemStack.getTransmissionTunerCount(): Int {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes != "tuned_transmission") continue
+ return extraAttributes.getInteger(attributes)
+ }
+ }
+ return 0
+ }
+
+ fun ItemStack.getManaDisintegrators(): Int {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes != "mana_disintegrator_count") continue
+ return extraAttributes.getInteger(attributes)
+ }
+ }
+ return 0
+ }
+
+ fun ItemStack.getMasterStars(): Int {
+ val stars = mapOf(
+ "➊" to 1,
+ "➋" to 2,
+ "➌" to 3,
+ "➍" to 4,
+ "➎" to 5,
+ )
+ val itemName = name!!
+ for ((icon, number) in stars) {
+ if (itemName.endsWith(icon)) {
+ return number
+ }
+ }
+
+ return 0
+ }
+
+ fun ItemStack.getDrillUpgrades(): List<String> {
+ val list = mutableListOf<String>()
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes in drillPartTypes) {
+ val upgradeItem = extraAttributes.getString(attributes)
+ list.add(upgradeItem.uppercase())
+ }
+ }
+ }
+
+ return list
+ }
+
+ fun ItemStack.getPowerScroll(): String? {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes == "power_ability_scroll") {
+ return extraAttributes.getString(attributes)
+ }
+ }
+ }
+
+ return null
+ }
+
+ fun ItemStack.getAbilityScrolls(): List<String> {
+ val list = mutableListOf<String>()
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes == "ability_scroll") {
+
+ val tagList = extraAttributes.getTagList(attributes, 8)
+ for (i in 0..3) {
+ val text = tagList.get(i).toString()
+ if (text == "END") break
+ var internalName = text.replace("\"", "")
+ list.add(internalName)
+ }
+ }
+ }
+ }
+
+ return list
+ }
+
+ fun ItemStack.getReforgeName(): String? {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes != "modifier") continue
+ return extraAttributes.getString(attributes)
+ }
+ }
+ return null
+ }
+
+ fun ItemStack.isRecombobulated(): Boolean {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ return extraAttributes.hasKey("rarity_upgrades")
+ }
+
+ return false
+ }
+
+ fun ItemStack.hasJalapenoBook(): Boolean {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ return extraAttributes.hasKey("jalapeno_count")
+ }
+
+ return false
+ }
+
+ fun ItemStack.hasEtherwarp(): Boolean {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ return extraAttributes.hasKey("ethermerge")
+ }
+
+ return false
+ }
+
+ fun ItemStack.hasWoodSingularity(): Boolean {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ return extraAttributes.hasKey("wood_singularity_count")
+ }
+
+ return false
+ }
+
+ fun ItemStack.hasArtOfWar(): Boolean {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ return extraAttributes.hasKey("art_of_war_count")
+ }
+
+ return false
+ }
+
+ // TODO untested
+ fun ItemStack.hasBookOfStats(): Boolean {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ return extraAttributes.hasKey("stats_book")
+ }
+
+ return false
+ }
+
+ fun ItemStack.hasArtOfPiece(): Boolean {
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ return extraAttributes.hasKey("artOfPeaceApplied")
+ }
+
+ return false
+ }
+
+ fun ItemStack.getEnchantments(): Map<String, Int> {
+ val map = mutableMapOf<String, Int>()
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes != "enchantments") continue
+ val enchantments = extraAttributes.getCompoundTag(attributes)
+ for (key in enchantments.keySet) {
+ map[key] = enchantments.getInteger(key)
+ }
+ }
+ }
+ return map
+ }
+
+ fun ItemStack.getGemstones(): List<EstimatedItemValue.GemstoneSlot> {
+ val list = mutableListOf<EstimatedItemValue.GemstoneSlot>()
+ for (tags in tagCompound.keySet) {
+ if (tags != "ExtraAttributes") continue
+ val extraAttributes = tagCompound.getCompoundTag(tags)
+ for (attributes in extraAttributes.keySet) {
+ if (attributes != "gems") continue
+ val gemstones = extraAttributes.getCompoundTag(attributes)
+ for (key in gemstones.keySet) {
+ if (key.endsWith("_gem")) continue
+ if (key == "unlocked_slots") continue
+ val value = gemstones.getString(key)
+ if (value == "") continue
+
+ val rawType = key.split("_")[0]
+ val type = EstimatedItemValue.GemstoneType.getByName(rawType)
+
+ val tier = EstimatedItemValue.GemstoneTier.getByName(value)
+ if (tier == null) {
+ LorenzUtils.debug("Gemstone tier is null for item $name: ('$key' = '$value')")
+ continue
+ }
+ if (type != null) {
+ list.add(EstimatedItemValue.GemstoneSlot(type, tier))
+ } else {
+ val newKey = gemstones.getString(key + "_gem")
+ val newType = EstimatedItemValue.GemstoneType.getByName(newKey)
+ if (newType == null) {
+ LorenzUtils.debug("Gemstone type is null for item $name: ('$newKey' with '$key' = '$value')")
+ continue
+ }
+ list.add(EstimatedItemValue.GemstoneSlot(newType, tier))
+ }
+ }
+ }
+ }
+ return list
+ }
+} \ No newline at end of file