mirror of
https://github.com/Auxilor/EcoEnchants.git
synced 2024-11-21 14:55:17 +01:00
Removed 1.20.6 support
This commit is contained in:
parent
9467961232
commit
6aac6c586b
@ -26,7 +26,6 @@ dependencies {
|
||||
implementation(project(":eco-core:core-nms:v1_20_R1"))
|
||||
implementation(project(":eco-core:core-nms:v1_20_R2"))
|
||||
implementation(project(":eco-core:core-nms:v1_20_R3", configuration = "reobf"))
|
||||
implementation(project(":eco-core:core-nms:v1_20_6", configuration = "reobf"))
|
||||
implementation(project(":eco-core:core-nms:v1_21", configuration = "reobf"))
|
||||
}
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
plugins {
|
||||
id("io.papermc.paperweight.userdev")
|
||||
}
|
||||
|
||||
group = "com.willfp"
|
||||
version = rootProject.version
|
||||
|
||||
dependencies {
|
||||
paperweight.paperDevBundle("1.20.6-R0.1-SNAPSHOT")
|
||||
}
|
||||
|
||||
tasks {
|
||||
build {
|
||||
dependsOn(reobfJar)
|
||||
}
|
||||
|
||||
compileJava {
|
||||
options.release = 21
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "21"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,230 +0,0 @@
|
||||
package com.willfp.ecoenchants.proxy.v1_20_6
|
||||
|
||||
import com.willfp.eco.core.Prerequisite
|
||||
import com.willfp.ecoenchants.CodecReplacerProxy
|
||||
import com.willfp.ecoenchants.proxy.v1_20_6.registration.VanillaEcoEnchantsEnchantment
|
||||
import com.willfp.ecoenchants.setStaticFinal
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.core.NonNullList
|
||||
import net.minecraft.core.component.DataComponentPatch
|
||||
import net.minecraft.core.component.DataComponents
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.core.registries.Registries
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.ListTag
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.network.chat.ComponentSerialization
|
||||
import net.minecraft.network.codec.ByteBufCodecs
|
||||
import net.minecraft.network.codec.StreamCodec
|
||||
import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket
|
||||
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.component.CustomData
|
||||
import net.minecraft.world.item.enchantment.Enchantment
|
||||
import net.minecraft.world.item.enchantment.ItemEnchantments
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers
|
||||
|
||||
class CodecReplacer : CodecReplacerProxy {
|
||||
override fun replaceItemCodec() {
|
||||
ItemStack::class.java
|
||||
.getDeclaredField("OPTIONAL_STREAM_CODEC")
|
||||
.setStaticFinal(PatchedStreamCodec)
|
||||
|
||||
ItemStack::class.java
|
||||
.getDeclaredField("OPTIONAL_LIST_STREAM_CODEC")
|
||||
.setStaticFinal(
|
||||
PatchedStreamCodec.apply(ByteBufCodecs.collection { size ->
|
||||
NonNullList.createWithCapacity(size)
|
||||
})
|
||||
)
|
||||
|
||||
ServerboundSetCreativeModeSlotPacket.STREAM_CODEC::class.java
|
||||
.getDeclaredField("val\$codec2")
|
||||
.apply {
|
||||
isAccessible = true
|
||||
set(
|
||||
ServerboundSetCreativeModeSlotPacket.STREAM_CODEC,
|
||||
ItemStack.validatedStreamCodec(PatchedStreamCodec)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private object PatchedStreamCodec : StreamCodec<RegistryFriendlyByteBuf, ItemStack> {
|
||||
private const val nbtKey = "ecoenchants:client_enchs_patch"
|
||||
private const val nbtKeyShow = "ecoenchants:client_enchs_patch_show"
|
||||
private const val nbtKeyGlint = "ecoenchants:client_enchs_patch_glint"
|
||||
|
||||
private val itemStreamCodec = ByteBufCodecs.holderRegistry(Registries.ITEM)
|
||||
|
||||
fun Enchantment.isEco() = this is VanillaEcoEnchantsEnchantment
|
||||
|
||||
fun Map<Enchantment, Int>.toComponent(): ItemEnchantments {
|
||||
val component = ItemEnchantments.Mutable(ItemEnchantments.EMPTY)
|
||||
for ((enchant, level) in this) {
|
||||
component.set(enchant, level)
|
||||
}
|
||||
return component.toImmutable()
|
||||
}
|
||||
|
||||
fun serialize(itemStack: ItemStack): ItemStack {
|
||||
val enchantments = itemStack.get(DataComponents.ENCHANTMENTS) ?: return itemStack
|
||||
|
||||
// Separate out enchantments into vanilla and custom
|
||||
val vanillaEnchantments = mutableMapOf<Enchantment, Int>()
|
||||
val customEnchantments = mutableMapOf<Enchantment, Int>()
|
||||
|
||||
for ((holder, level) in enchantments.entrySet()) {
|
||||
val enchant = holder.value()
|
||||
if (enchant.isEco()) {
|
||||
customEnchantments[enchant] = level
|
||||
} else {
|
||||
vanillaEnchantments[enchant] = level
|
||||
}
|
||||
}
|
||||
|
||||
if (customEnchantments.isEmpty()) {
|
||||
return itemStack
|
||||
}
|
||||
|
||||
// Only keep vanilla enchants in NBT
|
||||
itemStack.set(
|
||||
DataComponents.ENCHANTMENTS,
|
||||
vanillaEnchantments
|
||||
.toComponent()
|
||||
.withTooltip(enchantments.showInTooltip)
|
||||
)
|
||||
|
||||
// Override glint
|
||||
val hasGlint = itemStack.get(DataComponents.ENCHANTMENT_GLINT_OVERRIDE)
|
||||
itemStack.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, true)
|
||||
|
||||
// Put custom enchants in custom data
|
||||
val customData = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).update {
|
||||
it.remove(nbtKey)
|
||||
|
||||
val tag = ListTag()
|
||||
|
||||
for ((enchant, level) in customEnchantments) {
|
||||
val id = BuiltInRegistries.ENCHANTMENT.getKey(enchant) ?: continue
|
||||
|
||||
tag.add(CompoundTag().apply {
|
||||
putString("id", id.toString())
|
||||
putInt("lvl", level)
|
||||
})
|
||||
}
|
||||
|
||||
it.put(nbtKey, tag)
|
||||
it.putBoolean(nbtKeyShow, enchantments.showInTooltip)
|
||||
if (hasGlint != null) {
|
||||
it.putBoolean(nbtKeyGlint, hasGlint)
|
||||
}
|
||||
}
|
||||
|
||||
itemStack.set(DataComponents.CUSTOM_DATA, customData)
|
||||
|
||||
return itemStack
|
||||
}
|
||||
|
||||
fun deserialize(itemStack: ItemStack): ItemStack {
|
||||
val customData = itemStack.get(DataComponents.CUSTOM_DATA) ?: return itemStack
|
||||
|
||||
// Fetch enchantments from custom data
|
||||
val enchantments = ItemEnchantments.Mutable(
|
||||
itemStack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY)
|
||||
)
|
||||
|
||||
val customDataTag = customData.copyTag()
|
||||
|
||||
customDataTag.getList(nbtKey, CraftMagicNumbers.NBT.TAG_COMPOUND)
|
||||
.filterIsInstance<CompoundTag>()
|
||||
.forEach { tag ->
|
||||
val id = tag.getString("id")
|
||||
val level = tag.getInt("lvl")
|
||||
|
||||
val enchant = BuiltInRegistries.ENCHANTMENT.get(
|
||||
ResourceLocation(id)
|
||||
) ?: return@forEach
|
||||
|
||||
enchantments.set(enchant, level)
|
||||
}
|
||||
|
||||
if (enchantments.keySet().isEmpty()) {
|
||||
return itemStack
|
||||
}
|
||||
|
||||
enchantments.showInTooltip = customDataTag.getBoolean(nbtKeyShow)
|
||||
|
||||
// Remove extra data
|
||||
val cleaned = customData.update {
|
||||
it.remove(nbtKey)
|
||||
it.remove(nbtKeyShow)
|
||||
it.remove(nbtKeyGlint)
|
||||
}
|
||||
|
||||
// Set to item
|
||||
itemStack.set(DataComponents.ENCHANTMENTS, enchantments.toImmutable())
|
||||
|
||||
// Reset glint
|
||||
val hasGlint = if (customDataTag.contains(nbtKeyGlint)) {
|
||||
customDataTag.getBoolean(nbtKeyGlint)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
itemStack.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, hasGlint)
|
||||
|
||||
// Set cleaned data
|
||||
if (cleaned.isEmpty) {
|
||||
itemStack.remove(DataComponents.CUSTOM_DATA)
|
||||
} else {
|
||||
itemStack.set(DataComponents.CUSTOM_DATA, cleaned)
|
||||
}
|
||||
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun decode(buf: RegistryFriendlyByteBuf): ItemStack {
|
||||
val i = buf.readVarInt()
|
||||
return if (i <= 0) {
|
||||
ItemStack.EMPTY
|
||||
} else {
|
||||
val holder: Holder<Item> =
|
||||
itemStreamCodec.decode(buf) as Holder<Item>
|
||||
val dataComponentPatch =
|
||||
DataComponentPatch.STREAM_CODEC.decode(buf) as DataComponentPatch
|
||||
|
||||
deserialize(ItemStack(holder, i, dataComponentPatch))
|
||||
}
|
||||
}
|
||||
|
||||
override fun encode(buf: RegistryFriendlyByteBuf, itemStack: ItemStack) {
|
||||
@Suppress("SENSELESS_COMPARISON")
|
||||
if (itemStack.isEmpty || itemStack.item == null) {
|
||||
buf.writeVarInt(0)
|
||||
} else {
|
||||
val remapped = serialize(itemStack)
|
||||
|
||||
buf.writeVarInt(remapped.count)
|
||||
|
||||
itemStreamCodec.encode(
|
||||
buf,
|
||||
remapped.itemHolder
|
||||
)
|
||||
|
||||
if (Prerequisite.HAS_PAPER.isMet) {
|
||||
// Paper start - adventure; conditionally render translatable components
|
||||
val prev = ComponentSerialization.DONT_RENDER_TRANSLATABLES.get()
|
||||
try {
|
||||
ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(true)
|
||||
DataComponentPatch.STREAM_CODEC.encode(buf, remapped.componentsPatch)
|
||||
} finally {
|
||||
ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(prev)
|
||||
}
|
||||
// Paper end - adventure; conditionally render translatable components
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.willfp.ecoenchants.proxy.v1_20_6
|
||||
|
||||
import com.willfp.eco.core.fast.FastItemStack
|
||||
import com.willfp.ecoenchants.display.HideStoredEnchantsProxy
|
||||
import org.bukkit.inventory.ItemFlag
|
||||
|
||||
class HideStoredEnchants: HideStoredEnchantsProxy {
|
||||
override fun hideStoredEnchants(fis: FastItemStack) {
|
||||
fis.addItemFlags(ItemFlag.HIDE_STORED_ENCHANTS)
|
||||
}
|
||||
|
||||
override fun areStoredEnchantsHidden(fis: FastItemStack): Boolean {
|
||||
return fis.hasItemFlag(ItemFlag.HIDE_STORED_ENCHANTS)
|
||||
}
|
||||
|
||||
override fun showStoredEnchants(fis: FastItemStack) {
|
||||
fis.removeItemFlags(ItemFlag.HIDE_STORED_ENCHANTS)
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
package com.willfp.ecoenchants.proxy.v1_20_6
|
||||
|
||||
import com.willfp.ecoenchants.enchant.EcoEnchant
|
||||
import com.willfp.ecoenchants.enchant.EcoEnchants
|
||||
import com.willfp.ecoenchants.enchant.impl.EcoEnchantBase
|
||||
import com.willfp.ecoenchants.enchant.registration.modern.ModernEnchantmentRegistererProxy
|
||||
import com.willfp.ecoenchants.proxy.v1_20_6.registration.EcoEnchantsCraftEnchantment
|
||||
import com.willfp.ecoenchants.proxy.v1_20_6.registration.ModifiedVanillaCraftEnchantment
|
||||
import com.willfp.ecoenchants.proxy.v1_20_6.registration.VanillaEcoEnchantsEnchantment
|
||||
import net.minecraft.core.Holder
|
||||
import net.minecraft.core.MappedRegistry
|
||||
import net.minecraft.core.Registry
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.enchantment.Enchantments
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.craftbukkit.CraftRegistry
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import java.util.IdentityHashMap
|
||||
import java.util.function.BiFunction
|
||||
|
||||
class ModernEnchantmentRegisterer : ModernEnchantmentRegistererProxy {
|
||||
private val frozenField = MappedRegistry::class.java
|
||||
.declaredFields
|
||||
.filter { it.type.isPrimitive }[0]
|
||||
.apply { isAccessible = true }
|
||||
|
||||
private val unregisteredIntrusiveHoldersField = MappedRegistry::class.java
|
||||
.declaredFields
|
||||
.last { it.type == Map::class.java }
|
||||
.apply { isAccessible = true }
|
||||
|
||||
private val minecraftToBukkit = CraftRegistry::class.java
|
||||
.getDeclaredField("minecraftToBukkit")
|
||||
.apply { isAccessible = true }
|
||||
|
||||
private val vanillaEnchantments = Enchantments::class.java
|
||||
.declaredFields
|
||||
.filter { it.type == net.minecraft.world.item.enchantment.Enchantment::class.java }
|
||||
.map { it.get(null) as net.minecraft.world.item.enchantment.Enchantment }
|
||||
.mapNotNull { BuiltInRegistries.ENCHANTMENT.getKey(it) }
|
||||
.map { CraftNamespacedKey.fromMinecraft(it) }
|
||||
.toSet()
|
||||
|
||||
override fun replaceRegistry() {
|
||||
val newRegistryMTB =
|
||||
BiFunction<NamespacedKey, net.minecraft.world.item.enchantment.Enchantment, Enchantment> { key, registry ->
|
||||
val isVanilla = vanillaEnchantments.contains(key)
|
||||
val eco = EcoEnchants.getByID(key.key)
|
||||
|
||||
if (isVanilla) {
|
||||
ModifiedVanillaCraftEnchantment(key, registry)
|
||||
} else if (eco != null) {
|
||||
eco as Enchantment
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
// Update bukkit registry
|
||||
minecraftToBukkit.set(org.bukkit.Registry.ENCHANTMENT, newRegistryMTB)
|
||||
|
||||
// Unfreeze NMS registry
|
||||
frozenField.set(BuiltInRegistries.ENCHANTMENT, false)
|
||||
unregisteredIntrusiveHoldersField.set(
|
||||
BuiltInRegistries.ENCHANTMENT,
|
||||
IdentityHashMap<net.minecraft.world.item.enchantment.Enchantment,
|
||||
Holder.Reference<net.minecraft.world.item.enchantment.Enchantment>>()
|
||||
)
|
||||
}
|
||||
|
||||
override fun register(enchant: EcoEnchantBase): Enchantment {
|
||||
if (BuiltInRegistries.ENCHANTMENT.containsKey(CraftNamespacedKey.toMinecraft(enchant.enchantmentKey))) {
|
||||
val nms = BuiltInRegistries.ENCHANTMENT[CraftNamespacedKey.toMinecraft(enchant.enchantmentKey)]
|
||||
|
||||
if (nms != null) {
|
||||
return EcoEnchantsCraftEnchantment(enchant, nms)
|
||||
} else {
|
||||
throw IllegalStateException("Enchantment ${enchant.id} wasn't registered")
|
||||
}
|
||||
}
|
||||
|
||||
Registry.register(BuiltInRegistries.ENCHANTMENT, enchant.id, VanillaEcoEnchantsEnchantment(enchant))
|
||||
|
||||
return register(enchant)
|
||||
}
|
||||
|
||||
override fun unregister(enchant: EcoEnchant) {
|
||||
/*
|
||||
|
||||
You can't unregister from a minecraft registry, so we simply leave the stale reference there.
|
||||
This shouldn't cause many issues in production as the bukkit registry is replaced on each reload.
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.willfp.ecoenchants.proxy.v1_20_6
|
||||
|
||||
import com.willfp.ecoenchants.mechanics.OpenInventoryProxy
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class OpenInventory : OpenInventoryProxy {
|
||||
override fun getOpenInventory(player: Player): Any {
|
||||
return (player as CraftPlayer).handle.containerMenu
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
package com.willfp.ecoenchants.proxy.v1_20_6.registration
|
||||
|
||||
import com.willfp.eco.util.toComponent
|
||||
import com.willfp.ecoenchants.display.getFormattedName
|
||||
import com.willfp.ecoenchants.enchant.EcoEnchant
|
||||
import com.willfp.ecoenchants.enchant.impl.EcoEnchantBase
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.minecraft.world.item.enchantment.Enchantment
|
||||
import org.bukkit.craftbukkit.enchantments.CraftEnchantment
|
||||
import org.bukkit.enchantments.EnchantmentTarget
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class EcoEnchantsCraftEnchantment(
|
||||
private val enchant: EcoEnchantBase,
|
||||
nmsEnchantment: Enchantment
|
||||
) : CraftEnchantment(enchant.enchantmentKey, nmsEnchantment), EcoEnchant by enchant {
|
||||
init {
|
||||
enchant.enchantment = this
|
||||
}
|
||||
|
||||
override fun onRegister() {
|
||||
// Fix for hardcoded enchantments
|
||||
if (plugin.isLoaded) {
|
||||
enchant.onRegister()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRemove() {
|
||||
enchant.onRemove()
|
||||
}
|
||||
|
||||
override fun canEnchantItem(item: ItemStack): Boolean {
|
||||
return enchant.canEnchantItem(item)
|
||||
}
|
||||
|
||||
override fun conflictsWith(other: org.bukkit.enchantments.Enchantment): Boolean {
|
||||
return enchant.conflictsWith(other)
|
||||
}
|
||||
|
||||
override fun translationKey(): String {
|
||||
return "ecoenchants:enchantment.$id"
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "getName is a legacy Spigot API",
|
||||
replaceWith = ReplaceWith("this.displayName(level)")
|
||||
)
|
||||
override fun getName(): String = this.id.uppercase()
|
||||
override fun getMaxLevel(): Int = enchant.maximumLevel
|
||||
|
||||
override fun getStartLevel(): Int = 1
|
||||
|
||||
@Deprecated(
|
||||
message = "getItemTargets is an incompatible Spigot API",
|
||||
replaceWith = ReplaceWith("this.targets")
|
||||
)
|
||||
@Suppress("DEPRECATION")
|
||||
override fun getItemTarget(): EnchantmentTarget = EnchantmentTarget.ALL
|
||||
|
||||
@Deprecated(
|
||||
message = "Treasure enchantments do not exist in EcoEnchants",
|
||||
replaceWith = ReplaceWith("this.isEnchantable")
|
||||
)
|
||||
override fun isTreasure(): Boolean = !enchant.isObtainableThroughEnchanting
|
||||
|
||||
@Deprecated(
|
||||
message = "Use EnchantmentType instead",
|
||||
replaceWith = ReplaceWith("type.id")
|
||||
)
|
||||
override fun isCursed(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun displayName(level: Int): Component {
|
||||
return enchant.getFormattedName(level).toComponent()
|
||||
}
|
||||
|
||||
override fun isTradeable(): Boolean {
|
||||
return enchant.isObtainableThroughTrading
|
||||
}
|
||||
|
||||
override fun isDiscoverable(): Boolean {
|
||||
return enchant.isObtainableThroughDiscovery
|
||||
}
|
||||
|
||||
override fun getMinModifiedCost(level: Int): Int {
|
||||
return Int.MAX_VALUE
|
||||
}
|
||||
|
||||
override fun getMaxModifiedCost(level: Int): Int {
|
||||
return Int.MAX_VALUE
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other is EcoEnchant && this.enchantmentKey == other.enchantmentKey
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return this.enchantmentKey.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "EcoEnchantsCraftEnchantment(key=$key)"
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.willfp.ecoenchants.proxy.v1_20_6.registration
|
||||
|
||||
import com.willfp.ecoenchants.enchant.vanillaEnchantmentData
|
||||
import net.minecraft.world.item.enchantment.Enchantment
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.craftbukkit.enchantments.CraftEnchantment
|
||||
|
||||
class ModifiedVanillaCraftEnchantment(
|
||||
key: NamespacedKey,
|
||||
target: Enchantment
|
||||
) : CraftEnchantment(key, target) {
|
||||
override fun getMaxLevel(): Int = this.vanillaEnchantmentData?.maxLevel ?: super.getMaxLevel()
|
||||
|
||||
override fun conflictsWith(other: org.bukkit.enchantments.Enchantment): Boolean {
|
||||
val otherConflicts = when (other) {
|
||||
is ModifiedVanillaCraftEnchantment -> other.vanillaEnchantmentData?.conflicts?.contains(this.key) == true
|
||||
else -> other.conflictsWith(this)
|
||||
}
|
||||
|
||||
return this.vanillaEnchantmentData?.conflicts?.contains(other.key) ?: super.conflictsWith(other)
|
||||
|| otherConflicts
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
package com.willfp.ecoenchants.proxy.v1_20_6.registration
|
||||
|
||||
import com.willfp.eco.core.Prerequisite
|
||||
import com.willfp.eco.util.toComponent
|
||||
import com.willfp.ecoenchants.display.getFormattedName
|
||||
import com.willfp.ecoenchants.enchant.EcoEnchant
|
||||
import com.willfp.ecoenchants.enchant.EcoEnchants
|
||||
import io.papermc.paper.adventure.PaperAdventure
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.tags.ItemTags
|
||||
import net.minecraft.world.entity.EquipmentSlot
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.inventory.AnvilMenu
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.enchantment.Enchantment
|
||||
import org.bukkit.craftbukkit.enchantments.CraftEnchantment
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack
|
||||
import java.util.Objects
|
||||
|
||||
class VanillaEcoEnchantsEnchantment(
|
||||
enchant: EcoEnchant
|
||||
) : Enchantment(
|
||||
definition(
|
||||
ItemTags.DURABILITY_ENCHANTABLE, 0, // Weight is 0, so we can use our own rarity system
|
||||
enchant.maximumLevel,
|
||||
constantCost(1),
|
||||
constantCost(1),
|
||||
0
|
||||
)
|
||||
) {
|
||||
private val id = enchant.id
|
||||
|
||||
// Fetch on each call to ensure we get the latest enchantment
|
||||
private val enchant: EcoEnchant?
|
||||
get() = EcoEnchants[id]
|
||||
|
||||
override fun canEnchant(stack: ItemStack): Boolean {
|
||||
/*
|
||||
|
||||
This is the mother of all jank solutions.
|
||||
|
||||
Because I want the EcoEnchants anvil code to handle all custom enchantment logic,
|
||||
I need to prevent the NMS anvil code from processing the EcoEnchants enchantments.
|
||||
|
||||
However, there's no API method that I can use to do this - **however**,
|
||||
this method is called once in the NMS anvil code, and if it returns false then
|
||||
the anvil will not allow this enchantment to be applied to the item.
|
||||
|
||||
So, I can check if the calling method is the anvil merge method, and if it is,
|
||||
I can return false.
|
||||
|
||||
*/
|
||||
|
||||
val caller = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).callerClass
|
||||
|
||||
if (caller.name == AnvilMenu::class.java.name) {
|
||||
return false
|
||||
}
|
||||
|
||||
// End disgusting bodge
|
||||
|
||||
val item = CraftItemStack.asCraftMirror(stack)
|
||||
return enchant?.canEnchantItem(item) ?: false
|
||||
}
|
||||
|
||||
override fun isCurse(): Boolean {
|
||||
return enchant?.type?.noGrindstone == true
|
||||
}
|
||||
|
||||
override fun isDiscoverable(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun isTradeable(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun isTreasureOnly(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun checkCompatibility(other: Enchantment): Boolean {
|
||||
val bukkit = CraftEnchantment.minecraftToBukkit(other)
|
||||
|
||||
if (enchant != null) {
|
||||
return !enchant!!.conflictsWith(bukkit)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getSlotItems(entity: LivingEntity): MutableMap<EquipmentSlot, ItemStack> {
|
||||
return mutableMapOf()
|
||||
}
|
||||
|
||||
override fun getFullname(level: Int): Component {
|
||||
val enchant = this.enchant
|
||||
return if (Prerequisite.HAS_PAPER.isMet && enchant != null) {
|
||||
PaperAdventure.asVanilla(enchant.getFormattedName(level).toComponent())
|
||||
} else {
|
||||
super.getFullname(level)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "VanillaEcoEnchantsEnchantment(id='$id')"
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return other is VanillaEcoEnchantsEnchantment && other.id == this.id
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return Objects.hash(id)
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.willfp.ecoenchants
|
||||
|
||||
interface CodecReplacerProxy {
|
||||
fun replaceItemCodec()
|
||||
}
|
@ -87,10 +87,6 @@ class EcoEnchantsPlugin : LibreforgePlugin() {
|
||||
NamedValue("level", it.level),
|
||||
)
|
||||
}
|
||||
|
||||
if (Prerequisite.HAS_1_20_5.isMet && !Prerequisite.HAS_1_21.isMet) {
|
||||
getProxy(CodecReplacerProxy::class.java).replaceItemCodec()
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleAfterLoad() {
|
||||
@ -102,12 +98,10 @@ class EcoEnchantsPlugin : LibreforgePlugin() {
|
||||
|
||||
// Run in afterLoad to prevent items from having their enchantments deleted
|
||||
if (Prerequisite.HAS_1_20_5.isMet && !Prerequisite.HAS_1_21.isMet) {
|
||||
if (!this.configYml.getBool("enable-1-20-6")) {
|
||||
Bukkit.getPluginManager().disablePlugin(this)
|
||||
|
||||
throw IllegalStateException("EcoEnchants should not be ran in production on 1.20.6. " +
|
||||
"If this is a development environment, please set 'enable-1-20-6' to true in config.yml. ")
|
||||
}
|
||||
throw IllegalStateException("EcoEnchants does not support 1.20.6. Please update your server " +
|
||||
"or downgrade to 1.20.4.")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,11 +167,3 @@ enchant-gui:
|
||||
lore-conversion:
|
||||
enabled: false # If lore conversion should be enabled
|
||||
aggressive: false # Will convert all items in all inventories when opened, likely to use a lot of performance
|
||||
|
||||
# DO NOT USE IN PRODUCTION!
|
||||
# EcoEnchants should not be run on 1.20.6 in production environments. This is for testing purposes only.
|
||||
# This will allow the plugin to run on 1.20.6, but it is not recommended.
|
||||
# Enabling this option may cause irreversible damage to your server and may corrupt all items.
|
||||
# If you want to use EcoEnchants on 1.20, please only run 1.20.4.
|
||||
# 1.21 will work as expected when it releases.
|
||||
enable-1-20-6: false
|
||||
|
@ -26,5 +26,4 @@ include(":eco-core:core-nms:v1_19_R3")
|
||||
include(":eco-core:core-nms:v1_20_R1")
|
||||
include(":eco-core:core-nms:v1_20_R2")
|
||||
include(":eco-core:core-nms:v1_20_R3")
|
||||
include(":eco-core:core-nms:v1_20_6")
|
||||
include(":eco-core:core-nms:v1_21")
|
||||
|
Loading…
Reference in New Issue
Block a user