fix: potion effects in exporter

This commit is contained in:
Linnea Gräf
2025-07-06 00:37:46 +02:00
parent 4140a24a0b
commit 44b817f7b9
5 changed files with 185 additions and 4 deletions

View File

@@ -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("_")
}
}

View File

@@ -7,11 +7,12 @@ 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.NbtPrimitive
import net.minecraft.nbt.NbtString
import net.minecraft.text.Text
import net.minecraft.util.Unit
@@ -135,6 +136,7 @@ class LegacyItemExporter private constructor(var itemStack: ItemStack) {
legacyNbt.put("HideFlags", NbtInt.of(254))
copyUnbreakable()
copyItemModel()
copyPotion()
copyExtraAttributes()
copyLegacySkullNbt()
copyDisplay()
@@ -144,6 +146,24 @@ class LegacyItemExporter private constructor(var itemStack: ItemStack) {
// 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)

View File

@@ -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")
}
}

View File

@@ -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()
}

View File

@@ -0,0 +1,140 @@
[
{
"id": 1,
"name": "Speed",
"displayName": "Speed",
"type": "good"
},
{
"id": 2,
"name": "Slowness",
"displayName": "Slowness",
"type": "bad"
},
{
"id": 3,
"name": "Haste",
"displayName": "Haste",
"type": "good"
},
{
"id": 4,
"name": "MiningFatigue",
"displayName": "Mining Fatigue",
"type": "bad"
},
{
"id": 5,
"name": "Strength",
"displayName": "Strength",
"type": "good"
},
{
"id": 6,
"name": "InstantHealth",
"displayName": "Instant Health",
"type": "good"
},
{
"id": 7,
"name": "InstantDamage",
"displayName": "Instant Damage",
"type": "bad"
},
{
"id": 8,
"name": "JumpBoost",
"displayName": "Jump Boost",
"type": "good"
},
{
"id": 9,
"name": "Nausea",
"displayName": "Nausea",
"type": "bad"
},
{
"id": 10,
"name": "Regeneration",
"displayName": "Regeneration",
"type": "good"
},
{
"id": 11,
"name": "Resistance",
"displayName": "Resistance",
"type": "good"
},
{
"id": 12,
"name": "FireResistance",
"displayName": "Fire Resistance",
"type": "good"
},
{
"id": 13,
"name": "WaterBreathing",
"displayName": "Water Breathing",
"type": "good"
},
{
"id": 14,
"name": "Invisibility",
"displayName": "Invisibility",
"type": "good"
},
{
"id": 15,
"name": "Blindness",
"displayName": "Blindness",
"type": "bad"
},
{
"id": 16,
"name": "NightVision",
"displayName": "Night Vision",
"type": "good"
},
{
"id": 17,
"name": "Hunger",
"displayName": "Hunger",
"type": "bad"
},
{
"id": 18,
"name": "Weakness",
"displayName": "Weakness",
"type": "bad"
},
{
"id": 19,
"name": "Poison",
"displayName": "Poison",
"type": "bad"
},
{
"id": 20,
"name": "Wither",
"displayName": "Wither",
"type": "bad"
},
{
"id": 21,
"name": "HealthBoost",
"displayName": "Health Boost",
"type": "good"
},
{
"id": 22,
"name": "Absorption",
"displayName": "Absorption",
"type": "good"
},
{
"id": 23,
"name": "Saturation",
"displayName": "Saturation",
"type": "good"
}
]