aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/FirstConfigLoadedEvent.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt88
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt304
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt165
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/DojoQuest.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/FetchQuest.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/MiniBossQuest.kt6
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/ProgressQuest.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/Quest.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/QuestCategory.kt11
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/QuestState.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/RescueMissionQuest.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/TrophyFishQuest.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/UnknownQuest.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/CrimsonMiniBoss.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt91
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt12
20 files changed, 750 insertions, 1 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
index f99a0ee2b..3297cdc3e 100644
--- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
+++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java
@@ -5,6 +5,7 @@ import at.hannibal2.skyhanni.config.Features;
import at.hannibal2.skyhanni.config.commands.Commands;
import at.hannibal2.skyhanni.data.*;
import at.hannibal2.skyhanni.data.repo.RepoManager;
+import at.hannibal2.skyhanni.events.FirstConfigLoadedEvent;
import at.hannibal2.skyhanni.features.anvil.AnvilCombineHelper;
import at.hannibal2.skyhanni.features.bazaar.*;
import at.hannibal2.skyhanni.features.bingo.CompactBingoChat;
@@ -30,6 +31,7 @@ import at.hannibal2.skyhanni.features.minion.MinionFeatures;
import at.hannibal2.skyhanni.features.misc.*;
import at.hannibal2.skyhanni.features.nether.MilleniaAgedBlazeColor;
import at.hannibal2.skyhanni.features.nether.ashfang.*;
+import at.hannibal2.skyhanni.features.nether.reputationhelper.CrimsonIsleReputationHelper;
import at.hannibal2.skyhanni.features.slayer.EndermanSlayerBeacon;
import at.hannibal2.skyhanni.features.slayer.HideMobNames;
import at.hannibal2.skyhanni.features.slayer.HighlightSlayerMiniboss;
@@ -171,6 +173,8 @@ public class SkyHanniMod {
loadModule(new BrewingStandOverlay());
loadModule(new BazaarUpdateTimer());
+ loadModule(new CrimsonIsleReputationHelper(this));
+
Commands.INSTANCE.init();
loadModule(new LorenzTest());
@@ -178,6 +182,8 @@ public class SkyHanniMod {
configManager = new ConfigManager();
configManager.firstLoad();
+ new FirstConfigLoadedEvent().postAndCatch();
+
MinecraftConsoleFilter.Companion.initLogging();
Runtime.getRuntime().addShutdownHook(new Thread(configManager::saveConfig));
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java b/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
index b3d138269..7a26ace3b 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Hidden.java
@@ -2,7 +2,9 @@ package at.hannibal2.skyhanni.config.features;
import com.google.gson.annotations.Expose;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
public class Hidden {
@@ -18,4 +20,13 @@ public class Hidden {
@Expose
public Map<String, String> minionName = new HashMap<>();
+
+ @Expose
+ public List<String> crimsonIsleQuests = new ArrayList<>();
+
+ @Expose
+ public int crimsonIsleLatestTrophyFishInInventory = 0;
+
+ @Expose
+ public List<String> crimsonIsleMiniBossesDoneToday = new ArrayList<>();
}
diff --git a/src/main/java/at/hannibal2/skyhanni/events/FirstConfigLoadedEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/FirstConfigLoadedEvent.kt
new file mode 100644
index 000000000..0213ae835
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/events/FirstConfigLoadedEvent.kt
@@ -0,0 +1,3 @@
+package at.hannibal2.skyhanni.events
+
+class FirstConfigLoadedEvent: LorenzEvent() \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt
index f2c610e04..06fbc93d6 100644
--- a/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt
+++ b/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt
@@ -5,7 +5,7 @@ import com.google.gson.Gson
import com.google.gson.JsonObject
import java.io.File
-class RepositoryReloadEvent(val repoLocation: File, val gson: Gson): LorenzEvent() {
+class RepositoryReloadEvent(private val repoLocation: File, val gson: Gson): LorenzEvent() {
fun getConstant(constant: String): JsonObject? {
return RepoUtils.getConstant(repoLocation, constant, gson)
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt
new file mode 100644
index 000000000..c86c968d1
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/CrimsonIsleReputationHelper.kt
@@ -0,0 +1,88 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.HyPixelData
+import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.events.RepositoryReloadEvent
+import at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.DailyQuestHelper
+import at.hannibal2.skyhanni.features.nether.reputationhelper.miniboss.DailyMiniBossHelper
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings
+import com.google.gson.JsonObject
+import net.minecraftforge.client.event.RenderGameOverlayEvent
+import net.minecraftforge.fml.common.eventhandler.EventPriority
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+
+class CrimsonIsleReputationHelper(skyHanniMod: SkyHanniMod) {
+
+ val questHelper = DailyQuestHelper(this)
+ val miniBossHelper = DailyMiniBossHelper(this)
+
+ var repoData: JsonObject = JsonObject()
+
+ private val display = mutableListOf<String>()
+ private var dirty = true
+ private var loaded = false
+
+ init {
+ skyHanniMod.loadModule(questHelper)
+ skyHanniMod.loadModule(miniBossHelper)
+ }
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ repoData = event.getConstant("CrimsonIsleReputation")!!
+ if (!loaded) {
+ loaded = true
+
+ miniBossHelper.init()
+
+ questHelper.loadConfig()
+ miniBossHelper.loadConfig()
+ }
+ }
+
+ @SubscribeEvent
+ fun onTick(event: TickEvent.ClientTickEvent) {
+ if (!HyPixelData.skyBlock) return
+ if (LorenzUtils.skyBlockIsland != IslandType.CRIMSON_ISLE) return
+ if (dirty) {
+ dirty = false
+ updateRender()
+ }
+ }
+
+ private fun updateRender() {
+ display.clear()
+
+ display.add("Reputation Helper:")
+ questHelper.render(display)
+ miniBossHelper.render(display)
+ }
+
+ @SubscribeEvent(priority = EventPriority.LOWEST)
+ fun renderOverlay(event: RenderGameOverlayEvent.Post) {
+ if (event.type != RenderGameOverlayEvent.ElementType.ALL) return
+
+ if (!HyPixelData.skyBlock) return
+ if (LorenzUtils.skyBlockIsland != IslandType.CRIMSON_ISLE) return
+
+ SkyHanniMod.feature.dev.debugPos.renderStrings(display)
+ }
+
+ fun update() {
+ dirty = true
+
+ questHelper.saveConfig()
+ miniBossHelper.saveConfig()
+ }
+
+ fun reset() {
+ LorenzUtils.chat("§e[SkyHanni] Reset Reputation Helper.")
+
+ questHelper.reset()
+ miniBossHelper.reset()
+ update()
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt
new file mode 100644
index 000000000..463cd3347
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/DailyQuestHelper.kt
@@ -0,0 +1,304 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.HyPixelData
+import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.events.GuiContainerEvent
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.events.ProfileApiDataLoadedEvent
+import at.hannibal2.skyhanni.features.nether.reputationhelper.CrimsonIsleReputationHelper
+import at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest.*
+import at.hannibal2.skyhanni.features.nether.reputationhelper.miniboss.CrimsonMiniBoss
+import at.hannibal2.skyhanni.utils.InventoryUtils.getInventoryName
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.ItemUtils.name
+import at.hannibal2.skyhanni.utils.LorenzColor
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.RenderUtils.highlight
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.inventory.GuiChest
+import net.minecraft.inventory.ContainerChest
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+
+class DailyQuestHelper(val reputationHelper: CrimsonIsleReputationHelper) {
+
+ private var tick = 0
+ private val loader = QuestLoader(this)
+
+ val quests = mutableListOf<Quest>()
+ private val sacksCache = mutableMapOf<String, Long>()
+ private var latestTrophyFishInInventory = 0
+
+ @SubscribeEvent
+ fun onTick(event: TickEvent.ClientTickEvent) {
+ if (!HyPixelData.skyBlock) return
+ if (LorenzUtils.skyBlockIsland != IslandType.CRIMSON_ISLE) return
+ tick++
+ if (tick % 20 == 0) {
+ loader.checkInventory()
+ checkInventory()
+ }
+
+ if (tick % 60 == 0) {
+ checkInventoryForFetchItem()
+ loader.loadFromTabList()
+
+ if (quests.size > 5) {
+ reputationHelper.reset()
+ }
+ }
+ }
+
+ private fun checkInventory() {
+ val fishQuest = getQuest<TrophyFishQuest>() ?: return
+ if (fishQuest.state != QuestState.ACCEPTED && fishQuest.state != QuestState.READY_TO_COLLECT) return
+
+ val fishName = fishQuest.fishName
+ var currentlyInInventory = 0
+ val player = Minecraft.getMinecraft().thePlayer
+ for (stack in player.inventory.mainInventory) {
+ if (stack == null) continue
+ val name = stack.name ?: continue
+ if (name.contains(fishName)) {
+ currentlyInInventory += stack.stackSize
+ }
+ }
+ val diff = currentlyInInventory - latestTrophyFishInInventory
+ if (diff < 1) return
+ LorenzUtils.debug("diff: $diff")
+ latestTrophyFishInInventory = currentlyInInventory
+
+ updateProcessQuest(fishQuest, fishQuest.haveAmount + diff)
+ }
+
+ fun update() {
+ reputationHelper.update()
+ }
+
+ @SubscribeEvent
+ fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) {
+ if (!HyPixelData.skyBlock) return
+ if (LorenzUtils.skyBlockIsland != IslandType.CRIMSON_ISLE) return
+ if (event.gui !is GuiChest) return
+ val chest = event.gui.inventorySlots as ContainerChest
+ val chestName = chest.getInventoryName()
+
+ if (chestName == "Challenges") {
+ if (LorenzUtils.skyBlockArea != "Dojo") return
+ val dojoQuest = getQuest<DojoQuest>() ?: return
+ if (dojoQuest.state != QuestState.ACCEPTED) return
+
+ for (slot in chest.inventorySlots) {
+ if (slot == null) continue
+ if (slot.slotNumber != slot.slotIndex) continue
+ val stack = slot.stack ?: continue
+ val itemName = stack.name ?: continue
+
+ if (itemName.contains(dojoQuest.dojoName)) {
+ slot highlight LorenzColor.AQUA
+ }
+ }
+ }
+ if (chestName == "Sack of Sacks") {
+ val fetchQuest = getQuest<FetchQuest>() ?: return
+ if (fetchQuest.state != QuestState.ACCEPTED) return
+
+ val fetchItem = fetchQuest.itemName
+ for (slot in chest.inventorySlots) {
+ if (slot == null) continue
+ if (slot.slotNumber != slot.slotIndex) continue
+ val stack = slot.stack ?: continue
+ if (stack.getLore().any { it.contains(fetchItem) }) {
+ slot highlight LorenzColor.AQUA
+ }
+ }
+ }
+ if (chestName.contains("Nether Sack")) {
+ val fetchQuest = getQuest<FetchQuest>() ?: return
+ if (fetchQuest.state != QuestState.ACCEPTED) return
+
+ val fetchItem = fetchQuest.itemName
+ for (slot in chest.inventorySlots) {
+ if (slot == null) continue
+ if (slot.slotNumber != slot.slotIndex) continue
+ val stack = slot.stack ?: continue
+ val itemName = stack.name ?: continue
+
+ if (itemName.contains(fetchItem)) {
+ slot highlight LorenzColor.AQUA
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (!HyPixelData.skyBlock) return
+ if (LorenzUtils.skyBlockIsland != IslandType.CRIMSON_ISLE) return
+
+ val message = event.message
+ if (message == "§aYou completed your Dojo quest! Visit the Town Board to claim the rewards.") {
+ val dojoQuest = getQuest<DojoQuest>() ?: return
+ dojoQuest.state = QuestState.READY_TO_COLLECT
+ update()
+ }
+ if (message == "§aYou completed your rescue quest! Visit the Town Board to claim the rewards,") {
+ val rescueMissionQuest = getQuest<RescueMissionQuest>() ?: return
+ rescueMissionQuest.state = QuestState.READY_TO_COLLECT
+ update()
+ }
+ }
+
+ private inline fun <reified T : Quest> getQuest() = quests.filterIsInstance<T>().firstOrNull()
+
+ private fun checkInventoryForFetchItem() {
+ val fetchQuest = getQuest<FetchQuest>() ?: return
+ if (fetchQuest.state != QuestState.ACCEPTED && fetchQuest.state != QuestState.READY_TO_COLLECT) return
+
+ val itemName = fetchQuest.itemName
+
+ val player = Minecraft.getMinecraft().thePlayer
+ var count = 0
+ for (stack in player.inventory.mainInventory) {
+ if (stack == null) continue
+ val name = stack.name ?: continue
+ if (name.contains(itemName)) {
+ count += stack.stackSize
+ }
+ }
+ updateProcessQuest(fetchQuest, count)
+ }
+
+ private fun updateProcessQuest(
+ quest: ProgressQuest,
+ newAmount: Int
+ ) {
+ var count = newAmount
+ val needAmount = quest.needAmount
+ if (count > needAmount) {
+ count = needAmount
+ }
+ if (quest.haveAmount == count) return
+
+ quest.haveAmount = count
+ quest.state = if (count == needAmount) QuestState.READY_TO_COLLECT else QuestState.ACCEPTED
+ update()
+ }
+
+ @SubscribeEvent
+ fun onProfileDataLoad(event: ProfileApiDataLoadedEvent) {
+ val profileData = event.profileData
+ val sacks = profileData["sacks_counts"]?.asJsonObject ?: return
+
+ sacksCache.clear()
+
+ for ((name, v) in sacks.entrySet()) {
+ val amount = v.asLong
+ sacksCache[name] = amount
+ }
+ update()
+ }
+
+ fun render(display: MutableList<String>) {
+ val done = quests.count { it.state == QuestState.COLLECTED }
+// val sneaking = Minecraft.getMinecraft().thePlayer.isSneaking
+// if (done != 5 || sneaking) {
+ if (done != 5) {
+ display.add("")
+ display.add("Daily Quests ($done/5 collected)")
+ for (quest in quests) {
+// if (!sneaking) {
+// if (quest.state == QuestState.COLLECTED) {
+// continue
+// }
+// }
+ display.add(renderQuest(quest))
+ }
+ }
+ }
+
+ private fun renderQuest(quest: Quest): String {
+ val type = quest.category.displayName
+ val state = quest.state.displayName
+ val stateColor = quest.state.color
+ val displayName = quest.displayName
+
+ val multipleText = if (quest is ProgressQuest && quest.state != QuestState.COLLECTED) {
+ val haveAmount = quest.haveAmount
+ val needAmount = quest.needAmount
+ " §e$haveAmount§8/§e$needAmount"
+ } else {
+ ""
+ }
+
+ val sacksText = if (quest is FetchQuest && quest.state != QuestState.COLLECTED) {
+ val name = quest.itemName.uppercase()
+ val amount = sacksCache.getOrDefault(name, 0)
+ val needAmount = quest.needAmount
+ val amountFormat = LorenzUtils.formatInteger(amount)
+ val color = if (amount >= needAmount) {
+ "§a"
+ } else {
+ "§c"
+ }
+ " §f($color$amountFormat §fin sacks)"
+ } else {
+ ""
+ }
+
+ val stateText = if (quest !is UnknownQuest) {
+ "$stateColor[$state] §f"
+ } else {
+ ""
+ }
+
+ return "$stateText$type: §f$displayName$multipleText$sacksText"
+ }
+
+ fun finishMiniBoss(miniBoss: CrimsonMiniBoss) {
+ val miniBossQuest = getQuest<MiniBossQuest>() ?: return
+ if (miniBossQuest.miniBoss == miniBoss) {
+ if (miniBossQuest.state == QuestState.READY_TO_COLLECT) {
+ miniBossQuest.state = QuestState.COLLECTED
+ updateProcessQuest(miniBossQuest, miniBossQuest.haveAmount + 1)
+ }
+ }
+ }
+
+ fun reset() {
+ quests.clear()
+ latestTrophyFishInInventory = 0
+ }
+
+ fun loadConfig() {
+ loader.loadConfig()
+ }
+
+ fun saveConfig() {
+ SkyHanniMod.feature.hidden.crimsonIsleQuests.clear()
+ for (quest in quests) {
+ val builder = StringBuilder()
+ val internalName = quest.internalName
+ builder.append(internalName)
+ builder.append(":")
+ val state = quest.state
+ builder.append(state)
+
+ if (quest is ProgressQuest) {
+ val need = quest.needAmount
+ val have = quest.haveAmount
+
+ builder.append(":")
+ builder.append(need)
+ builder.append(":")
+ builder.append(have)
+ } else {
+ builder.append(":0")
+ }
+ SkyHanniMod.feature.hidden.crimsonIsleQuests.add(builder.toString())
+ }
+
+ SkyHanniMod.feature.hidden.crimsonIsleLatestTrophyFishInInventory = latestTrophyFishInInventory
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt
new file mode 100644
index 000000000..b4a8e4200
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/QuestLoader.kt
@@ -0,0 +1,165 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest.*
+import at.hannibal2.skyhanni.utils.InventoryUtils.getInventoryName
+import at.hannibal2.skyhanni.utils.ItemUtils.getLore
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import at.hannibal2.skyhanni.utils.TabListUtils
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.inventory.GuiChest
+import net.minecraft.inventory.ContainerChest
+
+class QuestLoader(val dailyQuestHelper: DailyQuestHelper) {
+
+ fun loadFromTabList() {
+ var i = -1
+ for (line in TabListUtils.getTabList()) {
+ if (line.contains("Faction Quests:")) {
+ i = 0
+ continue
+ }
+ if (i == -1) continue
+
+ i++
+ readQuest(line)
+ if (i == 5) {
+ break
+ }
+ }
+ }
+
+ private fun readQuest(line: String) {
+ var text = line.substring(3)
+ val green = text.startsWith("§a")
+ text = text.substring(2)
+
+ val amount: Int
+ val name: String
+ if (text.contains(" §r§8x")) {
+ val split = text.split(" §r§8x")
+ name = split[0]
+ amount = split[1].toInt()
+ } else {
+ name = text
+ amount = 1
+ }
+
+ checkQuest(name, green, amount)
+ }
+
+ private fun checkQuest(name: String, green: Boolean, needAmount: Int) {
+ val oldQuest = getQuestByName(name)
+ if (oldQuest != null) {
+ if (green) {
+ if (oldQuest.state != QuestState.READY_TO_COLLECT && oldQuest.state != QuestState.COLLECTED) {
+ oldQuest.state = QuestState.READY_TO_COLLECT
+ dailyQuestHelper.update()
+ LorenzUtils.debug("Reputation Helper: Tab-List updated ${oldQuest.internalName} (This should not happen)")
+ }
+ }
+ return
+ }
+
+ val state = if (green) QuestState.READY_TO_COLLECT else QuestState.NOT_ACCEPTED
+ dailyQuestHelper.update()
+ dailyQuestHelper.quests.add(addQuest(name, state, needAmount))
+ }
+
+ private fun addQuest(
+ name: String,
+ state: QuestState,
+ needAmount: Int
+ ): Quest {
+ for (miniBoss in dailyQuestHelper.reputationHelper.miniBossHelper.miniBosses) {
+ if (name == miniBoss.displayName) {
+ return MiniBossQuest(miniBoss, state, needAmount)
+ }
+ }
+
+ for (entry in dailyQuestHelper.reputationHelper.repoData.entrySet()) {
+ val category = entry.key
+
+ for (element in entry.value.asJsonArray) {
+ val entryName = element.asString
+
+ if (name.startsWith("$entryName Rank ")) {
+ val split = name.split(" Rank ")
+ val dojoName = split[0]
+ val dojoRankGoal = split[1]
+ return DojoQuest(dojoName, dojoRankGoal, state)
+ }
+
+ if (name == entryName) {
+ when (category) {
+ "FISHING" -> return TrophyFishQuest(name, state, needAmount)
+ "RESCUE" -> return RescueMissionQuest(state)
+ "FETCH" -> return FetchQuest(name, state, needAmount)
+ }
+ }
+ }
+ }
+
+ println("Unknown quest: '$name'")
+ return UnknownQuest(name)
+ }
+
+ private fun getQuestByName(name: String): Quest? {
+ return dailyQuestHelper.quests.firstOrNull { it.internalName == name }
+ }
+
+ fun checkInventory() {
+ if (LorenzUtils.skyBlockArea != "Community Center") return
+
+ val gui = Minecraft.getMinecraft().currentScreen
+ if (gui !is GuiChest) return
+ val chest = gui.inventorySlots as ContainerChest
+ val name = chest.getInventoryName()
+
+ for (quest in dailyQuestHelper.quests) {
+ val categoryName = quest.category.name
+ if (categoryName.equals(name, ignoreCase = true)) {
+ for (slot in chest.inventorySlots) {
+ if (slot == null) continue
+ if (slot.slotNumber != slot.slotIndex) continue
+
+ // Only checking the middle slot
+ if (slot.slotNumber != 22) continue
+
+ val stack = slot.stack ?: continue
+
+ val completed = stack.getLore().any { it.contains("Completed!") }
+ if (completed) {
+ if (quest.state != QuestState.COLLECTED) {
+ quest.state = QuestState.COLLECTED
+ dailyQuestHelper.update()
+ }
+ }
+
+ val accepted = !stack.getLore().any { it.contains("Click to start!") }
+ if (accepted) {
+ if (quest.state == QuestState.NOT_ACCEPTED) {
+ quest.state = QuestState.ACCEPTED
+ dailyQuestHelper.update()
+ }
+ }
+ }
+ }
+ }
+ }
+
+ fun loadConfig() {
+ for (text in SkyHanniMod.feature.hidden.crimsonIsleQuests) {
+ val split = text.split(":")
+ val name = split[0]
+ val state = QuestState.valueOf(split[1])
+ val needAmount = split[2].toInt()
+ val quest = addQuest(name, state, needAmount)
+ if (quest is ProgressQuest) {
+ val haveAmount = split[3].toInt()
+ quest.haveAmount = haveAmount
+ }
+ dailyQuestHelper.quests.add(quest)
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/DojoQuest.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/DojoQuest.kt
new file mode 100644
index 000000000..69353de07
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/DojoQuest.kt
@@ -0,0 +1,11 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+import at.hannibal2.skyhanni.utils.LorenzUtils
+
+class DojoQuest(public val dojoName: String, dojoRankGoal: String, state: QuestState) :
+ Quest(
+ QuestCategory.DOJO,
+ "$dojoName Rank $dojoRankGoal",
+ state,
+ "$dojoName (" + LorenzUtils.getPointsForDojoRank(dojoRankGoal) + " points)"
+ )
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/FetchQuest.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/FetchQuest.kt
new file mode 100644
index 000000000..d815f9a76
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/FetchQuest.kt
@@ -0,0 +1,4 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+class FetchQuest(val itemName: String, state: QuestState, needAmount: Int) :
+ ProgressQuest(QuestCategory.FETCH, itemName, state, needAmount) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/MiniBossQuest.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/MiniBossQuest.kt
new file mode 100644
index 000000000..6b0faeb53
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/MiniBossQuest.kt
@@ -0,0 +1,6 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+import at.hannibal2.skyhanni.features.nether.reputationhelper.miniboss.CrimsonMiniBoss
+
+class MiniBossQuest(val miniBoss: CrimsonMiniBoss, state: QuestState, needAmount: Int) :
+ ProgressQuest(QuestCategory.MINIBOSS, miniBoss.displayName, state, needAmount) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/ProgressQuest.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/ProgressQuest.kt
new file mode 100644
index 000000000..938afb483
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/ProgressQuest.kt
@@ -0,0 +1,9 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+abstract class ProgressQuest(
+ questCategory: QuestCategory,
+ displayName: String,
+ state: QuestState,
+ val needAmount: Int,
+ var haveAmount: Int = 0
+) : Quest(questCategory, displayName, state) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/Quest.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/Quest.kt
new file mode 100644
index 000000000..95bf91cd9
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/Quest.kt
@@ -0,0 +1,4 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+abstract class Quest(val category: QuestCategory, val internalName: String, var state: QuestState, val displayName: String = internalName) {
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/QuestCategory.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/QuestCategory.kt
new file mode 100644
index 000000000..933c5c007
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/QuestCategory.kt
@@ -0,0 +1,11 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+enum class QuestCategory(val displayName: String) {
+ FISHING("Trophy Fish"),
+ RESCUE("Rescue Mission"),
+ MINIBOSS("Mini Boss"),
+ FETCH("Item Fetch"),
+ DOJO("Dojo Task"),
+
+ UNKNOWN("§cUnknown"),
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/QuestState.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/QuestState.kt
new file mode 100644
index 000000000..acde3785d
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/QuestState.kt
@@ -0,0 +1,8 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+enum class QuestState(val displayName: String, val color: String) {
+ NOT_ACCEPTED("Not Accepted", "§c"),
+ ACCEPTED("Accepted", "§b"),
+ READY_TO_COLLECT("Ready to collect", "§a"),
+ COLLECTED("Collected", "§7"),
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/RescueMissionQuest.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/RescueMissionQuest.kt
new file mode 100644
index 000000000..71b201047
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/RescueMissionQuest.kt
@@ -0,0 +1,3 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+class RescueMissionQuest(state: QuestState): Quest(QuestCategory.RESCUE, "Rescue Mission", state, "Rescue the NPC") \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/TrophyFishQuest.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/TrophyFishQuest.kt
new file mode 100644
index 000000000..3ecd80912
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/TrophyFishQuest.kt
@@ -0,0 +1,4 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+class TrophyFishQuest(val fishName: String, state: QuestState, needAmount: Int) :
+ ProgressQuest(QuestCategory.FISHING, fishName, state, needAmount) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/UnknownQuest.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/UnknownQuest.kt
new file mode 100644
index 000000000..197ee3bce
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/dailyquest/quest/UnknownQuest.kt
@@ -0,0 +1,4 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.dailyquest.quest
+
+class UnknownQuest(unknownName: String): Quest(QuestCategory.UNKNOWN, unknownName, QuestState.NOT_ACCEPTED) {
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/CrimsonMiniBoss.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/CrimsonMiniBoss.kt
new file mode 100644
index 000000000..d8ea3bd2e
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/CrimsonMiniBoss.kt
@@ -0,0 +1,5 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.miniboss
+
+import java.util.regex.Pattern
+
+class CrimsonMiniBoss(val displayName: String, val pattern: Pattern, var doneToday: Boolean = false, ) \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt
new file mode 100644
index 000000000..9e72ff2c5
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/nether/reputationhelper/miniboss/DailyMiniBossHelper.kt
@@ -0,0 +1,91 @@
+package at.hannibal2.skyhanni.features.nether.reputationhelper.miniboss
+
+import at.hannibal2.skyhanni.SkyHanniMod
+import at.hannibal2.skyhanni.data.HyPixelData
+import at.hannibal2.skyhanni.data.IslandType
+import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.features.nether.reputationhelper.CrimsonIsleReputationHelper
+import at.hannibal2.skyhanni.utils.LorenzUtils
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import java.util.regex.Pattern
+
+class DailyMiniBossHelper(private val reputationHelper: CrimsonIsleReputationHelper) {
+
+ val miniBosses = mutableListOf<CrimsonMiniBoss>()
+
+ fun init() {
+ if (miniBosses.isNotEmpty()) return
+
+ val repoData = reputationHelper.repoData
+ val jsonElement = repoData["MINIBOSS"]
+ val asJsonArray = jsonElement.asJsonArray
+ for (entry in asJsonArray) {
+ val displayName = entry.asString
+ val patterns = " *§r§6§l${displayName.uppercase()} DOWN!"
+ miniBosses.add(CrimsonMiniBoss(displayName, Pattern.compile(patterns)))
+ }
+ }
+
+ @SubscribeEvent
+ fun onChat(event: LorenzChatEvent) {
+ if (!HyPixelData.skyBlock) return
+ if (LorenzUtils.skyBlockIsland != IslandType.CRIMSON_ISLE) return
+
+ val message = event.message
+ for (miniBoss in miniBosses) {
+ if (miniBoss.pattern.matcher(message).matches()) {
+ finished(miniBoss)
+ }
+ }
+ }
+
+ private fun finished(miniBoss: CrimsonMiniBoss) {
+ LorenzUtils.debug("Detected mini boss death: ${miniBoss.displayName}")
+ reputationHelper.questHelper.finishMiniBoss(miniBoss)
+ miniBoss.doneToday = true
+ reputationHelper.update()
+ }
+
+ fun render(display: MutableList<String>) {
+ val done = miniBosses.count { it.doneToday }
+// val sneaking = Minecraft.getMinecraft().thePlayer.isSneaking
+// if (done != 5 || sneaking) {
+ if (done != 5) {
+ display.add("")
+ display.add("Daily Bosses ($done/5 killed)")
+ for (miniBoss in miniBosses) {
+ display.add(renderQuest(miniBoss))
+ }
+ }
+ }
+
+ private fun renderQuest(miniBoss: CrimsonMiniBoss): String {
+ val color = if (miniBoss.doneToday) "§7Done" else "§bTodo"
+ val displayName = miniBoss.displayName
+ return "$displayName: $color"
+ }
+
+ fun reset() {
+ for (miniBoss in miniBosses) {
+ miniBoss.doneToday = false
+ }
+ }
+
+ fun saveConfig() {
+ SkyHanniMod.feature.hidden.crimsonIsleMiniBossesDoneToday.clear()
+
+ for (miniBoss in miniBosses) {
+ if (miniBoss.doneToday) {
+ SkyHanniMod.feature.hidden.crimsonIsleMiniBossesDoneToday.add(miniBoss.displayName)
+ }
+ }
+ }
+
+ fun loadConfig() {
+ for (name in SkyHanniMod.feature.hidden.crimsonIsleMiniBossesDoneToday) {
+ getByDisplayName(name)!!.doneToday = true
+ }
+ }
+
+ private fun getByDisplayName(name: String) = miniBosses.firstOrNull { it.displayName == name }
+} \ No newline at end of file
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
index 9d783ce86..7dea12015 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt
@@ -144,4 +144,16 @@ object LorenzUtils {
}
return null
}
+
+ fun getPointsForDojoRank(rank: String): Int {
+ return when (rank) {
+ "S" -> 1000
+ "A" -> 800
+ "B" -> 600
+ "C" -> 400
+ "D" -> 200
+ "F" -> 0
+ else -> 0
+ }
+ }
} \ No newline at end of file