feat: Add tool/harvestability indicator
This commit is contained in:
@@ -57,7 +57,7 @@ devauth = "1.2.1"
|
||||
ktor = "3.0.3"
|
||||
|
||||
# Update from https://repo.nea.moe/#/releases/moe/nea/neurepoparser
|
||||
neurepoparser = "1.6.0"
|
||||
neurepoparser = "1.7.0"
|
||||
|
||||
# Update from https://github.com/HotswapProjects/HotswapAgent/releases
|
||||
# TODO: bump to 2.0.1
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package moe.nea.firmament.compat.jade
|
||||
|
||||
import com.google.common.collect.Lists
|
||||
import snownee.jade.addon.harvest.SimpleToolHandler
|
||||
import snownee.jade.addon.harvest.ToolHandler
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.MinecraftClient
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.world.World
|
||||
import moe.nea.firmament.util.SBData
|
||||
|
||||
class DrillToolHandler(
|
||||
private val uid: Identifier,
|
||||
private val tools: MutableList<ItemStack>
|
||||
) : ToolHandler {
|
||||
override fun test(state: BlockState, world: World, pos: BlockPos): ItemStack {
|
||||
if (isOnMiningIsland()) {
|
||||
}
|
||||
|
||||
// TODO: figure out how this work
|
||||
return SimpleToolHandler.create(uid, tools.map {
|
||||
return@map it.item
|
||||
}).test(state, world, pos)
|
||||
}
|
||||
|
||||
override fun getTools(): List<ItemStack> {
|
||||
return this.tools
|
||||
}
|
||||
|
||||
override fun getUid(): Identifier {
|
||||
return this.uid
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,79 @@
|
||||
package moe.nea.firmament.compat.jade
|
||||
|
||||
import com.google.common.cache.Cache
|
||||
import com.google.common.cache.CacheBuilder
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.common.collect.Maps
|
||||
import java.util.concurrent.TimeUnit
|
||||
import snownee.jade.addon.harvest.ToolHandler
|
||||
import java.util.Optional
|
||||
import java.util.function.UnaryOperator
|
||||
import snownee.jade.api.BlockAccessor
|
||||
import snownee.jade.api.IBlockComponentProvider
|
||||
import snownee.jade.api.ITooltip
|
||||
import snownee.jade.api.JadeIds
|
||||
import snownee.jade.api.config.IPluginConfig
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockState
|
||||
import snownee.jade.api.theme.IThemeHelper
|
||||
import snownee.jade.api.ui.IElement
|
||||
import snownee.jade.api.ui.IElementHelper
|
||||
import snownee.jade.impl.ui.ItemStackElement
|
||||
import snownee.jade.impl.ui.TextElement
|
||||
import kotlin.jvm.optionals.getOrDefault
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.resource.ResourceManager
|
||||
import net.minecraft.resource.SynchronousResourceReloader
|
||||
import net.minecraft.item.Items
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.Vec2f
|
||||
import moe.nea.firmament.Firmament
|
||||
import moe.nea.firmament.repo.ItemCache.asItemStack
|
||||
import moe.nea.firmament.repo.RepoManager
|
||||
import moe.nea.firmament.repo.SBItemStack
|
||||
import moe.nea.firmament.util.MC
|
||||
|
||||
|
||||
class DrillToolProvider : IBlockComponentProvider, SynchronousResourceReloader {
|
||||
val resultCache: Cache<BlockState, ImmutableList<ItemStack>> = CacheBuilder.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES).build()
|
||||
val toolHandlers: MutableMap<Identifier, ToolHandler> = Maps.newLinkedHashMap()
|
||||
private val shearableBlocks: MutableList<Block> = mutableListOf()
|
||||
private val checkIcon: Text = Text.literal("✔")
|
||||
private val xIcon: Text = Text.literal("✕")
|
||||
private val itemSize = Vec2f(10f, 0f)
|
||||
|
||||
@Synchronized
|
||||
fun registerHandler(handler: ToolHandler) {
|
||||
toolHandlers.put(handler.uid, handler)
|
||||
class DrillToolProvider : IBlockComponentProvider {
|
||||
override fun appendTooltip(
|
||||
tooltip: ITooltip,
|
||||
accessor: BlockAccessor,
|
||||
p2: IPluginConfig?
|
||||
) {
|
||||
val customBlock = CustomFakeBlockProvider.getCustomBlock(accessor) ?: return
|
||||
if (customBlock.breakingPower <= 0) return
|
||||
val tool = RepoManager.miningData.getToolsThatCanBreak(customBlock.breakingPower).firstOrNull()
|
||||
?.asItemStack() ?: return
|
||||
tooltip.replace(JadeIds.MC_HARVEST_TOOL, UnaryOperator { elements ->
|
||||
elements.map { inner ->
|
||||
val lastItemIndex = inner.indexOfLast { it is ItemStackElement }
|
||||
if (lastItemIndex < 0) return@map inner
|
||||
val innerMut = inner.toMutableList()
|
||||
val harvestIndicator = innerMut.indexOfLast {
|
||||
it is TextElement && it.cachedSize == Vec2f.ZERO && it.text.visit {
|
||||
if (it.isEmpty()) Optional.empty() else Optional.of(true)
|
||||
}.getOrDefault(false)
|
||||
}
|
||||
val canHarvest = (SBItemStack(MC.stackInHand).neuItem?.breakingPower ?: 0) >= customBlock.breakingPower
|
||||
val lastItem = innerMut[lastItemIndex] as ItemStackElement
|
||||
if (harvestIndicator < 0) {
|
||||
innerMut.add(lastItemIndex + 1, canHarvestIndicator(canHarvest, lastItem.alignment))
|
||||
} else {
|
||||
innerMut.set(harvestIndicator, canHarvestIndicator(canHarvest, lastItem.alignment))
|
||||
}
|
||||
innerMut.set(lastItemIndex, IElementHelper.get()
|
||||
.item(tool, 0.75f)
|
||||
.translate(lastItem.translation)
|
||||
.size(lastItem.size)
|
||||
.message(null)
|
||||
.align(lastItem.alignment))
|
||||
innerMut.subList(0, lastItemIndex - 1).removeIf { it is ItemStackElement }
|
||||
innerMut
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun appendTooltip(tooltip: ITooltip, accessor: BlockAccessor, config: IPluginConfig) {
|
||||
TODO("Not yet implemented")
|
||||
fun canHarvestIndicator(canHarvest: Boolean, align: IElement.Align): IElement {
|
||||
val t = IThemeHelper.get()
|
||||
val text = if (canHarvest) t.success(CHECK) else t.danger(X)
|
||||
return IElementHelper.get().text(text)
|
||||
.scale(0.75F).zOffset(800).size(Vec2f.ZERO).translate(Vec2f(-3F, 3.25F)).align(align)
|
||||
}
|
||||
|
||||
private val CHECK: Text = Text.literal("✔")
|
||||
private val X: Text = Text.literal("✕")
|
||||
|
||||
override fun getUid(): Identifier {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun reload(manager: ResourceManager) {
|
||||
TODO("Not yet implemented")
|
||||
return Firmament.identifier("toolprovider")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package moe.nea.firmament.compat.jade
|
||||
|
||||
import snownee.jade.addon.harvest.HarvestToolProvider
|
||||
import snownee.jade.api.IWailaClientRegistration
|
||||
import snownee.jade.api.IWailaCommonRegistration
|
||||
import snownee.jade.api.IWailaPlugin
|
||||
@@ -18,6 +19,7 @@ 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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package moe.nea.firmament.compat.jade
|
||||
|
||||
import snownee.jade.api.BlockAccessor
|
||||
import snownee.jade.api.IBlockComponentProvider
|
||||
import snownee.jade.api.ITooltip
|
||||
import snownee.jade.api.config.IPluginConfig
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import moe.nea.firmament.util.SBData
|
||||
|
||||
class GemstoneProvider(val type: String, val replacement: String) : IBlockComponentProvider {
|
||||
override fun appendTooltip(tooltip: ITooltip, accessor: BlockAccessor, config: IPluginConfig) {
|
||||
if (SBData.isOnSkyblock) {
|
||||
tooltip.add(drillIcon)
|
||||
// TODO: override jade breakability test to include breaking power of drills on mining islands
|
||||
tooltip.append(Text.of("Breaking Power 6/7/8/9/10")) // TODO: Use NEU API/add new data for breaking power
|
||||
tooltip.replace(Identifier.of("minecraft", type), Text.literal("Gemstone $type of $replacement y")) // this doesnt work
|
||||
}
|
||||
}
|
||||
|
||||
override fun getUid(): Identifier {
|
||||
return "gemstone_${type}_${replacement}".jadeId()
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package moe.nea.firmament.compat.jade
|
||||
|
||||
import snownee.jade.api.BlockAccessor
|
||||
import snownee.jade.api.IBlockComponentProvider
|
||||
import snownee.jade.api.ITooltip
|
||||
import snownee.jade.api.config.IPluginConfig
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import moe.nea.firmament.util.SBData
|
||||
|
||||
class HardstoneProvider : IBlockComponentProvider {
|
||||
override fun appendTooltip(tooltip: ITooltip, accessor: BlockAccessor, config: IPluginConfig) {
|
||||
if (SBData.isOnSkyblock) {
|
||||
tooltip.add(drillIcon)
|
||||
// TODO: override jade breakability test to include breaking power of drills on mining islands
|
||||
tooltip.append(Text.of("Breaking Power 5"))
|
||||
tooltip.replace(Identifier.of("minecraft", "stone"), Text.literal("Hard Stone")) // this doesnt work
|
||||
}
|
||||
}
|
||||
|
||||
override fun getUid(): Identifier {
|
||||
return "hardstone".jadeId()
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package moe.nea.firmament.compat.jade
|
||||
|
||||
import snownee.jade.api.BlockAccessor
|
||||
import snownee.jade.api.IBlockComponentProvider
|
||||
import snownee.jade.api.ITooltip
|
||||
import snownee.jade.api.config.IPluginConfig
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import moe.nea.firmament.util.SBData
|
||||
|
||||
class MithrilProvider(val type: String) : IBlockComponentProvider {
|
||||
override fun appendTooltip(tooltip: ITooltip, accessor: BlockAccessor, config: IPluginConfig) {
|
||||
if (SBData.isOnSkyblock) { // why is there no utility to check if we are on an island with mithril am i dumb
|
||||
tooltip.add(drillIcon)
|
||||
tooltip.append(Text.of("Breaking Power 5"))
|
||||
tooltip.replace(Identifier.of("minecraft", type), Text.literal("Mithril $type")) // this doesnt work
|
||||
}
|
||||
}
|
||||
|
||||
override fun getUid(): Identifier {
|
||||
return "mithril_$type".jadeId()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package moe.nea.firmament.mixins.compat.jade;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import snownee.jade.api.ui.Element;
|
||||
import snownee.jade.api.ui.IElement;
|
||||
|
||||
@Mixin(Element.class)
|
||||
public interface ElementAccessor {
|
||||
@Accessor("align")
|
||||
IElement.Align getAlign_firmament();
|
||||
}
|
||||
@@ -2,6 +2,10 @@ package moe.nea.firmament.repo
|
||||
|
||||
import io.github.moulberry.repo.IReloadable
|
||||
import io.github.moulberry.repo.NEURepository
|
||||
import io.github.moulberry.repo.data.NEUItem
|
||||
import java.util.Collections
|
||||
import java.util.NavigableMap
|
||||
import java.util.TreeMap
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
import kotlinx.serialization.serializer
|
||||
@@ -19,14 +23,31 @@ import moe.nea.firmament.util.SkyBlockIsland
|
||||
import moe.nea.firmament.util.SkyblockId
|
||||
import moe.nea.firmament.util.mc.FirmamentDataComponentTypes
|
||||
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||
import moe.nea.firmament.util.skyblockId
|
||||
|
||||
class MiningRepoData : IReloadable {
|
||||
var customMiningAreas: Map<SkyBlockIsland, CustomMiningArea> = mapOf()
|
||||
private set
|
||||
var customMiningBlocks: List<CustomMiningBlock> = listOf()
|
||||
private set
|
||||
var toolsByBreakingPower: NavigableMap<BreakingPowerKey, NEUItem> = Collections.emptyNavigableMap()
|
||||
private set
|
||||
|
||||
|
||||
data class BreakingPowerKey(
|
||||
val breakingPower: Int,
|
||||
val itemId: SkyblockId? = null
|
||||
) {
|
||||
companion object {
|
||||
val COMPARATOR: Comparator<BreakingPowerKey> =
|
||||
Comparator
|
||||
.comparingInt<BreakingPowerKey> { it.breakingPower }
|
||||
.thenComparing(Comparator.comparing(
|
||||
{ it.itemId },
|
||||
nullsFirst(Comparator.naturalOrder<SkyblockId>())))
|
||||
}
|
||||
}
|
||||
|
||||
override fun reload(repo: NEURepository) {
|
||||
customMiningAreas = repo.file("mining/custom_mining_areas.json")
|
||||
?.kJson(serializer()) ?: mapOf()
|
||||
@@ -35,6 +56,18 @@ class MiningRepoData : IReloadable {
|
||||
.filter { it.path.endsWith(".json") }
|
||||
.map { it.kJson(serializer<CustomMiningBlock>()) }
|
||||
.toList()
|
||||
toolsByBreakingPower = Collections.unmodifiableNavigableMap(
|
||||
repo.items.items
|
||||
.values
|
||||
.asSequence()
|
||||
.filter { it.breakingPower > 0 }
|
||||
.associateTo(TreeMap<BreakingPowerKey, NEUItem>(BreakingPowerKey.COMPARATOR)) {
|
||||
BreakingPowerKey(it.breakingPower, it.skyblockId) to it
|
||||
})
|
||||
}
|
||||
|
||||
fun getToolsThatCanBreak(breakingPower: Int): Collection<NEUItem> {
|
||||
return toolsByBreakingPower.tailMap(BreakingPowerKey(breakingPower, null), true).values
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -99,7 +99,7 @@ object MC {
|
||||
inline val soundManager get() = instance.soundManager
|
||||
inline val player: ClientPlayerEntity? get() = TestUtil.unlessTesting { instance.player }
|
||||
inline val camera: Entity? get() = instance.cameraEntity
|
||||
inline val stackInHand: ItemStack? get() = player?.inventory?.mainHandStack
|
||||
inline val stackInHand: ItemStack get() = player?.inventory?.mainHandStack ?: ItemStack.EMPTY
|
||||
inline val guiAtlasManager get() = instance.guiAtlasManager
|
||||
inline val world: ClientWorld? get() = TestUtil.unlessTesting { instance.world }
|
||||
inline val playerName: String? get() = player?.name?.unformattedString
|
||||
|
||||
@@ -34,7 +34,7 @@ import moe.nea.firmament.util.json.DashlessUUIDSerializer
|
||||
*/
|
||||
@JvmInline
|
||||
@Serializable
|
||||
value class SkyblockId(val neuItem: String) {
|
||||
value class SkyblockId(val neuItem: String) : Comparable<SkyblockId> {
|
||||
val identifier
|
||||
get() = Identifier.of("skyblockitem",
|
||||
neuItem.lowercase().replace(";", "__")
|
||||
@@ -48,6 +48,10 @@ value class SkyblockId(val neuItem: String) {
|
||||
return neuItem
|
||||
}
|
||||
|
||||
override fun compareTo(other: SkyblockId): Int {
|
||||
return neuItem.compareTo(other.neuItem)
|
||||
}
|
||||
|
||||
/**
|
||||
* A bazaar stock item id, as returned by the HyPixel bazaar api endpoint.
|
||||
* These are not equivalent to the in-game ids, or the NEU repo ids, and in fact, do not refer to items, but instead
|
||||
|
||||
Reference in New Issue
Block a user