Make REI aware of SkyBlock item ids

This commit is contained in:
nea
2023-05-04 15:12:56 +02:00
parent bfcb02e52b
commit f2aa75f7c1
6 changed files with 126 additions and 26 deletions

View File

@@ -0,0 +1,14 @@
package moe.nea.notenoughupdates.mixins.accessor;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.screen.slot.Slot;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(HandledScreen.class)
public interface AccessorHandledScreen {
@Accessor("focusedSlot")
@Nullable
Slot getFocusedSlot_NEU();
}

View File

@@ -1,15 +1,23 @@
package moe.nea.notenoughupdates.rei
import dev.architectury.event.CompoundEventResult
import io.github.moulberry.repo.data.NEUItem
import me.shedaniel.math.Point
import me.shedaniel.rei.api.client.plugins.REIClientPlugin
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry
import me.shedaniel.rei.api.client.registry.screen.FocusedStackProvider
import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry
import me.shedaniel.rei.api.common.entry.EntryStack
import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes
import moe.nea.notenoughupdates.repo.ItemCache.asItemStack
import moe.nea.notenoughupdates.repo.RepoManager
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.item.ItemStack
import net.minecraft.util.Identifier
import moe.nea.notenoughupdates.mixins.accessor.AccessorHandledScreen
import moe.nea.notenoughupdates.repo.ItemCache.asItemStack
import moe.nea.notenoughupdates.repo.RepoManager
import moe.nea.notenoughupdates.util.skyBlockId
class NEUReiPlugin : REIClientPlugin {
@@ -26,6 +34,21 @@ class NEUReiPlugin : REIClientPlugin {
registry.register(SKYBLOCK_ITEM_TYPE_ID, SBItemEntryDefinition)
}
override fun registerScreens(registry: ScreenRegistry) {
registry.registerFocusedStack(object : FocusedStackProvider {
override fun provide(screen: Screen?, mouse: Point?): CompoundEventResult<EntryStack<*>> {
if (screen !is HandledScreen<*>) return CompoundEventResult.pass()
screen as AccessorHandledScreen
val focusedSlot = screen.focusedSlot_NEU ?: return CompoundEventResult.pass()
val item = focusedSlot.stack ?: return CompoundEventResult.pass()
val skyblockId = item.skyBlockId ?: return CompoundEventResult.pass()
val neuItem = RepoManager.getNEUItem(skyblockId) ?: return CompoundEventResult.interrupt(false, null)
return CompoundEventResult.interruptTrue(EntryStack.of(SBItemEntryDefinition, neuItem))
}
override fun getPriority(): Double = 1_000_000.0
})
}
override fun registerEntries(registry: EntryRegistry) {
RepoManager.neuRepo.items?.items?.values?.forEach {

View File

@@ -1,6 +1,7 @@
package moe.nea.notenoughupdates.rei
import io.github.moulberry.repo.data.NEUItem
import java.util.stream.Stream
import me.shedaniel.math.Rectangle
import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer
import me.shedaniel.rei.api.client.gui.widgets.Tooltip
@@ -11,15 +12,17 @@ import me.shedaniel.rei.api.common.entry.comparison.ComparisonContext
import me.shedaniel.rei.api.common.entry.type.EntryDefinition
import me.shedaniel.rei.api.common.entry.type.EntryType
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtCompound
import net.minecraft.registry.tag.TagKey
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import moe.nea.notenoughupdates.rei.NEUReiPlugin.Companion.asItemEntry
import moe.nea.notenoughupdates.repo.ItemCache.asItemStack
import moe.nea.notenoughupdates.repo.ItemCache.getIdentifier
import net.minecraft.client.util.math.MatrixStack
import net.minecraft.item.ItemStack
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import java.util.stream.Stream
import net.minecraft.registry.tag.TagKey
import moe.nea.notenoughupdates.repo.RepoManager
import moe.nea.notenoughupdates.util.SkyblockId
object SBItemEntryDefinition : EntryDefinition<NEUItem> {
override fun equals(o1: NEUItem?, o2: NEUItem?, context: ComparisonContext?): Boolean {
@@ -57,8 +60,21 @@ object SBItemEntryDefinition : EntryDefinition<NEUItem> {
}
override fun getSerializer(): EntrySerializer<NEUItem>? {
return null
override fun getSerializer(): EntrySerializer<NEUItem?> {
return object : EntrySerializer<NEUItem?> {
override fun supportSaving(): Boolean = true
override fun supportReading(): Boolean = true
override fun read(tag: NbtCompound): NEUItem? {
return RepoManager.getNEUItem(SkyblockId(tag.getString("SKYBLOCK_ID")))
}
override fun save(entry: EntryStack<NEUItem?>, value: NEUItem?): NbtCompound {
return NbtCompound().apply {
putString("SKYBLOCK_ID", value?.skyblockItemId ?: "null")
}
}
}
}
override fun getTagsFor(entry: EntryStack<NEUItem>?, value: NEUItem?): Stream<out TagKey<*>>? {
@@ -70,6 +86,7 @@ object SBItemEntryDefinition : EntryDefinition<NEUItem> {
}
override fun hash(entry: EntryStack<NEUItem>, value: NEUItem, context: ComparisonContext): Long {
// Repo items are immutable, and get replaced entirely when loaded from disk
return System.identityHashCode(value) * 31L
}

View File

@@ -14,6 +14,7 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
import net.minecraft.client.MinecraftClient
import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket
import net.minecraft.text.Text
import moe.nea.notenoughupdates.util.SkyblockId
object RepoManager : DataHolder<RepoManager.Config>(serializer(), "repo", ::Config) {
@Serializable
@@ -55,6 +56,8 @@ object RepoManager : DataHolder<RepoManager.Config>(serializer(), "repo", ::Conf
})
}
fun getNEUItem(skyblockId: SkyblockId) = neuRepo.items.getItemBySkyblockId(skyblockId.neuItem)
fun launchAsyncUpdate(force: Boolean = false) {
NotEnoughUpdates.coroutineScope.launch {
progressBar.reportProgress("Downloading", 0, null)

View File

@@ -0,0 +1,42 @@
package moe.nea.notenoughupdates.util
import io.github.moulberry.repo.data.Rarity
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NbtCompound
@JvmInline
value class SkyblockId(val neuItem: String)
@Serializable
data class HypixelPetInfo(
val type: String,
val tier: Rarity,
) {
val skyblockId get() = SkyblockId("${type.uppercase()};${tier}")
}
private val jsonparser = Json { ignoreUnknownKeys = true }
val ItemStack.extraAttributes: NbtCompound
get() = getOrCreateSubNbt("ExtraAttributes")
val ItemStack.skyBlockId: SkyblockId?
get() {
when (val id = extraAttributes.getString("id")) {
"PET" -> {
val jsonString = extraAttributes.getString("petInfo")
if (jsonString.isNullOrBlank()) return null
val petInfo =
runCatching { jsonparser.decodeFromString<HypixelPetInfo>(jsonString) }
.getOrElse { return null }
return petInfo.skyblockId
}
// TODO: RUNE, ENCHANTED_BOOK, PARTY_HAT_CRAB{,_ANIMATED}, ABICASE
else -> {
return SkyblockId(id)
}
}
}

View File

@@ -1,19 +1,20 @@
{
"required": true,
"plugin": "moe.nea.notenoughupdates.init.MixinPlugin",
"package": "moe.nea.notenoughupdates.mixins",
"compatibilityLevel": "JAVA_16",
"client": [
"MixinDownloadingTerrainScreen",
"MixinMessageHandler",
"MixinMinecraft",
"MixinWorldRenderer",
"devenv.DisableCommonPacketWarnings"
],
"mixins": [
"devenv.DisableInvalidFishingHook"
],
"injectors": {
"defaultRequire": 1
"required": true,
"plugin": "moe.nea.notenoughupdates.init.MixinPlugin",
"package": "moe.nea.notenoughupdates.mixins",
"compatibilityLevel": "JAVA_16",
"client": [
"MixinDownloadingTerrainScreen",
"MixinMessageHandler",
"MixinMinecraft",
"MixinWorldRenderer",
"accessor.AccessorHandledScreen",
"devenv.DisableCommonPacketWarnings"
],
"mixins": [
"devenv.DisableInvalidFishingHook"
],
"injectors": {
"defaultRequire": 1
}
}