diff options
author | Linnea Gräf <nea@nea.moe> | 2025-03-07 00:21:38 +0100 |
---|---|---|
committer | Linnea Gräf <nea@nea.moe> | 2025-03-08 16:01:00 +0100 |
commit | b4a93bd7515ffd8f1fcbcf5315729ddd36b0166a (patch) | |
tree | 0f062d04649ba2df26251d922e27c7cd737f1fc0 | |
parent | 6ad259ca405d58f1956d67d7daeb05ae8590ca62 (diff) | |
download | Firmament-b4a93bd7515ffd8f1fcbcf5315729ddd36b0166a.tar.gz Firmament-b4a93bd7515ffd8f1fcbcf5315729ddd36b0166a.tar.bz2 Firmament-b4a93bd7515ffd8f1fcbcf5315729ddd36b0166a.zip |
feat: Add block breaking indicators to jade
10 files changed, 101 insertions, 39 deletions
diff --git a/src/compat/jade/java/moe/nea/firmament/compat/jade/CustomMiningHardnessProvider.kt b/src/compat/jade/java/moe/nea/firmament/compat/jade/CustomMiningHardnessProvider.kt index 1a662a4..7864339 100644 --- a/src/compat/jade/java/moe/nea/firmament/compat/jade/CustomMiningHardnessProvider.kt +++ b/src/compat/jade/java/moe/nea/firmament/compat/jade/CustomMiningHardnessProvider.kt @@ -4,8 +4,11 @@ import snownee.jade.api.BlockAccessor import snownee.jade.api.IBlockComponentProvider import snownee.jade.api.ITooltip import snownee.jade.api.config.IPluginConfig +import net.minecraft.block.BlockState import net.minecraft.util.Identifier +import net.minecraft.util.math.BlockPos import moe.nea.firmament.Firmament +import moe.nea.firmament.util.MC import moe.nea.firmament.util.tr object CustomMiningHardnessProvider : IBlockComponentProvider { @@ -22,4 +25,30 @@ object CustomMiningHardnessProvider : IBlockComponentProvider { override fun getUid(): Identifier = Firmament.identifier("custom_mining_hardness") + + data class BreakingInfo( + val blockPos: BlockPos, val stage: Int, + val state: BlockState?, + ) + + var currentBreakingInfo: BreakingInfo? = null + + @JvmStatic + fun setBreakingInfo(blockPos: BlockPos, stage: Int) { + currentBreakingInfo = BreakingInfo(blockPos.toImmutable(), stage, MC.world?.getBlockState(blockPos)) + } + + @JvmStatic + fun replaceBreakProgress(original: Float): Float { + if (!isOnMiningIsland()) return original + val pos = MC.interactionManager?.currentBreakingPos ?: return original + val info = currentBreakingInfo + if (info?.blockPos != pos || info.state != MC.world?.getBlockState(pos)) { + currentBreakingInfo = null + return 0F + } + // TODO: use linear extrapolation to guess how quickly this progresses between stages. + // This would only be possible after one stage, but should make the remaining stages a bit smoother + return info.stage / 10F + } } diff --git a/src/compat/jade/java/moe/nea/firmament/compat/jade/DrillToolProvider.kt b/src/compat/jade/java/moe/nea/firmament/compat/jade/DrillToolProvider.kt index b944e8d..bb52fe4 100644 --- a/src/compat/jade/java/moe/nea/firmament/compat/jade/DrillToolProvider.kt +++ b/src/compat/jade/java/moe/nea/firmament/compat/jade/DrillToolProvider.kt @@ -44,7 +44,7 @@ class DrillToolProvider : IBlockComponentProvider { if (it.isEmpty()) Optional.empty() else Optional.of(true) }.getOrDefault(false) } - val canHarvest = (SBItemStack(MC.stackInHand).neuItem?.breakingPower ?: 0) >= customBlock.breakingPower + val canHarvest = SBItemStack(MC.stackInHand).breakingPower >= customBlock.breakingPower val lastItem = innerMut[lastItemIndex] as ItemStackElement if (harvestIndicator < 0) { innerMut.add(lastItemIndex + 1, canHarvestIndicator(canHarvest, lastItem.alignment)) diff --git a/src/compat/jade/java/moe/nea/firmament/compat/jade/FirmamentJadePlugin.kt b/src/compat/jade/java/moe/nea/firmament/compat/jade/FirmamentJadePlugin.kt index 6cb04b5..900a48d 100644 --- a/src/compat/jade/java/moe/nea/firmament/compat/jade/FirmamentJadePlugin.kt +++ b/src/compat/jade/java/moe/nea/firmament/compat/jade/FirmamentJadePlugin.kt @@ -18,7 +18,6 @@ class FirmamentJadePlugin : IWailaPlugin { override fun registerClient(registration: IWailaClientRegistration) { registration.registerBlockComponent(CustomMiningHardnessProvider, Block::class.java) - registration.registerProgressClient(SkyblockProgressProvider()) registration.registerBlockComponent(DrillToolProvider(), Block::class.java) registration.addRayTraceCallback(CustomFakeBlockProvider(registration)) } diff --git a/src/compat/jade/java/moe/nea/firmament/compat/jade/SkyblockProgressProvider.kt b/src/compat/jade/java/moe/nea/firmament/compat/jade/SkyblockProgressProvider.kt deleted file mode 100644 index b0d809d..0000000 --- a/src/compat/jade/java/moe/nea/firmament/compat/jade/SkyblockProgressProvider.kt +++ /dev/null @@ -1,34 +0,0 @@ -package moe.nea.firmament.compat.jade - -import java.util.function.BiConsumer -import snownee.jade.api.Accessor -import snownee.jade.api.view.ClientViewGroup -import snownee.jade.api.view.IClientExtensionProvider -import snownee.jade.api.view.ProgressView -import snownee.jade.api.view.ViewGroup -import net.minecraft.text.Text -import net.minecraft.util.Identifier - -class SkyblockProgressProvider : IClientExtensionProvider<ProgressView.Data, ProgressView> { - // wtf does this do i think its for the little progress bar which breaks in mining fatigue mining system - // but like this is just copied from the example plugin soo - // this is different from the toolhandler/toolprovider, this one adjusts the mining progress bar to - // adjust with skyblock's nms packet fuckery (see pr for references on how those packets probably work) - // so yeah we need to fix that. - // TODO :3 lol - override fun getClientGroups(accessor: Accessor<*>, groups: List<ViewGroup<ProgressView.Data>>): List<ClientViewGroup<ProgressView>> { - return ClientViewGroup.map(groups, ProgressView::read, - BiConsumer { group: ViewGroup<ProgressView.Data>, clientGroup: ClientViewGroup<ProgressView> -> - var view = clientGroup.views.first() - view.style.color(-0x340000) - view.text = Text.literal("e") - view = clientGroup.views[1] - view.style.color(-0xff3400) - view.text = Text.literal("!!") - }) - } - - override fun getUid(): Identifier { - return "progress".jadeId() - } -} diff --git a/src/compat/jade/java/moe/nea/firmament/mixins/compat/jade/OnUpdateBreakProgress.java b/src/compat/jade/java/moe/nea/firmament/mixins/compat/jade/OnUpdateBreakProgress.java new file mode 100644 index 0000000..7d71ae8 --- /dev/null +++ b/src/compat/jade/java/moe/nea/firmament/mixins/compat/jade/OnUpdateBreakProgress.java @@ -0,0 +1,22 @@ +package moe.nea.firmament.mixins.compat.jade; + +import moe.nea.firmament.compat.jade.CustomMiningHardnessProvider; +import moe.nea.firmament.util.MC; +import net.minecraft.client.render.WorldRenderer; +import net.minecraft.util.math.BlockPos; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Objects; + +@Mixin(WorldRenderer.class) +public class OnUpdateBreakProgress { + @Inject(method = "setBlockBreakingInfo", at = @At("HEAD")) + private void replaceBreakProgress(int entityId, BlockPos pos, int stage, CallbackInfo ci) { + if (entityId == 0 && null != MC.INSTANCE.getInteractionManager() && Objects.equals(MC.INSTANCE.getInteractionManager().currentBreakingPos, pos)) { + CustomMiningHardnessProvider.setBreakingInfo(pos, stage); + } + } +} diff --git a/src/compat/jade/java/moe/nea/firmament/mixins/compat/jade/PatchBreakingBarSpeedJade.java b/src/compat/jade/java/moe/nea/firmament/mixins/compat/jade/PatchBreakingBarSpeedJade.java new file mode 100644 index 0000000..f85c301 --- /dev/null +++ b/src/compat/jade/java/moe/nea/firmament/mixins/compat/jade/PatchBreakingBarSpeedJade.java @@ -0,0 +1,20 @@ +package moe.nea.firmament.mixins.compat.jade; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import moe.nea.firmament.compat.jade.CustomMiningHardnessProvider; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import snownee.jade.JadeClient; + +@Mixin(JadeClient.class) +public class PatchBreakingBarSpeedJade { + @ModifyExpressionValue( + method = "drawBreakingProgress", + at = @At(value = "FIELD", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;currentBreakingProgress:F", opcode = Opcodes.GETFIELD) + ) + private static float replaceBlockBreakingProgress(float original) { + return CustomMiningHardnessProvider.replaceBreakProgress(original); + } + // TODO: given the inherent roughness of the server provided stages, i don't feel the need to also patch the accesses to the delta provided by the block state. if i ever get around to adding the linear extrapolation, i should also patch that extrapolation to use the better one provided by the server stages. +} diff --git a/src/main/java/moe/nea/firmament/mixins/accessor/AccessorWorldRenderer.java b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorWorldRenderer.java new file mode 100644 index 0000000..8b25562 --- /dev/null +++ b/src/main/java/moe/nea/firmament/mixins/accessor/AccessorWorldRenderer.java @@ -0,0 +1,17 @@ +package moe.nea.firmament.mixins.accessor; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import net.minecraft.client.render.WorldRenderer; +import net.minecraft.entity.player.BlockBreakingInfo; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.SortedSet; + +@Mixin(WorldRenderer.class) +public interface AccessorWorldRenderer { + @Accessor("blockBreakingProgressions") + @NotNull + Long2ObjectMap<SortedSet<BlockBreakingInfo>> getBlockBreakingProgressions_firmament(); +} diff --git a/src/main/kotlin/repo/SBItemStack.kt b/src/main/kotlin/repo/SBItemStack.kt index da34707..e04eec3 100644 --- a/src/main/kotlin/repo/SBItemStack.kt +++ b/src/main/kotlin/repo/SBItemStack.kt @@ -81,6 +81,7 @@ data class SBItemStack constructor( } val EMPTY = SBItemStack(SkyblockId.NULL, 0) + private val BREAKING_POWER_REGEX = "Breaking Power (?<power>[0-9]+)".toPattern() operator fun invoke(itemStack: ItemStack): SBItemStack { val skyblockId = itemStack.skyBlockId ?: SkyblockId.NULL return SBItemStack( @@ -349,6 +350,12 @@ data class SBItemStack constructor( private var itemStack_: ItemStack? = null + val breakingPower: Int + get() = + BREAKING_POWER_REGEX.useMatch(asImmutableItemStack().loreAccordingToNbt.firstOrNull()?.string) { + group("power").toInt() + } ?: 0 + private val itemStack: ItemStack get() { val itemStack = itemStack_ ?: run { diff --git a/src/main/kotlin/util/regex.kt b/src/main/kotlin/util/regex.kt index a44435c..f239810 100644 --- a/src/main/kotlin/util/regex.kt +++ b/src/main/kotlin/util/regex.kt @@ -16,12 +16,13 @@ import kotlin.time.Duration.Companion.seconds inline fun <T> String.ifMatches(regex: Regex, block: (MatchResult) -> T): T? = regex.matchEntire(this)?.let(block) -inline fun <T> Pattern.useMatch(string: String, block: Matcher.() -> T): T? { +inline fun <T> Pattern.useMatch(string: String?, block: Matcher.() -> T): T? { contract { callsInPlace(block, InvocationKind.AT_MOST_ONCE) } - return matcher(string) - .takeIf(Matcher::matches) + return string + ?.let(this::matcher) + ?.takeIf(Matcher::matches) ?.let(block) } diff --git a/src/main/resources/firmament.accesswidener b/src/main/resources/firmament.accesswidener index 1805721..fd79cb5 100644 --- a/src/main/resources/firmament.accesswidener +++ b/src/main/resources/firmament.accesswidener @@ -25,3 +25,4 @@ accessible field net/minecraft/client/render/OverlayTexture texture Lnet/minecra accessible method net/minecraft/client/render/RenderPhase$Texture getId ()Ljava/util/Optional; accessible field net/minecraft/client/render/RenderLayer$MultiPhase phases Lnet/minecraft/client/render/RenderLayer$MultiPhaseParameters; accessible field net/minecraft/client/render/RenderLayer$MultiPhaseParameters texture Lnet/minecraft/client/render/RenderPhase$TextureBase; +accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingPos Lnet/minecraft/util/math/BlockPos; |