diff --git a/.idea/libraries/Gradle__org_antlr_antlr4_4_13_2.xml b/.idea/libraries/Gradle__org_antlr_antlr4_4_13_2.xml deleted file mode 100644 index ad25f7151..000000000 --- a/.idea/libraries/Gradle__org_antlr_antlr4_4_13_2.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_antlr_antlr4_runtime_4_13_2.xml b/.idea/libraries/Gradle__org_antlr_antlr4_runtime_4_13_2.xml deleted file mode 100644 index a25aa6458..000000000 --- a/.idea/libraries/Gradle__org_antlr_antlr4_runtime_4_13_2.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/kotlin/org/xodium/vanillaplus/modules/PlayerModule.kt b/src/main/kotlin/org/xodium/vanillaplus/modules/PlayerModule.kt index 6cf7827b1..028c3b63f 100644 --- a/src/main/kotlin/org/xodium/vanillaplus/modules/PlayerModule.kt +++ b/src/main/kotlin/org/xodium/vanillaplus/modules/PlayerModule.kt @@ -8,6 +8,9 @@ import io.papermc.paper.datacomponent.item.ResolvableProfile import io.papermc.paper.event.entity.EntityEquipmentChangedEvent import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder import org.bukkit.Material +import org.bukkit.NamespacedKey +import org.bukkit.Tag +import org.bukkit.block.ShulkerBox import org.bukkit.entity.Player import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority @@ -16,12 +19,16 @@ import org.bukkit.event.block.BlockDropItemEvent import org.bukkit.event.entity.PlayerDeathEvent import org.bukkit.event.inventory.ClickType import org.bukkit.event.inventory.InventoryClickEvent +import org.bukkit.event.inventory.InventoryCloseEvent import org.bukkit.event.inventory.InventoryType import org.bukkit.event.player.PlayerAdvancementDoneEvent import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerQuitEvent import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.Recipe +import org.bukkit.inventory.ShapelessRecipe +import org.bukkit.inventory.meta.BlockStateMeta import org.bukkit.permissions.Permission import org.bukkit.permissions.PermissionDefault import org.xodium.vanillaplus.VanillaPlus.Companion.instance @@ -29,6 +36,7 @@ import org.xodium.vanillaplus.data.CommandData import org.xodium.vanillaplus.enchantments.* import org.xodium.vanillaplus.interfaces.ModuleInterface import org.xodium.vanillaplus.pdcs.PlayerPDC.nickname +import org.xodium.vanillaplus.pdcs.ShulkerPDC.lock import org.xodium.vanillaplus.utils.ExtUtils.mm import org.xodium.vanillaplus.utils.ExtUtils.tryCatch import org.xodium.vanillaplus.utils.FmtUtils.fireFmt @@ -138,14 +146,75 @@ internal class PlayerModule( @EventHandler fun on(event: InventoryClickEvent) { - if (!enabled() || - event.click != config.enderChestClickType || - event.currentItem?.type != Material.ENDER_CHEST || - event.clickedInventory?.type != InventoryType.PLAYER + if (!enabled()) return + + val player = event.whoClicked as? Player ?: return + + if (event.clickedInventory?.type != InventoryType.PLAYER) return + + if (event.click == config.enderChestClickType && + event.currentItem?.type == Material.ENDER_CHEST ) { - return + event.isCancelled = true + instance.server.scheduler.runTask( + instance, + Runnable { player.openInventory(player.enderChest) }, + ) + } + + val item = event.currentItem ?: return + + if (event.click == config.shulkerClickType && + Tag.SHULKER_BOXES.isTagged(item.type) + ) { + event.isCancelled = true + + val meta = item.itemMeta as? BlockStateMeta ?: return + val shulker = meta.blockState as? ShulkerBox ?: return + + if (!shulker.lock()) { + shulker.lock(true) + + meta.blockState = shulker + item.itemMeta = meta + + instance.server.scheduler.runTask( + instance, + Runnable { player.openInventory(shulker.inventory) }, + ) + } } + // TODO: make it so when click on enderchest/shulker it first closes current inventory before opening the new one. + } + + @EventHandler + fun on(event: InventoryCloseEvent) { + if (!enabled()) return + + val player = event.player as? Player ?: return + for (item in player.inventory.contents) { + if (item != null && Tag.SHULKER_BOXES.isTagged(item.type)) { + val meta = item.itemMeta as? BlockStateMeta ?: continue + val shulker = meta.blockState as? ShulkerBox ?: continue + + if (shulker.lock()) { + shulker.inventory.contents = event.inventory.contents + shulker.lock(false) + + meta.blockState = shulker + item.itemMeta = meta + + instance.server.scheduler.runTask( + instance, + Runnable { player.updateInventory() }, + ) + + break + } + } + } + // FIX event.isCancelled = true instance.server.scheduler.runTask( @@ -256,6 +325,7 @@ internal class PlayerModule( data class Config( var enderChestClickType: ClickType = ClickType.SHIFT_RIGHT, + var shulkerClickType: ClickType = ClickType.SHIFT_RIGHT, var skullDropChance: Double = 0.1, var xpCostToBottle: Int = 11, var silkTouchConfig: SilkTouchEnchantment.Config = SilkTouchEnchantment.Config(), diff --git a/src/main/kotlin/org/xodium/vanillaplus/pdcs/PlayerPDC.kt b/src/main/kotlin/org/xodium/vanillaplus/pdcs/PlayerPDC.kt index c4146c5bb..ac2549fee 100644 --- a/src/main/kotlin/org/xodium/vanillaplus/pdcs/PlayerPDC.kt +++ b/src/main/kotlin/org/xodium/vanillaplus/pdcs/PlayerPDC.kt @@ -4,14 +4,8 @@ import org.bukkit.NamespacedKey import org.bukkit.entity.Player import org.bukkit.persistence.PersistentDataType import org.xodium.vanillaplus.VanillaPlus.Companion.instance -import org.xodium.vanillaplus.pdcs.PlayerPDC.NICKNAME_KEY -import org.xodium.vanillaplus.pdcs.PlayerPDC.SCOREBOARD_VISIBILITY_KEY -/** - * Provides access to player-specific persistent data including nicknames and scoreboard preferences. - * @property NICKNAME_KEY The namespaced key used for storing nickname data. - * @property SCOREBOARD_VISIBILITY_KEY The namespaced key used for storing scoreboard visibility preferences. - */ +/** Provides access to player-specific persistent data including nicknames and scoreboard preferences. */ internal object PlayerPDC { private val NICKNAME_KEY = NamespacedKey(instance, "nickname") private val SCOREBOARD_VISIBILITY_KEY = NamespacedKey(instance, "scoreboard_visibility") diff --git a/src/main/kotlin/org/xodium/vanillaplus/pdcs/ShulkerPDC.kt b/src/main/kotlin/org/xodium/vanillaplus/pdcs/ShulkerPDC.kt new file mode 100644 index 000000000..426d835ef --- /dev/null +++ b/src/main/kotlin/org/xodium/vanillaplus/pdcs/ShulkerPDC.kt @@ -0,0 +1,25 @@ +package org.xodium.vanillaplus.pdcs + +import org.bukkit.NamespacedKey +import org.bukkit.block.ShulkerBox +import org.bukkit.persistence.PersistentDataType +import org.xodium.vanillaplus.VanillaPlus.Companion.instance + +/** Provides access to shulker-specific persistent data including sold status. */ +internal object ShulkerPDC { + private val LOCK_KEY = NamespacedKey(instance, "lock") + + /** + * Retrieves the usage status of this shulker box from its persistent data container. + * @receiver The shulker box whose usage status to retrieve. + * @return `true` if the shulker box is marked as in use, `false` otherwise. + */ + fun ShulkerBox.lock(): Boolean = persistentDataContainer.get(LOCK_KEY, PersistentDataType.BOOLEAN) ?: false + + /** + * Sets the usage status of this shulker box in its persistent data container. + * @receiver The shulker box whose usage status to modify. + * @param boolean The usage state to set (`true` for in use, `false` for not in use). + */ + fun ShulkerBox.lock(boolean: Boolean) = persistentDataContainer.set(LOCK_KEY, PersistentDataType.BOOLEAN, boolean) +}