From 7fe0eece16678e2c3cce0ea5534916d1064e1f0e Mon Sep 17 00:00:00 2001 From: DaRacci Date: Tue, 27 Sep 2022 01:13:18 +1000 Subject: [PATCH] fix: handle spawning of bosses from droppers and dispensers --- .../willfp/ecobosses/spawn/SpawnEggHandler.kt | 72 +++++++++++++------ 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/spawn/SpawnEggHandler.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/spawn/SpawnEggHandler.kt index 7bf0cc7..d54ba58 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/spawn/SpawnEggHandler.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/spawn/SpawnEggHandler.kt @@ -1,46 +1,33 @@ package com.willfp.ecobosses.spawn +import com.willfp.ecobosses.EcoBossesPlugin import com.willfp.ecobosses.bosses.bossEgg import com.willfp.ecobosses.events.BossSpawnEvent import org.bukkit.Bukkit +import org.bukkit.Location +import org.bukkit.block.Container +import org.bukkit.block.data.Directional +import org.bukkit.entity.Player import org.bukkit.event.Event import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.block.Action +import org.bukkit.event.block.BlockDispenseEvent import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.inventory.EquipmentSlot +import org.bukkit.inventory.ItemStack class SpawnEggHandler : Listener { @EventHandler( ignoreCancelled = true ) fun handle(event: PlayerInteractEvent) { - if (event.action != Action.RIGHT_CLICK_BLOCK) { - return - } - - val item = event.item ?: return - val boss = item.bossEgg ?: return + if (event.action != Action.RIGHT_CLICK_BLOCK) return + if (!this.handleSpawnEgg(event.item, event.clickedBlock?.location?.add(0.0, 1.5, 0.0), event.player)) return event.isCancelled = true event.setUseItemInHand(Event.Result.DENY) - val location = event.clickedBlock?.location?.add(0.0, 1.5, 0.0) ?: return - - val player = event.player - - if (!boss.spawnConditions.all { it.condition.isConditionMet(player, it.config) }) { - return - } - - val spawnEvent = BossSpawnEvent(boss, location, BossSpawnEvent.SpawnReason.EGG, player) - - Bukkit.getPluginManager().callEvent(spawnEvent) - - if (spawnEvent.isCancelled) { - return - } - if (event.hand == EquipmentSlot.HAND) { val hand = event.player.inventory.itemInMainHand hand.amount = hand.amount - 1 @@ -48,7 +35,46 @@ class SpawnEggHandler : Listener { val hand = event.player.inventory.itemInOffHand hand.amount = hand.amount - 1 } + } + + @EventHandler( + ignoreCancelled = true + ) + fun handle(event: BlockDispenseEvent) { + val facing = (event.block.blockData as Directional).facing + val location = event.block.location.add(facing.direction.multiply(1.7)) + + if (!this.handleSpawnEgg(event.item, location, null)) return + + event.isCancelled = true + + val dispenser = event.block.state as? Container ?: return + + // This is needed as the event must finish first, + // Otherwise the dispenser/dropper thinks the item is already removed from this event. + EcoBossesPlugin.instance.scheduler.run { + val item = dispenser.inventory.find { it?.isSimilar(event.item) == true } ?: return@run + item.amount -= 1 + dispenser.update() + } + } + + private fun handleSpawnEgg( + item: ItemStack?, + location: Location?, + player: Player? + ): Boolean { + val boss = item?.bossEgg ?: return false + + if (location == null || (player != null && !boss.spawnConditions.all { it.condition.isConditionMet(player, it.config) })) return false + + val spawnEvent = BossSpawnEvent(boss, location, BossSpawnEvent.SpawnReason.EGG, player) + Bukkit.getPluginManager().callEvent(spawnEvent) + + if (spawnEvent.isCancelled) return false boss.spawn(location) + + return true } -} \ No newline at end of file +}