diff --git a/.idea/libraries/Gradle__io_papermc_paper_paper_api_1_21_10_R0_1_SNAPSHOT.xml b/.idea/libraries/Gradle__io_papermc_paper_paper_api_1_21_10_R0_1_SNAPSHOT.xml index 9cef7876f..e421723b2 100644 --- a/.idea/libraries/Gradle__io_papermc_paper_paper_api_1_21_10_R0_1_SNAPSHOT.xml +++ b/.idea/libraries/Gradle__io_papermc_paper_paper_api_1_21_10_R0_1_SNAPSHOT.xml @@ -6,7 +6,7 @@ - + \ No newline at end of file diff --git a/.idea/modules/VanillaPlus.main.iml b/.idea/modules/VanillaPlus.main.iml index db9206a2c..9a3643c55 100644 --- a/.idea/modules/VanillaPlus.main.iml +++ b/.idea/modules/VanillaPlus.main.iml @@ -11,7 +11,7 @@ - + @@ -55,7 +55,7 @@ - + diff --git a/.idea/modules/VanillaPlus.test.iml b/.idea/modules/VanillaPlus.test.iml index 4c8849308..4abd22975 100644 --- a/.idea/modules/VanillaPlus.test.iml +++ b/.idea/modules/VanillaPlus.test.iml @@ -12,7 +12,7 @@ - + VanillaPlus:main @@ -54,7 +54,7 @@ - + diff --git a/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt b/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt index af1454158..ffd807a78 100644 --- a/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt +++ b/src/main/kotlin/org/xodium/vanillaplus/VanillaPlusBootstrap.kt @@ -9,6 +9,10 @@ import io.papermc.paper.registry.RegistryKey import io.papermc.paper.registry.event.RegistryEvents import io.papermc.paper.registry.keys.tags.EnchantmentTagKeys import io.papermc.paper.registry.keys.tags.ItemTypeTagKeys +import io.papermc.paper.registry.tag.TagKey +import io.papermc.paper.tag.TagEntry +import net.kyori.adventure.key.Key +import org.xodium.vanillaplus.enchantments.PickupEnchantment import org.xodium.vanillaplus.enchantments.ReplantEnchantment /** Main bootstrap class of the plugin. */ @@ -17,16 +21,32 @@ internal class VanillaPlusBootstrap : PluginBootstrap { companion object { const val INSTANCE = "vanillaplus" val REPLANT = ReplantEnchantment.key - val ENCHANTS = setOf(REPLANT) + val PICKUP = PickupEnchantment.key + val ENCHANTS = setOf(REPLANT, PICKUP) + val TOOLS = TagKey.create(RegistryKey.ITEM, Key.key(INSTANCE, "tools")) } override fun bootstrap(ctx: BootstrapContext) { ctx.lifecycleManager.apply { + registerEventHandler(LifecycleEvents.TAGS.preFlatten(RegistryKey.ITEM)) { event -> + event.registrar().setTag( + TOOLS, + setOf( + TagEntry.tagEntry(ItemTypeTagKeys.PICKAXES), + TagEntry.tagEntry(ItemTypeTagKeys.AXES), + TagEntry.tagEntry(ItemTypeTagKeys.SHOVELS), + TagEntry.tagEntry(ItemTypeTagKeys.HOES), + ), + ) + } registerEventHandler( RegistryEvents.ENCHANTMENT.compose().newHandler { event -> val hoeTag = event.getOrCreateTag(ItemTypeTagKeys.HOES) + val toolsTag = event.getOrCreateTag(TOOLS) + event.registry().apply { - register(REPLANT) { ReplantEnchantment.init(it).supportedItems(hoeTag) } + register(REPLANT) { ReplantEnchantment.builder(it).supportedItems(hoeTag) } + register(PICKUP) { PickupEnchantment.builder(it).supportedItems(toolsTag) } } }, ) diff --git a/src/main/kotlin/org/xodium/vanillaplus/enchantments/PickupEnchantment.kt b/src/main/kotlin/org/xodium/vanillaplus/enchantments/PickupEnchantment.kt new file mode 100644 index 000000000..b73e3494a --- /dev/null +++ b/src/main/kotlin/org/xodium/vanillaplus/enchantments/PickupEnchantment.kt @@ -0,0 +1,48 @@ +package org.xodium.vanillaplus.enchantments + +import io.papermc.paper.registry.RegistryKey +import io.papermc.paper.registry.TypedKey +import io.papermc.paper.registry.data.EnchantmentRegistryEntry +import net.kyori.adventure.key.Key +import org.bukkit.enchantments.Enchantment +import org.bukkit.event.block.BlockBreakEvent +import org.bukkit.inventory.EquipmentSlotGroup +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.INSTANCE +import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.PICKUP +import org.xodium.vanillaplus.interfaces.EnchantmentInterface +import org.xodium.vanillaplus.utils.ExtUtils.mm + +@Suppress("UnstableApiUsage") +internal object PickupEnchantment : EnchantmentInterface { + override val key: TypedKey = TypedKey.create(RegistryKey.ENCHANTMENT, Key.key(INSTANCE, "pickup")) + + override fun builder(builder: EnchantmentRegistryEntry.Builder): EnchantmentRegistryEntry.Builder = + builder + .description(PICKUP.value().replaceFirstChar { it.uppercase() }.mm()) + // TODO: Adjust costs and levels as needed + .anvilCost(8) + .maxLevel(1) + .weight(5) + .minimumCost(EnchantmentRegistryEntry.EnchantmentCost.of(1, 10)) + .maximumCost(EnchantmentRegistryEntry.EnchantmentCost.of(8, 20)) + .activeSlots(EquipmentSlotGroup.MAINHAND) + + /** + * Handles the block break event to automatically pick up drops when the tool has the Pickup enchantment. + * @param event The BlockBreakEvent triggered when a block is broken. + */ + fun pickup(event: BlockBreakEvent) { + val player = event.player + val itemInHand = player.inventory.itemInMainHand + + if (!itemInHand.hasItemMeta() || !itemInHand.itemMeta.hasEnchant(get())) return + + event.isDropItems = false + + for (drop in event.block.drops) { + val remaining = player.inventory.addItem(drop) + + for (item in remaining.values) player.world.dropItemNaturally(player.location, item) + } + } +} diff --git a/src/main/kotlin/org/xodium/vanillaplus/enchantments/ReplantEnchantment.kt b/src/main/kotlin/org/xodium/vanillaplus/enchantments/ReplantEnchantment.kt index d3d260871..83703ee65 100644 --- a/src/main/kotlin/org/xodium/vanillaplus/enchantments/ReplantEnchantment.kt +++ b/src/main/kotlin/org/xodium/vanillaplus/enchantments/ReplantEnchantment.kt @@ -4,8 +4,11 @@ import io.papermc.paper.registry.RegistryKey import io.papermc.paper.registry.TypedKey import io.papermc.paper.registry.data.EnchantmentRegistryEntry import net.kyori.adventure.key.Key +import org.bukkit.block.data.Ageable import org.bukkit.enchantments.Enchantment +import org.bukkit.event.block.BlockBreakEvent import org.bukkit.inventory.EquipmentSlotGroup +import org.xodium.vanillaplus.VanillaPlus.Companion.instance import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.INSTANCE import org.xodium.vanillaplus.VanillaPlusBootstrap.Companion.REPLANT import org.xodium.vanillaplus.interfaces.EnchantmentInterface @@ -15,13 +18,40 @@ import org.xodium.vanillaplus.utils.ExtUtils.mm internal object ReplantEnchantment : EnchantmentInterface { override val key: TypedKey = TypedKey.create(RegistryKey.ENCHANTMENT, Key.key(INSTANCE, "replant")) - override fun init(builder: EnchantmentRegistryEntry.Builder): EnchantmentRegistryEntry.Builder = + override fun builder(builder: EnchantmentRegistryEntry.Builder): EnchantmentRegistryEntry.Builder = builder .description(REPLANT.value().replaceFirstChar { it.uppercase() }.mm()) + // TODO: Adjust costs and levels as needed .anvilCost(8) .maxLevel(1) .weight(5) .minimumCost(EnchantmentRegistryEntry.EnchantmentCost.of(1, 10)) .maximumCost(EnchantmentRegistryEntry.EnchantmentCost.of(8, 20)) .activeSlots(EquipmentSlotGroup.MAINHAND) + + /** + * Automatically replants a crop block after it has been fully grown and harvested. + * @param event The BlockBreakEvent triggered when a block is broken. + */ + fun replant(event: BlockBreakEvent) { + val block = event.block + val ageable = block.blockData as? Ageable ?: return + val itemInHand = event.player.inventory.itemInMainHand + + if (ageable.age < ageable.maximumAge) return + if (!itemInHand.hasItemMeta() || !itemInHand.itemMeta.hasEnchant(get())) return + + // TODO: take seed out of drop. since planting would require a seed being used. + + instance.server.scheduler.runTaskLater( + instance, + Runnable { + val blockType = block.type + + block.type = blockType + block.blockData = ageable.apply { age = 0 } + }, + 2, + ) + } } diff --git a/src/main/kotlin/org/xodium/vanillaplus/interfaces/EnchantmentInterface.kt b/src/main/kotlin/org/xodium/vanillaplus/interfaces/EnchantmentInterface.kt index e252fb96d..3c972a266 100644 --- a/src/main/kotlin/org/xodium/vanillaplus/interfaces/EnchantmentInterface.kt +++ b/src/main/kotlin/org/xodium/vanillaplus/interfaces/EnchantmentInterface.kt @@ -17,11 +17,11 @@ internal interface EnchantmentInterface { val key: TypedKey /** - * Initializes the Drift enchantment. + * Configures the properties of the enchantment using the provided builder. * @param builder The builder used to define the enchantment properties. * @return The builder for method chaining. */ - fun init(builder: EnchantmentRegistryEntry.Builder): EnchantmentRegistryEntry.Builder + fun builder(builder: EnchantmentRegistryEntry.Builder): EnchantmentRegistryEntry.Builder /** * Retrieves the enchantment from the registry. diff --git a/src/main/kotlin/org/xodium/vanillaplus/modules/PlayerModule.kt b/src/main/kotlin/org/xodium/vanillaplus/modules/PlayerModule.kt index b20500a5b..e11671b6a 100644 --- a/src/main/kotlin/org/xodium/vanillaplus/modules/PlayerModule.kt +++ b/src/main/kotlin/org/xodium/vanillaplus/modules/PlayerModule.kt @@ -7,8 +7,6 @@ import io.papermc.paper.datacomponent.item.ItemLore import io.papermc.paper.datacomponent.item.ResolvableProfile import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder import org.bukkit.Material -import org.bukkit.block.Block -import org.bukkit.block.data.Ageable import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority @@ -26,6 +24,7 @@ import org.bukkit.permissions.Permission import org.bukkit.permissions.PermissionDefault import org.xodium.vanillaplus.VanillaPlus.Companion.instance import org.xodium.vanillaplus.data.CommandData +import org.xodium.vanillaplus.enchantments.PickupEnchantment import org.xodium.vanillaplus.enchantments.ReplantEnchantment import org.xodium.vanillaplus.interfaces.ModuleInterface import org.xodium.vanillaplus.pdcs.PlayerPDC.nickname @@ -165,33 +164,8 @@ internal class PlayerModule( fun on(event: BlockBreakEvent) { if (!enabled()) return - replant(event.block, event.player.inventory.itemInMainHand) - } - - /** - * Automatically replants a crop block after it has been fully grown and harvested. - * @param block The block that was broken. - * @param tool The tool used to break the block. - */ - private fun replant( - block: Block, - tool: ItemStack, - ) { - val ageable = block.blockData as? Ageable ?: return - - if (ageable.age < ageable.maximumAge) return - if (!tool.hasItemMeta() || !tool.itemMeta.hasEnchant(ReplantEnchantment.get())) return - - instance.server.scheduler.runTaskLater( - instance, - Runnable { - val blockType = block.type - - block.type = blockType - block.blockData = ageable.apply { age = 0 } - }, - 2, - ) + ReplantEnchantment.replant(event) + PickupEnchantment.pickup(event) } /**