diff options
-rw-r--r-- | build.gradle.kts | 35 | ||||
-rw-r--r-- | buildSrc/build.gradle.kts | 30 | ||||
-rw-r--r-- | buildSrc/src/FabricModTransform.kt | 80 | ||||
-rw-r--r-- | gradle/libs.versions.toml | 5 | ||||
-rw-r--r-- | src/main/kotlin/features/debug/PowerUserTools.kt | 1 | ||||
-rw-r--r-- | src/main/kotlin/features/debug/itemeditor/ItemExporter.kt | 70 | ||||
-rw-r--r-- | src/main/kotlin/features/debug/itemeditor/LegacyItemData.kt | 14 | ||||
-rw-r--r-- | src/main/kotlin/features/debug/itemeditor/LegacyItemExporter.kt | 40 | ||||
-rw-r--r-- | src/main/kotlin/util/SkyblockId.kt | 7 | ||||
-rw-r--r-- | src/main/kotlin/util/StringUtil.kt | 6 | ||||
-rw-r--r-- | src/main/resources/legacy_data/effects.json | 140 | ||||
-rw-r--r-- | testagent/build.gradle.kts | 2 |
12 files changed, 381 insertions, 49 deletions
diff --git a/build.gradle.kts b/build.gradle.kts index 3a72ed0..065925a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,6 +6,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import com.google.common.hash.Hashing import com.google.devtools.ksp.gradle.KspAATask import com.google.gson.Gson @@ -29,7 +30,6 @@ plugins { // alias(libs.plugins.loom) // TODO: use arch loom once they update to 1.8 id("fabric-loom") version "1.10.1" - alias(libs.plugins.shadow) id("moe.nea.licenseextractificator") alias(libs.plugins.mcAutoTranslations) } @@ -130,6 +130,9 @@ val collectTranslations by tasks.registering(CollectTranslations::class) { this.classes.from(sourceSets.main.get().kotlin.classesDirectory) } +val shadowJar = tasks.register("shadowJar", ShadowJar::class) +val mergedSourceSetsJar = tasks.register("mergedSourceSetsJar", ShadowJar::class) + val compatSourceSets: MutableSet<SourceSet> = mutableSetOf() fun createIsolatedSourceSet(name: String, path: String = "compat/$name", isEnabled: Boolean = true): SourceSet { val ss = sourceSets.create(name) { @@ -178,7 +181,7 @@ fun createIsolatedSourceSet(name: String, path: String = "compat/$name", isEnabl (ss.implementationConfigurationName)(project.files(tasks.compileKotlin.map { it.destinationDirectory })) (ss.implementationConfigurationName)(project.files(tasks.compileJava.map { it.destinationDirectory })) } - tasks.shadowJar { + mergedSourceSetsJar.configure { from(ss.output) } // TODO: figure out why inheritances are not being respected by tiny kotlin names @@ -268,8 +271,7 @@ dependencies { nonModImplentation("com.google.auto.service:auto-service-annotations:1.1.1") ksp("dev.zacsweers.autoservice:auto-service-ksp:1.2.0") include(libs.manninghamMills) - include(libs.moulconfig) - + shadowMe(libs.moulconfig) annotationProcessor(libs.mixinextras) nonModImplentation(libs.mixinextras) @@ -437,22 +439,33 @@ tasks.jar { destinationDirectory.set(layout.buildDirectory.dir("badjars")) archiveClassifier.set("slim") } - -tasks.shadowJar { +mergedSourceSetsJar.configure { + from(zipTree(tasks.jar.flatMap { it.archiveFile })) + destinationDirectory.set(layout.buildDirectory.dir("badjars")) + archiveClassifier.set("merged-source-sets") + mergeServiceFiles() +} +shadowJar.configure { + from(zipTree(tasks.remapJar.flatMap { it.archiveFile })) configurations = listOf(shadowMe) - archiveClassifier.set("dev") + archiveClassifier.set("") relocate("io.github.moulberry.repo", "moe.nea.firmament.deps.repo") - destinationDirectory.set(layout.buildDirectory.dir("badjars")) + relocate("io.github.notenoughupdates.moulconfig", "moe.nea.firmament.deps.moulconfig") mergeServiceFiles() + transform<FabricModTransform>() } tasks.remapJar { // injectAccessWidener.set(true) - inputFile.set(tasks.shadowJar.flatMap { it.archiveFile }) - dependsOn(tasks.shadowJar) - archiveClassifier.set("") + inputFile.set(mergedSourceSetsJar.flatMap { it.archiveFile }) + dependsOn(mergedSourceSetsJar) + destinationDirectory.set(layout.buildDirectory.dir("badjars")) + archiveClassifier.set("remapped") } +tasks.assemble { dependsOn(shadowJar) } + + tasks.processResources { val replacements = listOf( "version" to project.version.toString(), diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 54719bc..1b2542b 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,25 +3,27 @@ // SPDX-License-Identifier: CC0-1.0 plugins { - kotlin("jvm") version "2.1.0" - `kotlin-dsl` + kotlin("jvm") version "2.1.0" + `kotlin-dsl` } repositories { - mavenCentral() - maven { - name = "jitpack" - url = uri("https://jitpack.io") - } + mavenCentral() + maven { + name = "jitpack" + url = uri("https://jitpack.io") + } } dependencies { - implementation("com.github.romangraef:neaslicenseextractificator:1.1.0") - implementation("com.google.code.gson:gson:2.10.1") + implementation("com.github.romangraef:neaslicenseextractificator:1.1.0") + api("com.gradleup.shadow:shadow-gradle-plugin:9.0.0-rc1") + implementation("net.fabricmc:access-widener:2.1.0") + implementation("com.google.code.gson:gson:2.10.1") } sourceSets { - main { - kotlin { - srcDir(file("src")) - } - } + main { + kotlin { + srcDir(file("src")) + } + } } diff --git a/buildSrc/src/FabricModTransform.kt b/buildSrc/src/FabricModTransform.kt new file mode 100644 index 0000000..53affbe --- /dev/null +++ b/buildSrc/src/FabricModTransform.kt @@ -0,0 +1,80 @@ +import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransformer +import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext +import com.google.gson.Gson +import com.google.gson.JsonObject +import com.google.gson.JsonPrimitive +import java.io.Serializable +import net.fabricmc.accesswidener.AccessWidenerReader +import net.fabricmc.accesswidener.AccessWidenerWriter +import org.apache.tools.zip.ZipEntry +import org.apache.tools.zip.ZipOutputStream +import org.gradle.api.file.FileTreeElement +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal + +open class FabricModTransform : ResourceTransformer { + + enum class AccessWidenerInclusion : Serializable { + ALL, + NONE, + } + + @get:Input + var mergeAccessWideners: AccessWidenerInclusion = AccessWidenerInclusion.ALL + + @get:Internal + internal var mergedFmj: JsonObject? = null + + @get:Internal + internal val foundAccessWideners = AccessWidenerWriter() + + @get:Internal + internal var foundAnyAccessWidener = false + + override fun canTransformResource(element: FileTreeElement): Boolean { + if (mergeAccessWideners == AccessWidenerInclusion.ALL && element.name.endsWith(".accesswidener")) + return true + return element.path == "fabric.mod.json" + } + + override fun transform(context: TransformerContext) { + if (context.path.endsWith(".accesswidener")) { + foundAnyAccessWidener = true + // TODO: allow filtering for only those mentioned in a fabric.mod.json, potentially + context.inputStream.use { stream -> + AccessWidenerReader(foundAccessWideners).read(stream.bufferedReader()) + } + return + } + // TODO: mixins.json relocations + val fmj = context.inputStream.use { stream -> + Gson().fromJson(stream.bufferedReader(), JsonObject::class.java) + } + val mergedFmj = this.mergedFmj + println("${fmj["id"]} is first? ${mergedFmj == null}") + if (mergedFmj == null) { + this.mergedFmj = fmj + } else { + // TODO: merge stuff + } + } + + override fun hasTransformedResource(): Boolean { + return mergedFmj != null + } + + override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) { + val mergedFmj = mergedFmj!! + if (foundAnyAccessWidener) { + val awFile = mergedFmj["accessWidener"] + require(awFile is JsonPrimitive && awFile.isString) + os.putNextEntry(ZipEntry(awFile.asString)) + os.write(foundAccessWideners.write()) + os.closeEntry() + } + os.putNextEntry(ZipEntry("fabric.mod.json")) + os.write(mergedFmj.toString().toByteArray()) + os.closeEntry() + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e4f39e8..f536faf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,6 +40,8 @@ ncr = "Fabric-1.21.5-v2.12.0" # Update from https://modrinth.com/mod/female-gender/versions?l=fabric femalegender = "4.3.4+1.21.5" +shadow = "8.3.8" + # Update from https://modrinth.com/mod/explosive-enhancement/versions?l=fabric explosiveenhancement = "1.2.3-1.21.0" @@ -135,7 +137,7 @@ femalegender = { module = "maven.modrinth:female-gender", version.ref = "femaleg jade = { module = "maven.modrinth:jade", version.ref = "jade" } yacl = { module = "dev.isxander:yet-another-config-lib", version.ref = "yacl" } basicMath = { module = "me.shedaniel.cloth:basic-math", version.ref = "basicMath" } - +shadow = { module = "com.gradleup.shadow:shadow-gradle-plugin", version.ref = "shadow" } classTransform-mixinsTranslator = { module = "net.lenni0451.classtransform:mixinstranslator", version.ref = "classtransform" } classTransform-core = { module = "net.lenni0451.classtransform:core", version.ref = "classtransform" } @@ -162,5 +164,4 @@ kotlin_plugin_serialization = { id = "org.jetbrains.kotlin.plugin.serialization" kotlin_plugin_powerassert = { id = "org.jetbrains.kotlin.plugin.power-assert", version.ref = "kotlin" } kotlin_plugin_ksp = { id = "com.google.devtools.ksp", version.ref = "kotlin_ksp" } loom = { id = "dev.architectury.loom", version.ref = "loom" } -shadow = { id = "com.github.johnrengelman.shadow", version = "8.1.1" } mcAutoTranslations = { id = "moe.nea.mc-auto-translations", version.ref = "mcAutoTranslations" } 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() } diff --git a/src/main/resources/legacy_data/effects.json b/src/main/resources/legacy_data/effects.json new file mode 100644 index 0000000..0b885b5 --- /dev/null +++ b/src/main/resources/legacy_data/effects.json @@ -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" + } +] diff --git a/testagent/build.gradle.kts b/testagent/build.gradle.kts index 3bd8c8c..73eb583 100644 --- a/testagent/build.gradle.kts +++ b/testagent/build.gradle.kts @@ -1,6 +1,6 @@ plugins { java - alias(libs.plugins.shadow) + id("com.gradleup.shadow") } dependencies { implementation(libs.asm) |