feat: Add block breaking indicators to jade
This commit is contained in:
@@ -4,8 +4,11 @@ import snownee.jade.api.BlockAccessor
|
|||||||
import snownee.jade.api.IBlockComponentProvider
|
import snownee.jade.api.IBlockComponentProvider
|
||||||
import snownee.jade.api.ITooltip
|
import snownee.jade.api.ITooltip
|
||||||
import snownee.jade.api.config.IPluginConfig
|
import snownee.jade.api.config.IPluginConfig
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
|
import moe.nea.firmament.util.MC
|
||||||
import moe.nea.firmament.util.tr
|
import moe.nea.firmament.util.tr
|
||||||
|
|
||||||
object CustomMiningHardnessProvider : IBlockComponentProvider {
|
object CustomMiningHardnessProvider : IBlockComponentProvider {
|
||||||
@@ -22,4 +25,30 @@ object CustomMiningHardnessProvider : IBlockComponentProvider {
|
|||||||
|
|
||||||
override fun getUid(): Identifier =
|
override fun getUid(): Identifier =
|
||||||
Firmament.identifier("custom_mining_hardness")
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class DrillToolProvider : IBlockComponentProvider {
|
|||||||
if (it.isEmpty()) Optional.empty() else Optional.of(true)
|
if (it.isEmpty()) Optional.empty() else Optional.of(true)
|
||||||
}.getOrDefault(false)
|
}.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
|
val lastItem = innerMut[lastItemIndex] as ItemStackElement
|
||||||
if (harvestIndicator < 0) {
|
if (harvestIndicator < 0) {
|
||||||
innerMut.add(lastItemIndex + 1, canHarvestIndicator(canHarvest, lastItem.alignment))
|
innerMut.add(lastItemIndex + 1, canHarvestIndicator(canHarvest, lastItem.alignment))
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ class FirmamentJadePlugin : IWailaPlugin {
|
|||||||
|
|
||||||
override fun registerClient(registration: IWailaClientRegistration) {
|
override fun registerClient(registration: IWailaClientRegistration) {
|
||||||
registration.registerBlockComponent(CustomMiningHardnessProvider, Block::class.java)
|
registration.registerBlockComponent(CustomMiningHardnessProvider, Block::class.java)
|
||||||
registration.registerProgressClient(SkyblockProgressProvider())
|
|
||||||
registration.registerBlockComponent(DrillToolProvider(), Block::class.java)
|
registration.registerBlockComponent(DrillToolProvider(), Block::class.java)
|
||||||
registration.addRayTraceCallback(CustomFakeBlockProvider(registration))
|
registration.addRayTraceCallback(CustomFakeBlockProvider(registration))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -81,6 +81,7 @@ data class SBItemStack constructor(
|
|||||||
}
|
}
|
||||||
val EMPTY = SBItemStack(SkyblockId.NULL, 0)
|
val EMPTY = SBItemStack(SkyblockId.NULL, 0)
|
||||||
|
|
||||||
|
private val BREAKING_POWER_REGEX = "Breaking Power (?<power>[0-9]+)".toPattern()
|
||||||
operator fun invoke(itemStack: ItemStack): SBItemStack {
|
operator fun invoke(itemStack: ItemStack): SBItemStack {
|
||||||
val skyblockId = itemStack.skyBlockId ?: SkyblockId.NULL
|
val skyblockId = itemStack.skyBlockId ?: SkyblockId.NULL
|
||||||
return SBItemStack(
|
return SBItemStack(
|
||||||
@@ -349,6 +350,12 @@ data class SBItemStack constructor(
|
|||||||
|
|
||||||
private var itemStack_: ItemStack? = null
|
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
|
private val itemStack: ItemStack
|
||||||
get() {
|
get() {
|
||||||
val itemStack = itemStack_ ?: run {
|
val itemStack = itemStack_ ?: run {
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ import kotlin.time.Duration.Companion.seconds
|
|||||||
inline fun <T> String.ifMatches(regex: Regex, block: (MatchResult) -> T): T? =
|
inline fun <T> String.ifMatches(regex: Regex, block: (MatchResult) -> T): T? =
|
||||||
regex.matchEntire(this)?.let(block)
|
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 {
|
contract {
|
||||||
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||||
}
|
}
|
||||||
return matcher(string)
|
return string
|
||||||
.takeIf(Matcher::matches)
|
?.let(this::matcher)
|
||||||
|
?.takeIf(Matcher::matches)
|
||||||
?.let(block)
|
?.let(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 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$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/render/RenderLayer$MultiPhaseParameters texture Lnet/minecraft/client/render/RenderPhase$TextureBase;
|
||||||
|
accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingPos Lnet/minecraft/util/math/BlockPos;
|
||||||
|
|||||||
Reference in New Issue
Block a user