aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin')
-rw-r--r--src/main/kotlin/features/debug/PowerUserTools.kt1
-rw-r--r--src/main/kotlin/features/debug/itemeditor/ItemExporter.kt70
-rw-r--r--src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt14
-rw-r--r--src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt40
-rw-r--r--src/main/kotlin/util/SkyblockId.kt7
-rw-r--r--src/main/kotlin/util/StringUtil.kt6
6 files changed, 117 insertions, 21 deletions
diff --git a/src/main/kotlin/features/debug/PowerUserTools.kt b/src/main/kotlin/features/debug/PowerUserTools.kt
index 7c1df3f..1a7b2cf 100644
--- a/src/main/kotlin/features/debug/PowerUserTools.kt
+++ b/src/main/kotlin/features/debug/PowerUserTools.kt
@@ -59,6 +59,7 @@ object PowerUserTools : FirmamentFeature {
val exportItemStackToRepo by keyBindingWithDefaultUnbound("export-item-stack")
val exportUIRecipes by keyBindingWithDefaultUnbound("export-recipe")
val exportNpcLocation by keyBindingWithDefaultUnbound("export-npc-location")
+ val highlightNonOverlayItems by toggle("highlight-non-overlay") { false }
}
override val config
diff --git a/src/main/kotlin/features/debug/itemeditor/ItemExporter.kt b/src/main/kotlin/features/debug/itemeditor/ItemExporter.kt
index 37875fb..c521b5a 100644
--- a/src/main/kotlin/features/debug/itemeditor/ItemExporter.kt
+++ b/src/main/kotlin/features/debug/itemeditor/ItemExporter.kt
@@ -1,6 +1,5 @@
package moe.nea.firmament.features.debug.itemeditor
-import com.mojang.brigadier.arguments.StringArgumentType
import kotlinx.coroutines.launch
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonObject
@@ -19,13 +18,14 @@ import net.minecraft.nbt.NbtString
import net.minecraft.text.Text
import moe.nea.firmament.Firmament
import moe.nea.firmament.annotations.Subscribe
+import moe.nea.firmament.commands.RestArgumentType
import moe.nea.firmament.commands.get
-import moe.nea.firmament.commands.suggestsList
import moe.nea.firmament.commands.thenArgument
import moe.nea.firmament.commands.thenExecute
import moe.nea.firmament.commands.thenLiteral
import moe.nea.firmament.events.CommandEvent
import moe.nea.firmament.events.HandledScreenKeyPressedEvent
+import moe.nea.firmament.events.SlotRenderEvents
import moe.nea.firmament.features.debug.DeveloperFeatures
import moe.nea.firmament.features.debug.ExportedTestConstantMeta
import moe.nea.firmament.features.debug.PowerUserTools
@@ -40,6 +40,7 @@ import moe.nea.firmament.util.mc.SNbtFormatter.Companion.toPrettyString
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
import moe.nea.firmament.util.mc.loreAccordingToNbt
import moe.nea.firmament.util.mc.toNbtList
+import moe.nea.firmament.util.render.drawGuiTexture
import moe.nea.firmament.util.setSkyBlockId
import moe.nea.firmament.util.skyBlockId
import moe.nea.firmament.util.tr
@@ -47,6 +48,7 @@ import moe.nea.firmament.util.tr
object ItemExporter {
fun exportItem(itemStack: ItemStack): Text {
+ nonOverlayCache.clear()
val exporter = LegacyItemExporter.createExporter(itemStack)
var json = exporter.exportJson()
val fileName = json.jsonObject["internalname"]!!.jsonPrimitive.content
@@ -116,25 +118,42 @@ object ItemExporter {
fun onCommand(event: CommandEvent.SubCommand) {
event.subcommand(DeveloperFeatures.DEVELOPER_SUBCOMMAND) {
thenLiteral("reexportlore") {
- thenArgument("itemid", StringArgumentType.string()) { itemid ->
- suggestsList { RepoManager.neuRepo.items.items.keys }
+ thenArgument("itemid", RestArgumentType) { itemid ->
+ suggests { ctx, builder ->
+ val spaceIndex = builder.remaining.lastIndexOf(" ")
+ val (before, after) =
+ if (spaceIndex < 0) Pair("", builder.remaining)
+ else Pair(
+ builder.remaining.substring(0, spaceIndex + 1),
+ builder.remaining.substring(spaceIndex + 1)
+ )
+ RepoManager.neuRepo.items.items.keys
+ .asSequence()
+ .filter { it.startsWith(after, ignoreCase = true) }
+ .forEach {
+ builder.suggest(before + it)
+ }
+
+ builder.buildFuture()
+ }
thenExecute {
- val itemid = SkyblockId(get(itemid))
- if (pathFor(itemid).notExists()) {
+ for (itemid in get(itemid).split(" ").map { SkyblockId(it) }) {
+ if (pathFor(itemid).notExists()) {
+ MC.sendChat(
+ tr(
+ "firmament.repo.export.relore.fail",
+ "Could not find json file to relore for ${itemid}"
+ )
+ )
+ }
+ fixLoreNbtFor(itemid)
MC.sendChat(
tr(
- "firmament.repo.export.relore.fail",
- "Could not find json file to relore for ${itemid}"
+ "firmament.repo.export.relore",
+ "Updated lore / display name for $itemid"
)
)
}
- fixLoreNbtFor(itemid)
- MC.sendChat(
- tr(
- "firmament.repo.export.relore",
- "Updated lore / display name for $itemid"
- )
- )
}
}
thenLiteral("all") {
@@ -188,6 +207,27 @@ object ItemExporter {
}
}
+ val nonOverlayCache = mutableMapOf<SkyblockId, Boolean>()
+
+ @Subscribe
+ fun onRender(event: SlotRenderEvents.Before) {
+ if (!PowerUserTools.TConfig.highlightNonOverlayItems) {
+ return
+ }
+ val stack = event.slot.stack ?: return
+ val isExported = nonOverlayCache.getOrPut(stack.skyBlockId ?: return) {
+ RepoDownloadManager.repoSavedLocation.resolve("itemsOverlay")
+ .resolve(ExportedTestConstantMeta.current.dataVersion.toString())
+ .resolve("${stack.skyBlockId}.snbt")
+ .exists()
+ }
+ if (!isExported)
+ event.context.drawGuiTexture(
+ Firmament.identifier("selected_pet_background"),
+ event.slot.x, event.slot.y, 16, 16,
+ )
+ }
+
fun exportStub(skyblockId: SkyblockId, title: String, extra: (ItemStack) -> Unit = {}) {
exportItem(ItemStack(Items.PLAYER_HEAD).also {
it.displayNameAccordingToNbt = Text.literal(title)
diff --git a/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt b/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt
index c0f48ca..bc8c618 100644
--- a/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt
+++ b/src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt
@@ -9,6 +9,7 @@ import moe.nea.firmament.Firmament
import moe.nea.firmament.repo.ExpensiveItemCacheApi
import moe.nea.firmament.repo.ItemCache
import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.StringUtil.camelWords
/**
* Load data based on [prismarine.js' 1.8 item data](https://github.com/PrismarineJS/minecraft-data/blob/master/data/pc/1.8/items.json)
@@ -58,6 +59,7 @@ object LegacyItemData {
val enchantmentLut = enchantmentData.associateBy { Identifier.ofVanilla(it.name) }
val itemDat = getLegacyData<List<ItemData>>("items")
+
@OptIn(ExpensiveItemCacheApi::class) // This is fine, we get loaded in a thread.
val itemLut = itemDat.flatMap { item ->
item.allVariants().map { legacyItemType ->
@@ -72,4 +74,16 @@ object LegacyItemData {
}
}.toMap()
+ @Serializable
+ data class LegacyEffect(
+ val id: Int,
+ val name: String,
+ val displayName: String,
+ val type: String
+ )
+
+ val effectList = getLegacyData<List<LegacyEffect>>("effects")
+ .associateBy {
+ it.name.camelWords().map { it.trim().lowercase() }.joinToString("_")
+ }
}
diff --git a/src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt b/src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt
index 3cd1ce8..ad03b16 100644
--- a/src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt
+++ b/src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt
@@ -7,9 +7,11 @@ import kotlinx.serialization.json.put
import kotlin.concurrent.thread
import net.minecraft.component.DataComponentTypes
import net.minecraft.item.ItemStack
+import net.minecraft.nbt.NbtByte
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtElement
import net.minecraft.nbt.NbtInt
+import net.minecraft.nbt.NbtList
import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.NbtString
import net.minecraft.text.Text
@@ -36,8 +38,9 @@ import moe.nea.firmament.util.unformattedString
class LegacyItemExporter private constructor(var itemStack: ItemStack) {
init {
- require(!itemStack.isEmpty)
+ require(!itemStack.isEmpty)
}
+
var lore = itemStack.loreAccordingToNbt
var name = itemStack.displayNameAccordingToNbt
val extraAttribs = itemStack.extraAttributes.copy()
@@ -133,24 +136,55 @@ class LegacyItemExporter private constructor(var itemStack: ItemStack) {
legacyNbt.put("HideFlags", NbtInt.of(254))
copyUnbreakable()
copyItemModel()
+ copyPotion()
copyExtraAttributes()
copyLegacySkullNbt()
copyDisplay()
+ copyColour()
copyEnchantments()
copyEnchantGlint()
// TODO: copyDisplay
}
+ private fun copyPotion() {
+ val effects = itemStack.get(DataComponentTypes.POTION_CONTENTS) ?: return
+ legacyNbt.put("CustomPotionEffects", NbtList().also {
+ effects.effects.forEach { effect ->
+ val effectId = effect.effectType.key.get().value.path
+ val duration = effect.duration
+ val legacyId = LegacyItemData.effectList[effectId]!!
+
+ it.add(NbtCompound().apply {
+ put("Ambient", NbtByte.of(false))
+ put("Duration", NbtInt.of(duration))
+ put("Id", NbtByte.of(legacyId.id.toByte()))
+ put("Amplifier", NbtByte.of(effect.amplifier.toByte()))
+ })
+ }
+ })
+ }
+
+ fun NbtCompound.getOrPutCompound(name: String): NbtCompound {
+ val compound = getCompoundOrEmpty(name)
+ put(name, compound)
+ return compound
+ }
+
+ private fun copyColour() {
+ val leatherTint = itemStack.get(DataComponentTypes.DYED_COLOR) ?: return
+ legacyNbt.getOrPutCompound("display").put("color", NbtInt.of(leatherTint.rgb))
+ }
+
private fun copyItemModel() {
val itemModel = itemStack.get(DataComponentTypes.ITEM_MODEL) ?: return
legacyNbt.put("ItemModel", NbtString.of(itemModel.toString()))
}
private fun copyDisplay() {
- legacyNbt.put("display", NbtCompound().apply {
+ legacyNbt.getOrPutCompound("display").apply {
put("Lore", lore.map { NbtString.of(it.getLegacyFormatString(trimmed = true)) }.toNbtList())
putString("Name", name.getLegacyFormatString(trimmed = true))
- })
+ }
}
fun exportModernSnbt(): NbtElement {
diff --git a/src/main/kotlin/util/SkyblockId.kt b/src/main/kotlin/util/SkyblockId.kt
index b4d583a..051ca86 100644
--- a/src/main/kotlin/util/SkyblockId.kt
+++ b/src/main/kotlin/util/SkyblockId.kt
@@ -251,10 +251,11 @@ val ItemStack.skyBlockId: SkyblockId?
val potionName = extraAttributes.getString("potion_name").getOrNull()
val potionLevel = extraAttributes.getInt("potion_level").getOrNull()
val potionType = extraAttributes.getString("potion_type").getOrNull()
+ fun String.potionNormalize() = uppercase().replace(" ", "_")
when {
- potionName != null -> SkyblockId("POTION_${potionName.uppercase()};$potionLevel")
- potionData != null -> SkyblockId("POTION_${potionData.uppercase()};$potionLevel")
- potionType != null -> SkyblockId("POTION_${potionType.uppercase()}")
+ potionName != null -> SkyblockId("POTION_${potionName.potionNormalize()};$potionLevel")
+ potionData != null -> SkyblockId("POTION_${potionData.potionNormalize()};$potionLevel")
+ potionType != null -> SkyblockId("POTION_${potionType.potionNormalize()}")
else -> SkyblockId("WATER_BOTTLE")
}
}
diff --git a/src/main/kotlin/util/StringUtil.kt b/src/main/kotlin/util/StringUtil.kt
index dc98dc0..50c5367 100644
--- a/src/main/kotlin/util/StringUtil.kt
+++ b/src/main/kotlin/util/StringUtil.kt
@@ -5,6 +5,12 @@ object StringUtil {
return splitToSequence(" ") // TODO: better boundaries
}
+ fun String.camelWords(): Sequence<String> {
+ return splitToSequence(camelWordStart)
+ }
+
+ private val camelWordStart = Regex("((?<=[a-z])(?=[A-Z]))| ")
+
fun parseIntWithComma(string: String): Int {
return string.replace(",", "").toInt()
}