aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-04-26 10:11:23 +0200
committerLinnea Gräf <nea@nea.moe>2024-04-26 10:12:18 +0200
commit041da7c7d179df01c4048a81ddf40a9f13c3ce77 (patch)
tree6e6933320c8e96a22bfe433b1e33b184948b8fbd
parentc264ca9e8f9f2b0aed457753c43bb4e25edb0ef1 (diff)
downloadfirmament-041da7c7d179df01c4048a81ddf40a9f13c3ce77.tar.gz
firmament-041da7c7d179df01c4048a81ddf40a9f13c3ce77.tar.bz2
firmament-041da7c7d179df01c4048a81ddf40a9f13c3ce77.zip
Add fuel durability bar
-rw-r--r--src/main/java/moe/nea/firmament/mixins/CustomDurabilityBarPatch.java58
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/mining/PickaxeAbility.kt51
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/DurabilityBarEvent.kt25
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/regex.kt42
-rw-r--r--src/main/kotlin/moe/nea/firmament/util/render/LerpUtils.kt15
-rw-r--r--src/main/resources/assets/firmament/lang/en_us.json3
6 files changed, 179 insertions, 15 deletions
diff --git a/src/main/java/moe/nea/firmament/mixins/CustomDurabilityBarPatch.java b/src/main/java/moe/nea/firmament/mixins/CustomDurabilityBarPatch.java
new file mode 100644
index 0000000..f396ce6
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/CustomDurabilityBarPatch.java
@@ -0,0 +1,58 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package moe.nea.firmament.mixins;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Share;
+import com.llamalad7.mixinextras.sugar.ref.LocalRef;
+import moe.nea.firmament.util.DurabilityBarEvent;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.item.ItemStack;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+@Mixin(DrawContext.class)
+public class CustomDurabilityBarPatch {
+ @WrapOperation(
+ method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isItemBarVisible()Z")
+ )
+ private boolean onIsItemBarVisible(
+ ItemStack instance, Operation<Boolean> original,
+ @Share("barOverride") LocalRef<DurabilityBarEvent.DurabilityBar> barOverride
+ ) {
+ if (original.call(instance))
+ return true;
+ DurabilityBarEvent event = new DurabilityBarEvent(instance);
+ DurabilityBarEvent.Companion.publish(event);
+ barOverride.set(event.getBarOverride());
+ return barOverride.get() != null;
+ }
+
+ @WrapOperation(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItemBarStep()I"))
+ private int overrideItemStep(
+ ItemStack instance, Operation<Integer> original,
+ @Share("barOverride") LocalRef<DurabilityBarEvent.DurabilityBar> barOverride
+ ) {
+ if (barOverride.get() != null)
+ return Math.round(barOverride.get().getPercentage() * 13);
+ return original.call(instance);
+ }
+
+ @WrapOperation(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getItemBarColor()I"))
+ private int overrideItemColor(
+ ItemStack instance, Operation<Integer> original,
+ @Share("barOverride") LocalRef<DurabilityBarEvent.DurabilityBar> barOverride
+ ) {
+ if (barOverride.get() != null)
+ return barOverride.get().getColor().getColor();
+ return original.call(instance);
+ }
+}
diff --git a/src/main/kotlin/moe/nea/firmament/features/mining/PickaxeAbility.kt b/src/main/kotlin/moe/nea/firmament/features/mining/PickaxeAbility.kt
index 4c23e04..24a39e0 100644
--- a/src/main/kotlin/moe/nea/firmament/features/mining/PickaxeAbility.kt
+++ b/src/main/kotlin/moe/nea/firmament/features/mining/PickaxeAbility.kt
@@ -7,11 +7,10 @@
package moe.nea.firmament.features.mining
import java.util.regex.Pattern
-import org.intellij.lang.annotations.Language
import kotlin.time.Duration
-import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
import net.minecraft.item.ItemStack
+import net.minecraft.util.DyeColor
import net.minecraft.util.Hand
import net.minecraft.util.Identifier
import moe.nea.firmament.events.HudRenderEvent
@@ -20,11 +19,19 @@ import moe.nea.firmament.events.SlotClickEvent
import moe.nea.firmament.events.WorldReadyEvent
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.gui.config.ManagedConfig
+import moe.nea.firmament.util.DurabilityBarEvent
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.SHORT_NUMBER_FORMAT
+import moe.nea.firmament.util.TIME_PATTERN
import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.extraAttributes
import moe.nea.firmament.util.item.displayNameAccordingToNbt
import moe.nea.firmament.util.item.loreAccordingToNbt
+import moe.nea.firmament.util.parseShortNumber
+import moe.nea.firmament.util.parseTimePattern
import moe.nea.firmament.util.render.RenderCircleProgress
+import moe.nea.firmament.util.render.lerp
+import moe.nea.firmament.util.toShedaniel
import moe.nea.firmament.util.unformattedString
import moe.nea.firmament.util.useMatch
@@ -36,6 +43,7 @@ object PickaxeAbility : FirmamentFeature {
object TConfig : ManagedConfig(identifier) {
val cooldownEnabled by toggle("ability-cooldown") { true }
val cooldownScale by integer("ability-scale", 16, 64) { 16 }
+ val drillFuelBar by toggle("fuel-bar") { true }
}
var lobbyJoinTime = TimeMark.farPast()
@@ -73,13 +81,36 @@ object PickaxeAbility : FirmamentFeature {
abilityOverride = null
}
ProcessChatEvent.subscribe {
- pattern.useMatch(it.unformattedString) {
+ abilityUsePattern.useMatch(it.unformattedString) {
lastUsage[group("name")] = TimeMark.now()
}
abilitySwitchPattern.useMatch(it.unformattedString) {
abilityOverride = group("ability")
}
}
+ DurabilityBarEvent.subscribe {
+ if (!TConfig.drillFuelBar) return@subscribe
+ val lore = it.item.loreAccordingToNbt
+ if (lore.lastOrNull()?.value?.unformattedString?.contains("DRILL") != true) return@subscribe
+ val maxFuel = lore.firstNotNullOfOrNull {
+ fuelPattern.useMatch(
+ it.value?.unformattedString ?: return@firstNotNullOfOrNull null
+ ) {
+ parseShortNumber(group("maxFuel"))
+ }
+ } ?: return@subscribe
+ val extra = it.item.extraAttributes
+ if (!extra.contains("drill_fuel")) return@subscribe
+ val fuel = extra.getInt("drill_fuel")
+ val percentage = fuel / maxFuel.toFloat()
+ it.barOverride = DurabilityBarEvent.DurabilityBar(
+ lerp(
+ DyeColor.RED.toShedaniel(),
+ DyeColor.GREEN.toShedaniel(),
+ percentage
+ ), percentage
+ )
+ }
SlotClickEvent.subscribe {
if (MC.screen?.title?.unformattedString == "Heart of the Mountain") {
val name = it.stack.displayNameAccordingToNbt?.unformattedString ?: return@subscribe
@@ -93,7 +124,8 @@ object PickaxeAbility : FirmamentFeature {
}
}
- val pattern = Pattern.compile("You used your (?<name>.*) Pickaxe Ability!")
+ val abilityUsePattern = Pattern.compile("You used your (?<name>.*) Pickaxe Ability!")
+ val fuelPattern = Pattern.compile("Fuel: .*/(?<maxFuel>$SHORT_NUMBER_FORMAT)")
data class PickaxeAbilityData(
val name: String,
@@ -117,21 +149,12 @@ object PickaxeAbility : FirmamentFeature {
return PickaxeAbilityData(name, cooldown)
}
- @Language("RegExp")
- val TIME_PATTERN = "[0-9]+[ms]"
+
val cooldownPattern = Pattern.compile("Cooldown: (?<cooldown>$TIME_PATTERN)")
val abilityPattern = Pattern.compile("Ability: (?<name>.*) {2}RIGHT CLICK")
val abilitySwitchPattern =
Pattern.compile("You selected (?<ability>.*) as your Pickaxe Ability\\. This ability will apply to all of your pickaxes!")
- fun parseTimePattern(text: String): Duration {
- val length = text.dropLast(1).toInt()
- return when (text.last()) {
- 'm' -> length.minutes
- 's' -> length.seconds
- else -> error("Invalid pattern for time $text")
- }
- }
private fun renderHud(event: HudRenderEvent) {
if (!TConfig.cooldownEnabled) return
diff --git a/src/main/kotlin/moe/nea/firmament/util/DurabilityBarEvent.kt b/src/main/kotlin/moe/nea/firmament/util/DurabilityBarEvent.kt
new file mode 100644
index 0000000..eacf070
--- /dev/null
+++ b/src/main/kotlin/moe/nea/firmament/util/DurabilityBarEvent.kt
@@ -0,0 +1,25 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package moe.nea.firmament.util
+
+import me.shedaniel.math.Color
+import net.minecraft.item.ItemStack
+import moe.nea.firmament.events.FirmamentEvent
+import moe.nea.firmament.events.FirmamentEventBus
+
+data class DurabilityBarEvent(
+ val item: ItemStack,
+) : FirmamentEvent() {
+ data class DurabilityBar(
+ val color: Color,
+ val percentage: Float,
+ )
+
+ var barOverride: DurabilityBar? = null
+
+ companion object : FirmamentEventBus<DurabilityBarEvent>()
+}
diff --git a/src/main/kotlin/moe/nea/firmament/util/regex.kt b/src/main/kotlin/moe/nea/firmament/util/regex.kt
index 4cc3f03..9de2b36 100644
--- a/src/main/kotlin/moe/nea/firmament/util/regex.kt
+++ b/src/main/kotlin/moe/nea/firmament/util/regex.kt
@@ -1,5 +1,6 @@
/*
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
+ * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
@@ -8,6 +9,10 @@ package moe.nea.firmament.util
import java.util.regex.Matcher
import java.util.regex.Pattern
+import org.intellij.lang.annotations.Language
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.minutes
+import kotlin.time.Duration.Companion.seconds
inline fun <T> String.ifMatches(regex: Regex, block: (MatchResult) -> T): T? =
regex.matchEntire(this)?.let(block)
@@ -16,3 +21,40 @@ inline fun <T> Pattern.useMatch(string: String, block: Matcher.() -> T): T? =
matcher(string)
.takeIf(Matcher::matches)
?.let(block)
+
+@Language("RegExp")
+val TIME_PATTERN = "[0-9]+[ms]"
+
+@Language("RegExp")
+val SHORT_NUMBER_FORMAT = "[0-9]+(?:,[0-9]+)*(?:\\.[0-9]+)?[kKmMbB]?"
+
+
+val siScalars = mapOf(
+ 'k' to 1_000.0,
+ 'K' to 1_000.0,
+ 'm' to 1_000_000.0,
+ 'M' to 1_000_000.0,
+ 'b' to 1_000_000_000.0,
+ 'B' to 1_000_000_000.0,
+)
+
+fun parseTimePattern(text: String): Duration {
+ val length = text.dropLast(1).toInt()
+ return when (text.last()) {
+ 'm' -> length.minutes
+ 's' -> length.seconds
+ else -> error("Invalid pattern for time $text")
+ }
+}
+
+fun parseShortNumber(string: String): Double {
+ var k = string.replace(",", "")
+ val scalar = k.last()
+ var scalarMultiplier = siScalars[scalar]
+ if (scalarMultiplier == null) {
+ scalarMultiplier = 1.0
+ } else {
+ k = k.dropLast(1)
+ }
+ return k.toDouble() * scalarMultiplier
+}
diff --git a/src/main/kotlin/moe/nea/firmament/util/render/LerpUtils.kt b/src/main/kotlin/moe/nea/firmament/util/render/LerpUtils.kt
index a979f8d..66899ce 100644
--- a/src/main/kotlin/moe/nea/firmament/util/render/LerpUtils.kt
+++ b/src/main/kotlin/moe/nea/firmament/util/render/LerpUtils.kt
@@ -6,6 +6,8 @@
package moe.nea.firmament.util.render
+import me.shedaniel.math.Color
+
val pi = Math.PI
val tau = Math.PI * 2
fun lerpAngle(a: Float, b: Float, progress: Float): Float {
@@ -17,7 +19,20 @@ fun lerpAngle(a: Float, b: Float, progress: Float): Float {
fun lerp(a: Float, b: Float, progress: Float): Float {
return a + (b - a) * progress
}
+fun lerp(a: Int, b: Int, progress: Float): Int {
+ return (a + (b - a) * progress).toInt()
+}
fun ilerp(a: Float, b: Float, value: Float): Float {
return (value - a) / (b - a)
}
+
+fun lerp(a: Color, b: Color, progress: Float): Color {
+ return Color.ofRGBA(
+ lerp(a.red, b.red, progress),
+ lerp(a.green, b.green, progress),
+ lerp(a.blue, b.blue, progress),
+ lerp(a.alpha, b.alpha, progress),
+ )
+}
+
diff --git a/src/main/resources/assets/firmament/lang/en_us.json b/src/main/resources/assets/firmament/lang/en_us.json
index 37df38e..cdcaea2 100644
--- a/src/main/resources/assets/firmament/lang/en_us.json
+++ b/src/main/resources/assets/firmament/lang/en_us.json
@@ -167,5 +167,6 @@
"firmament.quick-commands.join.unknown-catacombs": "Unknown catacombs floor %s",
"firmament.config.pickaxe-info": "Pickaxes",
"firmament.config.pickaxe-info.ability-cooldown": "Pickaxe Ability Cooldown",
- "firmament.config.pickaxe-info.ability-scale": "Ability Cooldown Scale"
+ "firmament.config.pickaxe-info.ability-scale": "Ability Cooldown Scale",
+ "firmament.config.pickaxe-info.fuel-bar": "Drill Fuel Durability Bar"
}