diff options
author | hannibal2 <24389977+hannibal00212@users.noreply.github.com> | 2023-07-25 03:36:16 +0200 |
---|---|---|
committer | hannibal2 <24389977+hannibal00212@users.noreply.github.com> | 2023-07-25 03:36:16 +0200 |
commit | 4acfc5313cb68d28167c4fe4c91ad7666befc677 (patch) | |
tree | abe83581a533a06d8063601d3142059a1c344f92 | |
parent | e2c7746ab27d8abdfef3e93743ed243a68469192 (diff) | |
download | skyhanni-4acfc5313cb68d28167c4fe4c91ad7666befc677.tar.gz skyhanni-4acfc5313cb68d28167c4fe4c91ad7666befc677.tar.bz2 skyhanni-4acfc5313cb68d28167c4fe4c91ad7666befc677.zip |
Show locations of inactive Blood Effigy
10 files changed, 230 insertions, 21 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 29e1ce9b0..042dec43c 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -76,6 +76,7 @@ import at.hannibal2.skyhanni.features.rift.area.mirrorverse.DanceRoomHelper import at.hannibal2.skyhanni.features.rift.area.mirrorverse.RiftLavaMazeParkour import at.hannibal2.skyhanni.features.rift.area.mirrorverse.RiftUpsideDownParkour import at.hannibal2.skyhanni.features.rift.area.mirrorverse.TubulatorParkour +import at.hannibal2.skyhanni.features.rift.area.stillgorechateau.RiftBloodEffigies import at.hannibal2.skyhanni.features.rift.area.westvillage.KloonHacking import at.hannibal2.skyhanni.features.rift.area.wyldwoods.RiftOdonata import at.hannibal2.skyhanni.features.rift.area.wyldwoods.ShyCruxWarnings @@ -355,6 +356,9 @@ class SkyHanniMod { loadModule(LivingCaveLivingMetalHelper()) loadModule(RiftMotesOrb()) loadModule(SlayerBossSpawnSoon()) + // + loadModule(RiftBloodEffigies()) + init() diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java index 48882f49e..1585c390b 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/RiftConfig.java @@ -525,14 +525,45 @@ public class RiftConfig { public boolean highlightBlobbercysts = true; } -// @Expose -// @ConfigOption(name = "Stillgore Chateau", desc = "") -// @Accordion -// public StillgoreChateauConfig stillgoreChateauConfig = new StillgoreChateauConfig(); -// -// public static class StillgoreChateauConfig { -// -// } + @Expose + @ConfigOption(name = "Stillgore Chateau", desc = "") + @Accordion + public StillgoreChateauConfig stillgoreChateauConfig = new StillgoreChateauConfig(); + + public static class StillgoreChateauConfig { + + @Expose + @ConfigOption(name = "Blood Effigies", desc = "") + @Accordion + public EffigiesConfig bloodEffigies = new EffigiesConfig(); + + public static class EffigiesConfig { + + @Expose + @ConfigOption(name = "Enabled", desc = "Show locations of inactive Blood Effigy.") + @ConfigEditorBoolean + public boolean enabled = false; + + @Expose + @ConfigOption(name = "Respawning Soon", desc = "Show effigies that are about to respawn.") + @ConfigEditorBoolean + public boolean respawningSoon = false; + + @Expose + @ConfigOption(name = "Respawning Time", desc = "Time before effigies respawn to show.") + @ConfigEditorSlider( + minValue = 1, + maxValue = 15, + minStep = 1 + ) + public int respwningSoonTime = 3; + + @Expose + @ConfigOption(name = "Unknown Times", desc = "Show effigies without known time.") + @ConfigEditorBoolean + public boolean unknownTime = false; + } + } // @Expose // @ConfigOption(name = "Mountaintop", desc = "") diff --git a/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt b/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt index 20d6f4d5c..340e3b621 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/MinecraftData.kt @@ -1,14 +1,12 @@ package at.hannibal2.skyhanni.data -import at.hannibal2.skyhanni.events.LorenzTickEvent -import at.hannibal2.skyhanni.events.PacketEvent -import at.hannibal2.skyhanni.events.PlaySoundEvent -import at.hannibal2.skyhanni.events.ReceiveParticleEvent +import at.hannibal2.skyhanni.events.* import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzVec import net.minecraft.client.Minecraft import net.minecraft.network.play.server.S29PacketSoundEffect import net.minecraft.network.play.server.S2APacketParticles +import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent @@ -32,6 +30,11 @@ class MinecraftData { } } + @SubscribeEvent + fun onWorldLoad(event: WorldEvent.Load) { + LorenzWorldSwitchEvent().postAndCatch() + } + @SubscribeEvent(receiveCanceled = true) fun onParticlePacketReceive(event: PacketEvent.ReceiveEvent) { if (!LorenzUtils.inSkyBlock) return diff --git a/src/main/java/at/hannibal2/skyhanni/data/ScoreboardData.kt b/src/main/java/at/hannibal2/skyhanni/data/ScoreboardData.kt index 6da73b554..9602c1b59 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/ScoreboardData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/ScoreboardData.kt @@ -1,5 +1,7 @@ package at.hannibal2.skyhanni.data +import at.hannibal2.skyhanni.events.ScoreboardChangeEvent +import at.hannibal2.skyhanni.events.ScoreboardRawChangeEvent import net.minecraft.client.Minecraft import net.minecraft.scoreboard.Score import net.minecraft.scoreboard.ScorePlayerTeam @@ -37,9 +39,7 @@ class ScoreboardData { if (end.length >= 2) { end = end.substring(2) } - list.add(start + end) - } return list @@ -47,9 +47,8 @@ class ScoreboardData { var sidebarLinesFormatted: List<String> = emptyList() - // TODO remove these two - var sidebarLines: List<String> = emptyList() - var sidebarLinesRaw: List<String> = emptyList() + var sidebarLines: List<String> = emptyList() // TODO rename to raw + var sidebarLinesRaw: List<String> = emptyList() // TODO delete } @SubscribeEvent(priority = EventPriority.HIGHEST) @@ -57,9 +56,18 @@ class ScoreboardData { if (event.phase != TickEvent.Phase.START) return val list = fetchScoreboardLines().reversed() - sidebarLines = list.map { cleanSB(it) } + val semiFormatted = list.map { cleanSB(it) } + if (semiFormatted != sidebarLines) { + ScoreboardRawChangeEvent(sidebarLines, semiFormatted).postAndCatch() + sidebarLines = semiFormatted + } + sidebarLinesRaw = list - sidebarLinesFormatted = formatLines(list) + val new = formatLines(list) + if (new != sidebarLinesFormatted) { + ScoreboardChangeEvent(sidebarLinesFormatted, new).postAndCatch() + sidebarLinesFormatted = new + } } private fun cleanSB(scoreboard: String): String { diff --git a/src/main/java/at/hannibal2/skyhanni/events/LorenzWorldSwitchEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/LorenzWorldSwitchEvent.kt new file mode 100644 index 000000000..503e0fd3c --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/LorenzWorldSwitchEvent.kt @@ -0,0 +1,3 @@ +package at.hannibal2.skyhanni.events + +class LorenzWorldSwitchEvent() : LorenzEvent()
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/events/ScoreboardChangeEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/ScoreboardChangeEvent.kt new file mode 100644 index 000000000..c2976629f --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/ScoreboardChangeEvent.kt @@ -0,0 +1,3 @@ +package at.hannibal2.skyhanni.events + +class ScoreboardChangeEvent(val oldList: List<String>, val newList: List<String>): LorenzEvent()
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/events/ScoreboardRawChangeEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/ScoreboardRawChangeEvent.kt new file mode 100644 index 000000000..6f7301701 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/ScoreboardRawChangeEvent.kt @@ -0,0 +1,3 @@ +package at.hannibal2.skyhanni.events + +class ScoreboardRawChangeEvent(val oldList: List<String>, val newList: List<String>): LorenzEvent()
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt b/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt new file mode 100644 index 000000000..9892be944 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/rift/area/stillgorechateau/RiftBloodEffigies.kt @@ -0,0 +1,141 @@ +package at.hannibal2.skyhanni.features.rift.area.stillgorechateau + +import at.hannibal2.skyhanni.events.LorenzTickEvent +import at.hannibal2.skyhanni.events.LorenzWorldSwitchEvent +import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.events.ScoreboardRawChangeEvent +import at.hannibal2.skyhanni.features.rift.everywhere.RiftAPI +import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypointFilled +import at.hannibal2.skyhanni.utils.* +import at.hannibal2.skyhanni.utils.LocationUtils.distanceToPlayer +import at.hannibal2.skyhanni.utils.LorenzUtils.editCopy +import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import at.hannibal2.skyhanni.utils.jsonobjects.RiftEffingesJson +import net.minecraft.entity.item.EntityArmorStand +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class RiftBloodEffigies { + private val config get() = RiftAPI.config.area.stillgoreChateauConfig.bloodEffigies + private var locations: List<LorenzVec> = emptyList() + private var effingesTime = mapOf( + 0 to -1L, + 1 to -1L, + 2 to -1L, + 3 to -1L, + 4 to -1L, + 5 to -1L, + ) + + private val effigiesTimerPattern = "§eRespawn §c(?<time>.*) §7\\(or click!\\)".toPattern() + + @SubscribeEvent + fun onWorldSwitch(event: LorenzWorldSwitchEvent) { + effingesTime = mapOf( + 0 to -1L, + 1 to -1L, + 2 to -1L, + 3 to -1L, + 4 to -1L, + 5 to -1L, + ) + } + + @SubscribeEvent + fun onRepoReload(event: RepositoryReloadEvent) { + event.getConstant<RiftEffingesJson>("RiftEffinges")?.locations?.let { + if (it.size != 6) { + error("Invalid rift effinges size: ${it.size} (expeced 6)") + } + locations = it + } + } + + @SubscribeEvent + fun onScoreboardChange(event: ScoreboardRawChangeEvent) { + if (!isEnabled()) return + + val line = event.newList.firstOrNull { it.startsWith("Effigies:") } ?: return + val hearts = "Effigies: (?<hearts>.*)".toPattern().matchMatcher(line) { + group("hearts") + } ?: return + + val split = hearts.split("§").drop(1) + for ((index, s) in split.withIndex()) { + val time = effingesTime[index]!! + val diff = time - System.currentTimeMillis() + if (diff < 0L) { + if (s == "7") { + if (time != 0L) { + LorenzUtils.chat("§e[SkyHanni] Effigies #${index + 1} respawned!") + effingesTime = effingesTime.editCopy { this[index] = 0L } + } + } else { + if (time != -1L) { + LorenzUtils.chat("§e[SkyHanni] Effigies #${index + 1} got killed!") + val endTime = System.currentTimeMillis() + 1_000 * 60 * 10 + effingesTime = effingesTime.editCopy { this[index] = endTime } + } + } + } + } + } + + @SubscribeEvent + fun onTick(event: LorenzTickEvent) { + if (!event.isMod(20)) return + if (!isEnabled()) return + + for (entity in EntityUtils.getEntitiesNearby<EntityArmorStand>(LocationUtils.playerLocation(), 6.0)) { + effigiesTimerPattern.matchMatcher(entity.name) { + val nearest = locations.sortedBy { it.distanceSq(entity.getLorenzVec()) }.firstOrNull() ?: return + val index = locations.indexOf(nearest) + + val string = group("time") + val time = TimeUtils.getMillis(string) + effingesTime = effingesTime.editCopy { this[index] = System.currentTimeMillis() + time } + } + } + } + + @SubscribeEvent + fun onRenderWorld(event: RenderWorldLastEvent) { + if (!isEnabled()) return + + for ((index, location) in locations.withIndex()) { + val name = "Effigies #${index + 1}" + val duration = effingesTime[index]!! + + if (duration == -1L) { + if (config.unknownTime) { + event.drawWaypointFilled(location, LorenzColor.GRAY.toColor(), seeThroughBlocks = true) + event.drawDynamicText(location, "§7Unknown Time ($name)", 1.5) + continue + } + } else { + val diff = duration - System.currentTimeMillis() + if (duration <= 0L) { + event.drawWaypointFilled(location, LorenzColor.RED.toColor(), seeThroughBlocks = true) + event.drawDynamicText(location, "§c$name is Alive! Break it!", 1.5) + continue + } + + if (config.respawningSoon) { + if (diff < 60_000 * config.respwningSoonTime) { + val time = TimeUtils.formatDuration(diff - 999) + event.drawWaypointFilled(location, LorenzColor.YELLOW.toColor(), seeThroughBlocks = true) + event.drawDynamicText(location, "§e$name is respawning $time", 1.5) + continue + } + } + } + + if (location.distanceToPlayer() < 5) { + event.drawDynamicText(location, "§7$name", 1.5) + } + } + } + + fun isEnabled() = RiftAPI.inRift() && RiftAPI.inStillgoreChateau() && config.enabled +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt index a0b6e91d8..4f9c1b799 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/TimeUtils.kt @@ -69,7 +69,9 @@ object TimeUtils { } // TODO: use kotlin Duration - fun getMillis(string: String) = pattern.matchMatcher(string.lowercase().trim()) { + fun getMillis(string: String) = getMillis_(string.replace("m", "m ").replace(" ", " ")) + + private fun getMillis_(string: String) = pattern.matchMatcher(string.lowercase().trim()) { val years = group("y")?.toLong() ?: 0L val days = group("d")?.toLong() ?: 0L val hours = group("h")?.toLong() ?: 0L @@ -83,7 +85,7 @@ object TimeUtils { millis += days * 24 * 60 * 60 * 1000 millis += (years * 365.25 * 24 * 60 * 60 * 1000).toLong() - millis + millis } ?: tryAlternativeFormat(string) private fun tryAlternativeFormat(string: String): Long { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/RiftEffingesJson.java b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/RiftEffingesJson.java new file mode 100644 index 000000000..47c10c2c9 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/jsonobjects/RiftEffingesJson.java @@ -0,0 +1,11 @@ +package at.hannibal2.skyhanni.utils.jsonobjects; + +import at.hannibal2.skyhanni.utils.LorenzVec; +import com.google.gson.annotations.Expose; + +import java.util.List; + +public class RiftEffingesJson { + @Expose + public List<LorenzVec> locations; +} |