aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/Features.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt221
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt21
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt21
6 files changed, 289 insertions, 10 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
index 998185755..3266af83c 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
@@ -23,6 +23,7 @@ import at.hannibal2.skyhanni.features.event.diana.GriffinBurrowHelper;
import at.hannibal2.skyhanni.features.event.diana.GriffinBurrowParticleFinder;
import at.hannibal2.skyhanni.features.event.diana.SoopyGuessBurrow;
import at.hannibal2.skyhanni.features.fishing.*;
+import at.hannibal2.skyhanni.features.garden.GardenVisitorFeatures;
import at.hannibal2.skyhanni.features.garden.SkyMartBestProfit;
import at.hannibal2.skyhanni.features.inventory.*;
import at.hannibal2.skyhanni.features.itemabilities.FireVeilWandParticles;
@@ -197,6 +198,7 @@ public class SkyHanniMod {
loadModule(new ParticleHider());
loadModule(new MiscFeatures());
loadModule(new SkyMartBestProfit());
+ loadModule(new GardenVisitorFeatures());
Commands.INSTANCE.init();
diff --git a/src/main/java/at/hannibal2/skyhanni/config/Features.java b/src/main/java/at/hannibal2/skyhanni/config/Features.java
index 633bc66c6..13ebf5106 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/Features.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/Features.java
@@ -141,6 +141,11 @@ public class Features extends Config {
editOverlay(activeConfigCategory, 200, 16, garden.skyMartCopperPricePos);
return;
}
+
+ if (runnableId.equals("visitorHelper")) {
+ editOverlay(activeConfigCategory, 200, 16, garden.visitorHelperPos);
+ return;
+ }
}
@Expose
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 9dec32d73..d5344900b 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
@@ -22,4 +22,33 @@ public class Garden {
@ConfigEditorButton(runnableId = "skyMartCopperPrice", buttonText = "Edit")
@ConfigAccordionId(id = 0)
public Position skyMartCopperPricePos = new Position(44, -108, false, true);
+
+ @Expose
+ @ConfigOption(name = "Visitor Helper", desc = "")
+ @ConfigEditorAccordion(id = 1)
+ public boolean visitorHelper = false;
+
+ @Expose
+ @ConfigOption(name = "Visitor Display", desc = "Show all items needed for the visitors.")
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean visitorHelperDisplay = true;
+
+ @Expose
+ @ConfigOption(name = "Visitor Helper Position", desc = "")
+ @ConfigEditorButton(runnableId = "visitorHelper", buttonText = "Edit")
+ @ConfigAccordionId(id = 1)
+ public Position visitorHelperPos = new Position(0, 0, false, true);
+
+ @Expose
+ @ConfigOption(name = "Highlight Ready", desc = "Highlight the visitor when the required items are in the inventory.")
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean visitorHelperHighlightReady = true;
+
+ @Expose
+ @ConfigOption(name = "Show Price", desc = "Show the bazaar price of the items required for the visitors.")
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 1)
+ public boolean visitorHelperShowPrice = true;
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt
new file mode 100644
index 000000000..513c91425
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenVisitorFeatures.kt
@@ -0,0 +1,221 @@
+package at.hannibal2.skyhanni.features.garden
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.events.InventoryOpenEvent
+import at.hannibal2.skyhanni.events.PacketEvent
+import at.hannibal2.skyhanni.events.withAlpha
+import at.hannibal2.skyhanni.mixins.hooks.RenderLivingEntityHelper
+import at.hannibal2.skyhanni.utils.*
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import net.minecraft.client.Minecraft
+import net.minecraft.entity.EntityLivingBase
+import net.minecraft.network.play.client.C02PacketUseEntity
+import net.minecraft.network.play.server.S13PacketDestroyEntities
+import net.minecraftforge.client.event.RenderGameOverlayEvent
+import net.minecraftforge.event.entity.player.ItemTooltipEvent
+import net.minecraftforge.fml.common.eventhandler.EventPriority
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+import java.util.regex.Pattern
+
+class GardenVisitorFeatures {
+
+ private val pattern = Pattern.compile("(.*)§8x(.*)")
+ private val visitors = mutableMapOf<String, Visitor>()
+ private val display = mutableListOf<String>()
+ private var lastClickedNpc = 0
+ private var nearby = false
+
+ @SubscribeEvent
+ fun onChatPacket(event: InventoryOpenEvent) {
+ if (!isEnabled()) return
+ if (!SkyHanniMod.feature.garden.visitorHelperDisplay &&
+ !SkyHanniMod.feature.garden.visitorHelperHighlightReady
+ ) return
+
+ val npcItem = event.inventory.items[13] ?: return
+ val lore = npcItem.getLore()
+ var isVisitor = false
+ if (lore.size == 4) {
+ val line = lore[3]
+ if (line.startsWith("§7Offers Accepted: §a")) {
+ isVisitor = true
+ }
+ }
+ if (!isVisitor) return
+
+ val offerItem = event.inventory.items[29] ?: return
+ if (offerItem.name != "§aAccept Offer") return
+
+ val visitor = Visitor(lastClickedNpc)
+ for (line in offerItem.getLore()) {
+ if (line == "§7Items Required:") continue
+ if (line.isEmpty()) break
+
+ val matcher = pattern.matcher(line)
+ if (matcher.matches()) {
+ val itemName = matcher.group(1).trim()
+ val amount = matcher.group(2).toInt()
+ visitor.items[itemName] = amount
+ }
+ }
+
+ val visitorName = npcItem.name!!
+ visitors[visitorName] = visitor
+
+ update()
+ }
+
+ private fun update() {
+ display.clear()
+
+ val requiredItems = mutableMapOf<String, Int>()
+ for ((_, visitor) in visitors) {
+ for ((itemName, amount) in visitor.items) {
+ val old = requiredItems.getOrDefault(itemName, 0)
+ requiredItems[itemName] = old + amount
+ }
+ }
+ if (requiredItems.isEmpty()) return
+
+ display.add("Visitors need:")
+ for ((name, amount) in requiredItems) {
+ display.add(" -$name §8x$amount")
+ }
+ }
+
+ var tick = 0
+
+ @SubscribeEvent(priority = EventPriority.LOW)
+ fun onTooltip(event: ItemTooltipEvent) {
+ if (!isEnabled()) return
+ if (!nearby) return
+ if (!SkyHanniMod.feature.garden.visitorHelperShowPrice) return
+
+ val name = event.itemStack.name ?: return
+ if (name != "§aAccept Offer") return
+
+ var i = 0
+ val list = event.toolTip
+ var totalPrice = 0.0
+ var amountDifferentItems = 0
+ for (l in list) {
+ val line = l.substring(4)
+ if (line == "") {
+ if (amountDifferentItems > 1) {
+ val format = NumberUtil.format(totalPrice)
+ list[1] = list[1] + "$line §f(§6$format§f)"
+ }
+ break
+ }
+
+ if (i > 1) {
+ val matcher = pattern.matcher(line)
+ if (matcher.matches()) {
+ val itemName = matcher.group(1).trim()
+ val amount = matcher.group(2).toInt()
+
+ val internalName = NEUItems.getInternalNameByName(itemName)
+ val auctionManager = NotEnoughUpdates.INSTANCE.manager.auctionManager
+ val lowestBin = auctionManager.getBazaarOrBin(internalName, false)
+ val price = lowestBin * amount
+ totalPrice += price
+ val format = NumberUtil.format(price)
+ list[i] = "$line §f(§6$format§f)"
+ amountDifferentItems++
+ }
+ }
+ i++
+ }
+ }
+
+ @SubscribeEvent
+ fun onTick(event: TickEvent.ClientTickEvent) {
+ if (!isEnabled()) return
+ if (!SkyHanniMod.feature.garden.visitorHelperDisplay &&
+ !SkyHanniMod.feature.garden.visitorHelperHighlightReady &&
+ !SkyHanniMod.feature.garden.visitorHelperShowPrice
+ ) return
+
+ if (tick++ % 60 == 0) {
+ check()
+ }
+ }
+
+ private fun check() {
+ nearby = LocationUtils.playerLocation().distance(LorenzVec(8.4, 72.0, -14.1)) < 10
+
+ if (nearby && SkyHanniMod.feature.garden.visitorHelperHighlightReady) {
+ checkVisitorsReady()
+ }
+ }
+
+ private fun checkVisitorsReady() {
+ for (visitor in visitors.values) {
+ var ready = true
+ for ((name, need) in visitor.items) {
+ val cleanName = name.removeColor()
+ val having = InventoryUtils.countItemsInLowerInventory { it.name?.contains(cleanName) ?: false }
+ if (having < need) {
+ ready = false
+ }
+ }
+
+ if (ready) {
+ val world = Minecraft.getMinecraft().theWorld
+ val entity = world.getEntityByID(visitor.entityId)
+ if (entity is EntityLivingBase) {
+ val color = LorenzColor.GREEN.toColor().withAlpha(120)
+ RenderLivingEntityHelper.setEntityColor(entity, color)
+ { SkyHanniMod.feature.garden.visitorHelperHighlightReady }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onReceiveEvent(event: PacketEvent.ReceiveEvent) {
+ val packet = event.packet
+ if (packet is S13PacketDestroyEntities) {
+ for (entityID in packet.entityIDs) {
+ for ((name, visitor) in visitors.toMutableMap()) {
+ if (visitor.entityId == entityID) {
+ visitors.remove(name)
+ update()
+ }
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onSendEvent(event: PacketEvent.SendEvent) {
+ val packet = event.packet
+ if (packet is C02PacketUseEntity) {
+ val theWorld = Minecraft.getMinecraft().theWorld
+ val entity = packet.getEntityFromWorld(theWorld)
+ val entityId = entity.entityId
+
+ lastClickedNpc = entityId
+ }
+ }
+
+ @SubscribeEvent
+ fun onRenderOverlay(event: RenderGameOverlayEvent.Post) {
+ if (event.type != RenderGameOverlayEvent.ElementType.ALL) return
+ if (!isEnabled()) return
+ if (!SkyHanniMod.feature.garden.visitorHelperDisplay) return
+ if (!nearby) return
+
+ SkyHanniMod.feature.garden.visitorHelperPos.renderStrings(display)
+ }
+
+ class Visitor(val entityId: Int, val items: MutableMap<String, Int> = mutableMapOf())
+
+ private fun isEnabled() = LorenzUtils.inSkyBlock && LorenzUtils.skyBlockIsland == IslandType.GARDEN
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt
index 8e9cc3dfa..369765c5d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/SkyMartBestProfit.kt
@@ -24,9 +24,7 @@ class SkyMartBestProfit {
@SubscribeEvent
fun onChatPacket(event: InventoryOpenEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!SkyHanniMod.feature.garden.skyMartCopperPrice) return
- if (LorenzUtils.skyBlockIsland != IslandType.GARDEN) return
+ if (!isEnabled()) return
val inventory = event.inventory
if (inventory.title != "SkyMart") return
@@ -55,14 +53,14 @@ class SkyMartBestProfit {
name = "§9Sunder I"
}
- val pair = Pair("$name§f:", "§6§l$perFormat §f(§6$priceFormat coins §f/ §c$amountFormat copper§f)")
+ val pair = Pair("$name§f:", "§6§l$perFormat §f(§6$priceFormat §f/ §c$amountFormat copper§f)")
priceMap[pair] = factor
}
}
display.clear()
- display.add("Coins per §ccopper")
+ display.add("Coins per §ccopper§f:")
display.add(" ")
val keys = priceMap.sortedDesc().keys
@@ -85,10 +83,13 @@ class SkyMartBestProfit {
@SubscribeEvent
fun onBackgroundDraw(event: GuiScreenEvent.BackgroundDrawnEvent) {
- if (!LorenzUtils.inSkyBlock) return
- if (!SkyHanniMod.feature.garden.skyMartCopperPrice) return
- if (LorenzUtils.skyBlockIsland != IslandType.GARDEN) return
-
- SkyHanniMod.feature.garden.skyMartCopperPricePos.renderStrings(display)
+ if (isEnabled()) {
+ SkyHanniMod.feature.garden.skyMartCopperPricePos.renderStrings(display)
+ }
}
+
+ private fun isEnabled() =
+ LorenzUtils.inSkyBlock &&
+ SkyHanniMod.feature.garden.skyMartCopperPrice &&
+ LorenzUtils.skyBlockIsland == IslandType.GARDEN
} \ 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 46c9c6fea..8c127fac8 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.utils
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
import io.github.moulberry.notenoughupdates.util.Utils
import net.minecraft.client.renderer.GlStateManager
@@ -9,6 +10,26 @@ import net.minecraft.item.ItemStack
object NEUItems {
private val itemCache = mutableMapOf<String, ItemStack>()
+ private val itemNameCache = mutableMapOf<String, String>() // display name -> internal name
+
+ fun getInternalNameByName(rawName: String): String? {
+ val itemName = rawName.removeColor()
+ if (itemNameCache.containsKey(itemName)) {
+ return itemNameCache[itemName]
+ }
+ val manager = NotEnoughUpdates.INSTANCE.manager
+ for ((internalId, b) in manager.itemInformation) {
+ if (b.has("displayname")) {
+ val name = b.get("displayname").asString
+ if (name.contains(itemName)) {
+ itemNameCache[itemName] = internalId
+ return internalId
+ }
+ }
+ }
+
+ return null
+ }
fun readItemFromRepo(internalName: String): ItemStack {
if (itemCache.contains(internalName)) {