diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/ItemManager.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/ItemManager.kt index bbbf639..7e4b9af 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/ItemManager.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/ItemManager.kt @@ -7,7 +7,8 @@ import de.moritzruth.spigot_ttt.game.items.impl.weapons.BaseballBat import de.moritzruth.spigot_ttt.game.items.impl.weapons.Knife import de.moritzruth.spigot_ttt.game.items.impl.weapons.guns.* import de.moritzruth.spigot_ttt.game.players.TTTPlayer -import de.moritzruth.spigot_ttt.game.players.TTTPlayerDeathEvent +import de.moritzruth.spigot_ttt.game.players.TTTPlayerDeathInPreparingEvent +import de.moritzruth.spigot_ttt.game.players.TTTPlayerTrueDeathEvent import de.moritzruth.spigot_ttt.utils.isLeftClick import de.moritzruth.spigot_ttt.utils.isRightClick import de.moritzruth.spigot_ttt.utils.sendActionBarMessage @@ -16,7 +17,6 @@ import org.bukkit.Material import org.bukkit.entity.Item import org.bukkit.entity.Player import org.bukkit.event.EventHandler -import org.bukkit.event.EventPriority import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.EntityPickupItemEvent import org.bukkit.event.entity.ItemDespawnEvent @@ -129,16 +129,32 @@ object ItemManager { } } - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - fun onTTTPlayerDeath(event: TTTPlayerDeathEvent) { + @EventHandler + fun onTTTPlayerDeathInPreparing(event: TTTPlayerDeathInPreparingEvent) { val itemStackInHand = event.tttPlayer.player.inventory.itemInMainHand if (itemStackInHand.type != Material.AIR) { val instance = getInstanceByItemStack(itemStackInHand) - if (instance != null && instance.notDroppableReason == null) - GameManager.world.dropItem(event.location, instance.createItemStack()) - event.tttPlayer.getOwningTTTItemInstances().forEach { - event.tttPlayer.removeItem(it.tttItem, false) + if ( + instance != null && + !event.tttPlayer.tttClass.defaultItems.contains(instance.tttItem) && + instance.notDroppableReason == null + ) { + event.tttPlayer.removeItem(instance.tttItem, removeInstance = false, becauseOfDeath = true) + GameManager.world.dropItem(event.location, instance.createItemStack()) + } + } + } + + @EventHandler + fun onTTTPlayerTrueDeath(event: TTTPlayerTrueDeathEvent) { + val itemStackInHand = event.tttPlayer.player.inventory.itemInMainHand + if (itemStackInHand.type != Material.AIR) { + val instance = getInstanceByItemStack(itemStackInHand) + + if (instance != null && instance.notDroppableReason == null) { + event.tttPlayer.removeItem(instance.tttItem, removeInstance = false, becauseOfDeath = true) + GameManager.world.dropItem(event.location, instance.createItemStack()) } } } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/TTTItem.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/TTTItem.kt index 9250685..2f38bca 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/TTTItem.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/TTTItem.kt @@ -22,7 +22,8 @@ open class TTTItem( val instanceType: KClass, val shopInfo: ShopInfo? = null, val spawnProbability: Probability? = null, - val disableDamage: Boolean = true + val disableDamage: Boolean = true, + val removeInstanceOnDeath: Boolean = true ) { open val listener: Listener? = null open val packetListener: PacketListener? = null @@ -34,7 +35,7 @@ open class TTTItem( itemStack.itemMeta?.persistentDataContainer?.get(ID_KEY, PersistentDataType.STRING) ?.let { instancesByUUID[UUID.fromString(it)] } - fun getInstance(tttPlayer: TTTPlayer) = instancesByUUID.values.find { it.carrier === tttPlayer } + open fun getInstance(tttPlayer: TTTPlayer) = instancesByUUID.values.find { it.carrier === tttPlayer } fun reset() { instancesByUUID.values.forEach { @@ -69,7 +70,10 @@ open class TTTItem( val ID_KEY = NamespacedKey(plugin, "instance") } - abstract class Instance(val tttItem: TTTItem<*>, droppable: Boolean = true) { + abstract class Instance( + val tttItem: TTTItem<*>, + droppable: Boolean = true + ) { val uuid = UUID.randomUUID()!! fun createItemStack() = tttItem.templateItemStack.clone().applyMeta { diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/TTTItemListener.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/TTTItemListener.kt index 351c5b6..a8e7981 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/TTTItemListener.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/TTTItemListener.kt @@ -37,11 +37,7 @@ open class TTTItemListener(private val tttItem: TTT protected fun handleWithInstance(event: InventoryCloseEvent, handler: (instance: InstanceT) -> Unit) { val player = event.player - if (player is Player) { - val tttPlayer = TTTPlayer.of(player) ?: return - val instance = tttItem.getInstance(tttPlayer) ?: return - handler(instance) - } + if (player is Player) handler(TTTPlayer.of(player)?.let { tttItem.getInstance(it) } ?: return) } protected fun handleWithInstance(event: InventoryClickEvent, handler: (instance: InstanceT) -> Unit) { diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/impl/SecondChance.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/impl/SecondChance.kt index ec39e59..afaa6bd 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/impl/SecondChance.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/items/impl/SecondChance.kt @@ -40,18 +40,23 @@ object SecondChance: TTTItem( buyableBy = roles(Role.TRAITOR, Role.JACKAL), buyLimit = 1, price = 2 - ) + ), + removeInstanceOnDeath = false ) { val ON_CORPSE = Resourcepack.Items.arrowDown val ON_SPAWN = Resourcepack.Items.dot private const val TIMEOUT = 10.0 + override fun getInstance(tttPlayer: TTTPlayer) = + instancesByUUID.values.find { it.tttPlayer === tttPlayer } + class Instance: TTTItem.Instance(SecondChance, false) { var preventRoundEnd = false; private set var timeoutAction: TimeoutAction? = null + lateinit var tttPlayer: TTTPlayer fun possiblyTrigger() { - if (Random.nextBoolean()) trigger() + if (true || Random.nextBoolean()) trigger() } private fun trigger() { @@ -59,6 +64,14 @@ object SecondChance: TTTItem( timeoutAction = TimeoutAction(this) } + override fun reset() { + timeoutAction?.stop() + } + + override fun onCarrierSet(carrier: TTTPlayer, isFirst: Boolean) { + tttPlayer = carrier + } + class TimeoutAction(private val instance: Instance) { val deathLocation: Location = instance.requireCarrier().player.location private val startedAt = Instant.now()!! @@ -66,7 +79,11 @@ object SecondChance: TTTItem( "${ChatColor.GREEN}${ChatColor.BOLD}Second Chance", BarColor.GREEN, BarStyle.SOLID - ).also { it.addPlayer(instance.requireCarrier().player) } + ).also { it.addPlayer(instance.tttPlayer.player) } + + init { + instance.tttPlayer.player.openInventory(chooseSpawnInventory) + } private var task: BukkitTask = plugin.server.scheduler.runTaskTimer(plugin, fun() { val duration = Duration.between(startedAt, Instant.now()).toMillis().toDouble() / 1000 @@ -79,18 +96,16 @@ object SecondChance: TTTItem( try { PlayerManager.letRemainingRoleGroupWin() } catch (e: IllegalStateException) {} - stop() } fun stop() { - val carrier = instance.requireCarrier() task.cancel() - carrier.player.apply { + instance.tttPlayer.player.apply { closeInventory() bossBar.removePlayer(this) } - carrier.removeItem(SecondChance) + instancesByUUID.remove(instance.uuid) } } } @@ -127,8 +142,10 @@ object SecondChance: TTTItem( @EventHandler fun onInventoryClose(event: InventoryCloseEvent) { if (event.inventory == chooseSpawnInventory) { - handleWithInstance(event) { instance -> - nextTick { instance.carrier?.player?.openInventory(chooseSpawnInventory) } + nextTick { + handleWithInstance(event) { instance -> + instance.tttPlayer.player.openInventory(chooseSpawnInventory) + } } } } @@ -147,7 +164,7 @@ object SecondChance: TTTItem( } timeoutAction.stop() - instance.carrier!!.revive(location) + instance.tttPlayer.revive(location) } } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayer.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayer.kt index 15a5e1a..625a10f 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayer.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayer.kt @@ -84,7 +84,7 @@ class TTTPlayer(player: Player, role: Role, val tttClass: TTTClassCompanion = TT if (GameManager.phase == GamePhase.PREPARING) { player.sendMessage("${TTTPlugin.prefix}${ChatColor.GRAY}${ChatColor.ITALIC}Du wirst nach der Vorbereitungsphase wiederbelebt") - val event = TTTPlayerDeathEvent( + val event = TTTPlayerDeathInPreparingEvent( tttPlayer = this, location = player.location, killer = killer, @@ -98,19 +98,12 @@ class TTTPlayer(player: Player, role: Role, val tttClass: TTTClassCompanion = TT val onlyRemainingRoleGroup = PlayerManager.getOnlyRemainingRoleGroup() - val firstEvent = TTTPlayerDeathEvent( - tttPlayer = this, - location = player.location, - killer = killer, - scream = reallyScream - ).call() - val event = TTTPlayerTrueDeathEvent( tttPlayer = this, location = player.location, tttCorpse = tttCorpse, killer = killer, - scream = firstEvent.scream, + scream = reallyScream, winnerRoleGroup = onlyRemainingRoleGroup ).call() @@ -118,6 +111,8 @@ class TTTPlayer(player: Player, role: Role, val tttClass: TTTClassCompanion = TT event.winnerRoleGroup?.run { GameManager.letRoleWin(primaryRole) } } + clearInventory(true) + if (reallyScream) GameManager.world.playSound( player.location, Resourcepack.Sounds.playerDeath, @@ -150,7 +145,7 @@ class TTTPlayer(player: Player, role: Role, val tttClass: TTTClassCompanion = TT player.scoreboard = scoreboard.scoreboard } - fun getOwningTTTItemInstances() = player.inventory.hotbarContents + private fun getOwningTTTItemInstances() = player.inventory.hotbarContents .filterNotNull() .mapNotNull { ItemManager.getInstanceByItemStack(it) } @@ -195,11 +190,21 @@ class TTTPlayer(player: Player, role: Role, val tttClass: TTTClassCompanion = TT player.exp = 0F player.allowFlight = player.gameMode == GameMode.CREATIVE player.foodLevel = 20 - player.inventory.clear() + clearInventory(false) tttClassInstance.reset() } + private fun clearInventory(becauseOfDeath: Boolean) { + val owningTTTItemInstances = getOwningTTTItemInstances() + + owningTTTItemInstances.forEach { + if (!(tttClass.defaultItems.contains(it.tttItem) && GameManager.phase == GamePhase.PREPARING)) { + removeItem(it.tttItem, becauseOfDeath = becauseOfDeath) + } + } + } + fun checkAddItemPreconditions(tttItem: TTTItem<*>) { val owningTTTItemInstances = getOwningTTTItemInstances() if (owningTTTItemInstances.find { it.tttItem === tttItem } != null) throw AlreadyHasItemException() @@ -221,10 +226,13 @@ class TTTPlayer(player: Player, role: Role, val tttClass: TTTClassCompanion = TT instance.carrier = this } - fun removeItem(item: TTTItem<*>, removeInstance: Boolean = true) { + fun removeItem(item: TTTItem<*>, removeInstance: Boolean = true, becauseOfDeath: Boolean = false) { item.getInstance(this)?.let { it.carrier = null - if (removeInstance) item.instancesByUUID.remove(it.uuid) + if (removeInstance && (!becauseOfDeath || it.tttItem.removeInstanceOnDeath)) { + item.instancesByUUID.remove(it.uuid) + it.reset() + } } player.inventory.removeTTTItem(item) diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayerDeathInPreparingEvent.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayerDeathInPreparingEvent.kt new file mode 100644 index 0000000..0f41932 --- /dev/null +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayerDeathInPreparingEvent.kt @@ -0,0 +1,24 @@ +package de.moritzruth.spigot_ttt.game.players + +import org.bukkit.Location +import org.bukkit.event.Event +import org.bukkit.event.HandlerList + +open class TTTPlayerDeathInPreparingEvent( + val tttPlayer: TTTPlayer, + val location: Location, + val killer: TTTPlayer?, + var scream: Boolean = true +): Event() { + override fun getHandlers(): HandlerList { + @Suppress("RedundantCompanionReference") // false positive + return Companion.handlers + } + + companion object { + private val handlers = HandlerList() + + @JvmStatic + fun getHandlerList() = handlers + } +} diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayerTrueDeathEvent.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayerTrueDeathEvent.kt index dffb137..a97c006 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayerTrueDeathEvent.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayerTrueDeathEvent.kt @@ -5,11 +5,13 @@ import org.bukkit.Location import org.bukkit.event.Event import org.bukkit.event.HandlerList -open class TTTPlayerDeathEvent( +class TTTPlayerTrueDeathEvent( val tttPlayer: TTTPlayer, val location: Location, val killer: TTTPlayer?, - var scream: Boolean = true + val scream: Boolean = true, + val tttCorpse: TTTCorpse, + var winnerRoleGroup: RoleGroup? = null ): Event() { override fun getHandlers(): HandlerList { @Suppress("RedundantCompanionReference") // false positive @@ -23,29 +25,3 @@ open class TTTPlayerDeathEvent( fun getHandlerList() = handlers } } - -class TTTPlayerTrueDeathEvent( - tttPlayer: TTTPlayer, - location: Location, - killer: TTTPlayer?, - scream: Boolean = true, - val tttCorpse: TTTCorpse, - var winnerRoleGroup: RoleGroup? = null -): TTTPlayerDeathEvent( - tttPlayer, - location, - killer, - scream -) { - override fun getHandlers(): HandlerList { - @Suppress("RedundantCompanionReference") // false positive - return Companion.handlers - } - - companion object { - private val handlers = HandlerList() - - @JvmStatic - fun getHandlerList() = handlers - } -}