legacy tag parsing and transformation
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
package moe.nea.notenoughupdates
|
||||
|
||||
import net.minecraft.nbt.*
|
||||
import java.util.*
|
||||
|
||||
class LegacyTagParser private constructor(string: String) {
|
||||
data class TagParsingException(val baseString: String, val offset: Int, val mes0: String) :
|
||||
Exception("$mes0 at $offset in `$baseString`.")
|
||||
|
||||
class StringRacer(val backing: String) {
|
||||
var idx = 0
|
||||
val stack = Stack<Int>()
|
||||
|
||||
fun pushState() {
|
||||
stack.push(idx)
|
||||
}
|
||||
|
||||
fun popState() {
|
||||
idx = stack.pop()
|
||||
}
|
||||
|
||||
fun discardState() {
|
||||
stack.pop()
|
||||
}
|
||||
|
||||
fun peek(count: Int): String {
|
||||
return backing.substring(minOf(idx, backing.length), minOf(idx + count, backing.length))
|
||||
}
|
||||
|
||||
fun finished(): Boolean {
|
||||
return peek(1).isEmpty()
|
||||
}
|
||||
|
||||
fun peekReq(count: Int): String? {
|
||||
val p = peek(count)
|
||||
if (p.length != count)
|
||||
return null
|
||||
return p
|
||||
}
|
||||
|
||||
fun consumeCountReq(count: Int): String? {
|
||||
val p = peekReq(count)
|
||||
if (p != null)
|
||||
idx += count
|
||||
return p
|
||||
}
|
||||
|
||||
fun tryConsume(string: String): Boolean {
|
||||
val p = peek(string.length)
|
||||
if (p != string)
|
||||
return false
|
||||
idx += p.length
|
||||
return true
|
||||
}
|
||||
|
||||
fun consumeWhile(shouldConsumeThisString: (String) -> Boolean): String {
|
||||
var lastString: String = ""
|
||||
while (true) {
|
||||
val nextString = lastString + peek(1)
|
||||
if (!shouldConsumeThisString(nextString)) {
|
||||
return lastString
|
||||
}
|
||||
idx++
|
||||
lastString = nextString
|
||||
}
|
||||
}
|
||||
|
||||
fun expect(search: String, errorMessage: String) {
|
||||
if (!tryConsume(search))
|
||||
error(errorMessage)
|
||||
}
|
||||
|
||||
fun error(errorMessage: String): Nothing {
|
||||
throw TagParsingException(backing, idx, errorMessage)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val racer = StringRacer(string)
|
||||
val baseTag = parseTag()
|
||||
|
||||
companion object {
|
||||
val digitRange = '0'..'9'
|
||||
fun parse(string: String): CompoundTag {
|
||||
return LegacyTagParser(string).baseTag
|
||||
}
|
||||
}
|
||||
|
||||
fun skipWhitespace() {
|
||||
racer.consumeWhile { Character.isWhitespace(it.last()) } // Only check last since other chars are always checked before.
|
||||
}
|
||||
|
||||
fun parseTag(): CompoundTag {
|
||||
skipWhitespace()
|
||||
racer.expect("{", "Expected '{’ at start of tag")
|
||||
skipWhitespace()
|
||||
val tag = CompoundTag()
|
||||
while (!racer.tryConsume("}")) {
|
||||
skipWhitespace()
|
||||
val lhs = parseIdentifier()
|
||||
skipWhitespace()
|
||||
racer.expect(":", "Expected ':' after identifier in tag")
|
||||
skipWhitespace()
|
||||
val rhs = parseAny()
|
||||
tag.put(lhs, rhs)
|
||||
racer.tryConsume(",")
|
||||
skipWhitespace()
|
||||
}
|
||||
return tag
|
||||
}
|
||||
|
||||
private fun parseAny(): Tag {
|
||||
skipWhitespace()
|
||||
val nextChar = racer.peekReq(1) ?: racer.error("Expected new object, found EOF")
|
||||
return when {
|
||||
nextChar == "{" -> parseTag()
|
||||
nextChar == "[" -> parseList()
|
||||
nextChar == "\"" -> parseStringTag()
|
||||
nextChar.first() in (digitRange) -> parseNumericTag()
|
||||
else -> racer.error("Unexpected token found. Expected start of new element")
|
||||
}
|
||||
}
|
||||
|
||||
fun parseList(): ListTag {
|
||||
skipWhitespace()
|
||||
racer.expect("[", "Expected '[' at start of tag")
|
||||
skipWhitespace()
|
||||
val list = ListTag()
|
||||
while (!racer.tryConsume("]")) {
|
||||
skipWhitespace()
|
||||
racer.pushState()
|
||||
val lhs = racer.consumeWhile { it.all { it in digitRange } }
|
||||
skipWhitespace()
|
||||
if (!racer.tryConsume(":") || lhs.isEmpty()) { // No prefixed 0:
|
||||
racer.popState()
|
||||
list.add(parseAny()) // Reparse our number (or not a number) as actual tag
|
||||
} else {
|
||||
racer.discardState()
|
||||
skipWhitespace()
|
||||
list.add(parseAny()) // Ignore prefix indexes. They should not be generated out of order by any vanilla implementation (which is what NEU should export). Instead append where it appears in order.
|
||||
}
|
||||
skipWhitespace()
|
||||
racer.tryConsume(",")
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
fun parseQuotedString(): String {
|
||||
skipWhitespace()
|
||||
racer.expect("\"", "Expected '\"' at string start")
|
||||
val sb = StringBuilder()
|
||||
while (true) {
|
||||
when (val peek = racer.consumeCountReq(1)) {
|
||||
"\"" -> break
|
||||
"\\" -> {
|
||||
val escaped = racer.consumeCountReq(1) ?: racer.error("Unfinished backslash escape")
|
||||
if (escaped != "\"" && escaped != "\\") {
|
||||
// Surprisingly i couldn't find unicode escapes to be generated by the original minecraft 1.8.9 implementation
|
||||
racer.idx--
|
||||
racer.error("Invalid backslash escape '$escaped'")
|
||||
}
|
||||
sb.append(escaped)
|
||||
}
|
||||
null -> racer.error("Unfinished string")
|
||||
else -> {
|
||||
sb.append(peek)
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun parseStringTag(): StringTag {
|
||||
return StringTag.valueOf(parseQuotedString())
|
||||
}
|
||||
|
||||
object Patterns {
|
||||
val DOUBLE = "([-+]?[0-9]*\\.?[0-9]+)[d|D]".toRegex()
|
||||
val FLOAT = "([-+]?[0-9]*\\.?[0-9]+)[f|F]".toRegex()
|
||||
val BYTE = "([-+]?[0-9]+)[b|B]".toRegex()
|
||||
val LONG = "([-+]?[0-9]+)[l|L]".toRegex()
|
||||
val SHORT = "([-+]?[0-9]+)[s|S]".toRegex()
|
||||
val INTEGER = "([-+]?[0-9]+)".toRegex()
|
||||
val DOUBLE_UNTYPED = "([-+]?[0-9]*\\.?[0-9]+)".toRegex()
|
||||
val ROUGH_PATTERN = "[-+]?[0-9]*\\.?[0-9]+[dDbBfFlLsS]?".toRegex()
|
||||
}
|
||||
|
||||
fun parseNumericTag(): NumericTag {
|
||||
skipWhitespace()
|
||||
val textForm = racer.consumeWhile { Patterns.ROUGH_PATTERN.matchEntire(it) != null }
|
||||
if (textForm.isEmpty()) {
|
||||
racer.error("Expected numeric tag (starting with either -, +, . or a digit")
|
||||
}
|
||||
val doubleMatch = Patterns.DOUBLE.matchEntire(textForm) ?: Patterns.DOUBLE_UNTYPED.matchEntire(textForm)
|
||||
if (doubleMatch != null) {
|
||||
return DoubleTag.valueOf(doubleMatch.groups[1]!!.value.toDouble())
|
||||
}
|
||||
val floatMatch = Patterns.FLOAT.matchEntire(textForm)
|
||||
if (floatMatch != null) {
|
||||
return FloatTag.valueOf(floatMatch.groups[1]!!.value.toFloat())
|
||||
}
|
||||
val byteMatch = Patterns.BYTE.matchEntire(textForm)
|
||||
if (byteMatch != null) {
|
||||
return ByteTag.valueOf(byteMatch.groups[1]!!.value.toByte())
|
||||
}
|
||||
val longMatch = Patterns.LONG.matchEntire(textForm)
|
||||
if (longMatch != null) {
|
||||
return LongTag.valueOf(longMatch.groups[1]!!.value.toLong())
|
||||
}
|
||||
val shortMatch = Patterns.SHORT.matchEntire(textForm)
|
||||
if (shortMatch != null) {
|
||||
return ShortTag.valueOf(shortMatch.groups[1]!!.value.toShort())
|
||||
}
|
||||
val integerMatch = Patterns.INTEGER.matchEntire(textForm)
|
||||
if (integerMatch != null) {
|
||||
return IntTag.valueOf(integerMatch.groups[1]!!.value.toInt())
|
||||
}
|
||||
throw IllegalStateException("Could not properly parse numeric tag '$textForm', despite passing rough verification. This is a bug in the LegacyTagParser")
|
||||
}
|
||||
|
||||
private fun parseIdentifier(): String {
|
||||
skipWhitespace()
|
||||
if (racer.peek(1) == "\"") {
|
||||
return parseQuotedString()
|
||||
}
|
||||
return racer.consumeWhile {
|
||||
val x = it.last()
|
||||
x != ':' && !Character.isWhitespace(x)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package moe.nea.notenoughupdates
|
||||
|
||||
import dev.architectury.registry.registries.Registries
|
||||
import io.github.moulberry.repo.NEURepository
|
||||
import java.nio.file.Path
|
||||
|
||||
object NotEnoughUpdates {
|
||||
val REGISTRIES by lazy { Registries.get(MOD_ID) }
|
||||
|
||||
|
||||
const val MOD_ID = "notenoughupdates"
|
||||
|
||||
val neuRepo = NEURepository.of(Path.of("NotEnoughUpdates-REPO")).also {
|
||||
it.reload()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fun init() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package moe.nea.notenoughupdates.rei
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import io.github.moulberry.repo.NEURepository
|
||||
import com.mojang.serialization.Dynamic
|
||||
import io.github.moulberry.repo.data.NEUItem
|
||||
import me.shedaniel.math.Point
|
||||
import me.shedaniel.math.Rectangle
|
||||
import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer
|
||||
@@ -16,45 +17,105 @@ import me.shedaniel.rei.api.common.entry.type.EntryType
|
||||
import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry
|
||||
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes
|
||||
import me.shedaniel.rei.api.common.util.EntryStacks
|
||||
import net.minecraft.core.Registry
|
||||
import moe.nea.notenoughupdates.LegacyTagParser
|
||||
import moe.nea.notenoughupdates.NotEnoughUpdates.neuRepo
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.NbtOps
|
||||
import net.minecraft.nbt.StringTag
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TextComponent
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.tags.TagKey
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.util.datafix.DataFixers.getDataFixer
|
||||
import net.minecraft.util.datafix.fixes.References
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import net.minecraft.world.item.enchantment.Enchantments
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.stream.Stream
|
||||
|
||||
|
||||
class NEUReiPlugin : REIClientPlugin {
|
||||
|
||||
data class SBItem(val sbname: String, val backing: Item)
|
||||
companion object {
|
||||
|
||||
fun EntryStack<NEUReiPlugin.SBItem>.asItemStack() =
|
||||
EntryStack.of(VanillaEntryTypes.ITEM, ItemStack(this.value.backing).also {
|
||||
it.enchant(Enchantments.BINDING_CURSE, 1)
|
||||
it.hoverName = TextComponent(value.sbname)
|
||||
})
|
||||
fun EntryStack<NEUItem>.asItemEntry(): EntryStack<ItemStack> {
|
||||
return EntryStack.of(VanillaEntryTypes.ITEM, value.asItemStack())
|
||||
}
|
||||
|
||||
fun ItemStack.appendLore(args: List<Component>) {
|
||||
val compoundTag = getOrCreateTagElement("display")
|
||||
val loreList = compoundTag.getList("Lore", StringTag.TAG_STRING.toInt())
|
||||
for (arg in args) {
|
||||
loreList.add(StringTag.valueOf(Component.Serializer.toJson(arg)))
|
||||
}
|
||||
compoundTag.put("Lore", loreList)
|
||||
}
|
||||
|
||||
val cache: MutableMap<String, ItemStack> = ConcurrentHashMap()
|
||||
|
||||
fun NEUItem.asItemStackNow(): ItemStack {
|
||||
val df = getDataFixer()
|
||||
val itemTag1_8_9 = CompoundTag()
|
||||
itemTag1_8_9.put("tag", LegacyTagParser.parse(this.nbttag))
|
||||
itemTag1_8_9.putString("id", this.minecraftItemId)
|
||||
itemTag1_8_9.putByte("Count", 1)
|
||||
itemTag1_8_9.putShort("Damage", this.damage.toShort())
|
||||
val itemTag_modern = try {
|
||||
df.update(
|
||||
References.ITEM_STACK,
|
||||
Dynamic(NbtOps.INSTANCE, itemTag1_8_9),
|
||||
99,
|
||||
2975
|
||||
).value as CompoundTag
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return ItemStack(Items.PAINTING).apply {
|
||||
appendLore(listOf(TextComponent("Exception rendering item: $skyblockItemId")))
|
||||
}
|
||||
}
|
||||
val itemInstance = ItemStack.of(itemTag_modern)
|
||||
return itemInstance.also {
|
||||
if(false)it.appendLore(
|
||||
listOf(
|
||||
TextComponent("Old: $minecraftItemId").withStyle {
|
||||
it.withItalic(false).withColor(ChatFormatting.RED)
|
||||
},
|
||||
TextComponent("Modern: $itemTag_modern").withStyle {
|
||||
it.withItalic(false).withColor(ChatFormatting.RED)
|
||||
},
|
||||
)
|
||||
)
|
||||
it.hoverName = TextComponent(this.skyblockItemId)
|
||||
}
|
||||
}
|
||||
|
||||
fun NEUItem.asItemStack(): ItemStack {
|
||||
var s = cache[this.skyblockItemId]
|
||||
if (s == null) {
|
||||
s = asItemStackNow()
|
||||
cache[this.skyblockItemId] = s
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
|
||||
val hehe = ResourceLocation("notenoughupdates", "skyblockitems")
|
||||
}
|
||||
|
||||
object SBItemEntryDefinition : EntryDefinition<SBItem> {
|
||||
override fun equals(o1: SBItem?, o2: SBItem?, context: ComparisonContext?): Boolean {
|
||||
object SBItemEntryDefinition : EntryDefinition<NEUItem> {
|
||||
override fun equals(o1: NEUItem?, o2: NEUItem?, context: ComparisonContext?): Boolean {
|
||||
return o1 == o2
|
||||
}
|
||||
|
||||
override fun getValueType(): Class<SBItem> = SBItem::class.java
|
||||
override fun getType(): EntryType<SBItem> =
|
||||
override fun getValueType(): Class<NEUItem> = NEUItem::class.java
|
||||
override fun getType(): EntryType<NEUItem> =
|
||||
EntryType.deferred(hehe)
|
||||
|
||||
override fun getRenderer(): EntryRenderer<SBItem> = object : EntryRenderer<SBItem> {
|
||||
override fun getRenderer(): EntryRenderer<NEUItem> = object : EntryRenderer<NEUItem> {
|
||||
override fun render(
|
||||
entry: EntryStack<SBItem>,
|
||||
entry: EntryStack<NEUItem>,
|
||||
matrices: PoseStack,
|
||||
bounds: Rectangle,
|
||||
mouseX: Int,
|
||||
@@ -63,75 +124,64 @@ class NEUReiPlugin : REIClientPlugin {
|
||||
) {
|
||||
VanillaEntryTypes.ITEM.definition.renderer
|
||||
.render(
|
||||
entry.asItemStack(),
|
||||
entry.asItemEntry(),
|
||||
matrices, bounds, mouseX, mouseY, delta
|
||||
)
|
||||
}
|
||||
|
||||
override fun getTooltip(entry: EntryStack<SBItem>, mouse: Point): Tooltip? {
|
||||
override fun getTooltip(entry: EntryStack<NEUItem>, mouse: Point): Tooltip? {
|
||||
return VanillaEntryTypes.ITEM.definition.renderer
|
||||
.getTooltip(entry.asItemStack(), mouse)
|
||||
.getTooltip(entry.asItemEntry(), mouse)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getSerializer(): EntrySerializer<SBItem>? {
|
||||
override fun getSerializer(): EntrySerializer<NEUItem>? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getTagsFor(entry: EntryStack<SBItem>?, value: SBItem?): Stream<out TagKey<*>> {
|
||||
override fun getTagsFor(entry: EntryStack<NEUItem>?, value: NEUItem?): Stream<out TagKey<*>> {
|
||||
return Stream.empty()
|
||||
}
|
||||
|
||||
override fun asFormattedText(entry: EntryStack<SBItem>, value: SBItem): Component {
|
||||
return VanillaEntryTypes.ITEM.definition.asFormattedText(entry.asItemStack(), ItemStack(value.backing))
|
||||
override fun asFormattedText(entry: EntryStack<NEUItem>, value: NEUItem): Component {
|
||||
return VanillaEntryTypes.ITEM.definition.asFormattedText(entry.asItemEntry(), value.asItemStack())
|
||||
}
|
||||
|
||||
override fun hash(entry: EntryStack<SBItem>, value: SBItem, context: ComparisonContext): Long {
|
||||
return value.sbname.hashCode().toLong()
|
||||
override fun hash(entry: EntryStack<NEUItem>, value: NEUItem, context: ComparisonContext): Long {
|
||||
return value.skyblockItemId.hashCode().toLong()
|
||||
}
|
||||
|
||||
override fun wildcard(entry: EntryStack<SBItem>, value: SBItem): SBItem {
|
||||
override fun wildcard(entry: EntryStack<NEUItem>, value: NEUItem): NEUItem {
|
||||
return value
|
||||
}
|
||||
|
||||
override fun normalize(entry: EntryStack<SBItem>, value: SBItem): SBItem {
|
||||
override fun normalize(entry: EntryStack<NEUItem>, value: NEUItem): NEUItem {
|
||||
return value
|
||||
}
|
||||
|
||||
override fun copy(entry: EntryStack<SBItem>?, value: SBItem): SBItem {
|
||||
return value.copy()
|
||||
override fun copy(entry: EntryStack<NEUItem>?, value: NEUItem): NEUItem {
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isEmpty(entry: EntryStack<SBItem>?, value: SBItem?): Boolean {
|
||||
override fun isEmpty(entry: EntryStack<NEUItem>?, value: NEUItem?): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getIdentifier(entry: EntryStack<SBItem>?, value: SBItem): ResourceLocation? {
|
||||
return ResourceLocation("skyblockitem", value.sbname)
|
||||
override fun getIdentifier(entry: EntryStack<NEUItem>?, value: NEUItem): ResourceLocation {
|
||||
return ResourceLocation("skyblockitem", value.skyblockItemId.lowercase().replace(";", "__"))
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
val neuRepo = NEURepository.of(Path.of("NotEnoughUpdates-REPO")).also {
|
||||
it.reload()
|
||||
}
|
||||
|
||||
override fun registerEntryTypes(registry: EntryTypeRegistry) {
|
||||
registry.register(hehe, SBItemEntryDefinition)
|
||||
}
|
||||
|
||||
override fun registerEntries(registry: EntryRegistry) {
|
||||
neuRepo.items.items.values.forEach {
|
||||
println("Adding item: $it")
|
||||
registry.addEntry(
|
||||
EntryStack.of(
|
||||
SBItemEntryDefinition, SBItem(
|
||||
it.skyblockItemId.lowercase().replace(";", "__"), Registry.ITEM.get(ResourceLocation(it.minecraftItemId))
|
||||
)
|
||||
)
|
||||
)
|
||||
registry.addEntry(EntryStack.of(SBItemEntryDefinition, it))
|
||||
}
|
||||
registry.addEntry(EntryStacks.of(ItemStack(Items.DIAMOND).also {
|
||||
it.enchant(Enchantments.ALL_DAMAGE_PROTECTION, 10)
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
package net.examplemod
|
||||
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform
|
||||
import dev.architectury.platform.Platform
|
||||
import java.nio.file.Path
|
||||
|
||||
object ExampleExpectPlatform {
|
||||
/**
|
||||
* We can use [Platform.getConfigFolder] but this is just an example of [ExpectPlatform].
|
||||
*
|
||||
*
|
||||
* This must be a **public static** method. The platform-implemented solution must be placed under a
|
||||
* platform sub-package, with its class suffixed with `Impl`.
|
||||
*
|
||||
*
|
||||
* Example:
|
||||
* Expect: net.examplemod.ExampleExpectPlatform#getConfigDirectory()
|
||||
* Actual Fabric: net.examplemod.fabric.ExampleExpectPlatformImpl#getConfigDirectory()
|
||||
* Actual Forge: net.examplemod.forge.ExampleExpectPlatformImpl#getConfigDirectory()
|
||||
*
|
||||
*
|
||||
* [You should also get the IntelliJ plugin to help with @ExpectPlatform.](https://plugins.jetbrains.com/plugin/16210-architectury)
|
||||
*/
|
||||
@ExpectPlatform
|
||||
@JvmStatic
|
||||
fun getConfigDirectory(): Path {
|
||||
// Just throw an error, the content should get replaced at runtime.
|
||||
throw AssertionError()
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package net.examplemod
|
||||
|
||||
import com.google.common.base.Suppliers
|
||||
import dev.architectury.registry.CreativeTabRegistry
|
||||
import dev.architectury.registry.registries.DeferredRegister
|
||||
import dev.architectury.registry.registries.Registries
|
||||
import dev.architectury.registry.registries.RegistrySupplier
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.CreativeModeTab
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import java.util.function.Supplier
|
||||
|
||||
object ExampleMod {
|
||||
const val MOD_ID = "examplemod"
|
||||
|
||||
// We can use this if we don't want to use DeferredRegister
|
||||
@Suppress("unused")
|
||||
val REGISTRIES: Supplier<Registries> = Suppliers.memoize { Registries.get(MOD_ID) }
|
||||
|
||||
// Registering a new creative tab
|
||||
val EXAMPLE_TAB: CreativeModeTab = CreativeTabRegistry.create(ResourceLocation(MOD_ID, "example_tab")) { ItemStack(EXAMPLE_ITEM.get()) }
|
||||
val ITEMS: DeferredRegister<Item> = DeferredRegister.create(MOD_ID, Registry.ITEM_REGISTRY)
|
||||
val EXAMPLE_ITEM: RegistrySupplier<Item> = ITEMS.register("example_item") { Item(Item.Properties().tab(EXAMPLE_TAB)) }
|
||||
|
||||
fun init() {
|
||||
ITEMS.register()
|
||||
println(ExampleExpectPlatform.getConfigDirectory().toAbsolutePath().normalize().toString())
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package net.examplemod.mixin
|
||||
|
||||
import net.minecraft.client.gui.screens.TitleScreen
|
||||
import org.objectweb.asm.Opcodes
|
||||
import org.spongepowered.asm.mixin.Mixin
|
||||
import org.spongepowered.asm.mixin.injection.At
|
||||
import org.spongepowered.asm.mixin.injection.Inject
|
||||
import org.spongepowered.asm.mixin.injection.Redirect
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo
|
||||
|
||||
@Mixin(TitleScreen::class)
|
||||
class MixinTitleScreen {
|
||||
@Inject(at = [At("HEAD")], method = ["init()V"])
|
||||
private fun init(info: CallbackInfo) {
|
||||
println("Hello from example architectury common mixin!")
|
||||
}
|
||||
|
||||
@Redirect(method = ["render"], at = At("FIELD", target = "minceraftEasterEgg", opcode = Opcodes.GETFIELD))
|
||||
private fun nextFloat(t: TitleScreen): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"item.examplemod.example_item": "Example Item"
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
"package": "net.examplemod.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"client": [
|
||||
"MixinTitleScreen"
|
||||
],
|
||||
"mixins": [
|
||||
],
|
||||
|
||||
@@ -9,6 +9,11 @@ architectury {
|
||||
|
||||
loom {
|
||||
accessWidenerPath.set(project(":common").loom.accessWidenerPath)
|
||||
launches {
|
||||
named("client") {
|
||||
property("fabric.log.level", "info")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package moe.nea.notenoughupdates
|
||||
|
||||
import moe.nea.notenoughupdates.NotEnoughUpdates.init
|
||||
import net.fabricmc.api.ModInitializer
|
||||
|
||||
class FabricMain : ModInitializer {
|
||||
override fun onInitialize() {
|
||||
init()
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package net.examplemod.fabric
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import java.nio.file.Path
|
||||
import net.examplemod.ExampleExpectPlatform
|
||||
|
||||
object ExampleExpectPlatformImpl {
|
||||
/**
|
||||
* This is our actual method to [ExampleExpectPlatform.getConfigDirectory].
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getConfigDirectory(): Path = FabricLoader.getInstance().configDir
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package net.examplemod.fabric
|
||||
|
||||
import net.examplemod.ExampleMod.init
|
||||
import net.fabricmc.api.ModInitializer
|
||||
|
||||
class ExampleModFabric : ModInitializer {
|
||||
override fun onInitialize() {
|
||||
init()
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
"environment": "client",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"net.examplemod.fabric.ExampleModFabric"
|
||||
"moe.nea.notenoughupdates.FabricMain"
|
||||
],
|
||||
"rei": [
|
||||
"moe.nea.notenoughupdates.rei.NEUReiPlugin"
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package net.examplemod.forge
|
||||
|
||||
import dev.architectury.platform.forge.EventBuses
|
||||
import net.examplemod.ExampleMod
|
||||
import net.examplemod.ExampleMod.init
|
||||
import moe.nea.notenoughupdates.NotEnoughUpdates
|
||||
import moe.nea.notenoughupdates.NotEnoughUpdates.init
|
||||
import net.minecraftforge.fml.common.Mod
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext
|
||||
|
||||
@Mod(ExampleMod.MOD_ID)
|
||||
@Mod(NotEnoughUpdates.MOD_ID)
|
||||
class ExampleModForge {
|
||||
init {
|
||||
// Submit our event bus to let architectury register our content on the right time
|
||||
EventBuses.registerModEventBus(ExampleMod.MOD_ID, FMLJavaModLoadingContext.get().modEventBus)
|
||||
EventBuses.registerModEventBus(NotEnoughUpdates.MOD_ID, FMLJavaModLoadingContext.get().modEventBus)
|
||||
init()
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package net.examplemod.quilt
|
||||
|
||||
import net.examplemod.ExampleMod.init
|
||||
import moe.nea.notenoughupdates.NotEnoughUpdates.init
|
||||
import org.quiltmc.loader.api.ModContainer
|
||||
import org.quiltmc.qsl.base.api.entrypoint.ModInitializer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user