1
0
Fork 0

Allow multiple listeners for a single TTTItem

This commit is contained in:
Moritz Ruth 2020-06-21 17:16:27 +02:00
parent 1d638db078
commit ce4502d3d8
No known key found for this signature in database
GPG key ID: AFD57E23E753841B
17 changed files with 468 additions and 432 deletions

View file

@ -32,6 +32,7 @@ object Resourcepack {
val boomBody = Material.BIRCH_WOOD val boomBody = Material.BIRCH_WOOD
val defibrillator = Material.IRON_INGOT val defibrillator = Material.IRON_INGOT
val secondChance = Material.GOLD_INGOT val secondChance = Material.GOLD_INGOT
val beeBomb = Material.BEEHIVE
// Weapons // Weapons
val deagle = Material.IRON_HOE val deagle = Material.IRON_HOE

View file

@ -55,9 +55,9 @@ object GeneralGameListener : Listener {
@EventHandler @EventHandler
fun onEntityDamageByEntity(event: EntityDamageByEntityEvent) { fun onEntityDamageByEntity(event: EntityDamageByEntityEvent) {
val player = event.damager val damager = event.damager
if (player is Player) { if (damager is Player) {
if (player.inventory.itemInMainHand.type == Material.AIR) { if (damager.inventory.itemInMainHand.type == Material.AIR) {
event.damage = 0.2 event.damage = 0.2
} }
} }
@ -77,9 +77,9 @@ object GeneralGameListener : Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
fun onEntityDamageLow(event: EntityDamageEvent) { fun onEntityDamageLow(event: EntityDamageEvent) {
if (ZERO_NO_DAMAGE_TICKS_CAUSES.contains(event.cause)) { if (ZERO_NO_DAMAGE_TICKS_CAUSES.contains(event.cause)) {
val player = event.entity val entity = event.entity
if (player is Player) { if (entity is Player) {
nextTick { player.noDamageTicks = 0 } nextTick { entity.noDamageTicks = 0 }
} }
} }
} }

View file

@ -0,0 +1,176 @@
package de.moritzruth.spigot_ttt.game.items
import com.codingforcookies.armorequip.ArmorEquipEvent
import de.moritzruth.spigot_ttt.game.GameListener
import de.moritzruth.spigot_ttt.game.GameManager
import de.moritzruth.spigot_ttt.game.players.TTTPlayer
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.nextTick
import de.moritzruth.spigot_ttt.utils.sendActionBarMessage
import org.bukkit.GameMode
import org.bukkit.Material
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
import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.InventoryAction
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.player.PlayerDropItemEvent
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.event.player.PlayerItemHeldEvent
import org.bukkit.event.player.PlayerSwapHandItemsEvent
object ItemListener: GameListener() {
@EventHandler(priority = EventPriority.LOW)
fun onInventoryClick(event: InventoryClickEvent) = handle(event) { tttPlayer ->
if (event.click === ClickType.CREATIVE || event.clickedInventory?.holder != event.whoClicked) return@handle
if (event.slot in 0..8) {
// is in hotbar
when(event.action) {
InventoryAction.PICKUP_ALL,
InventoryAction.PICKUP_HALF,
InventoryAction.PICKUP_ONE -> {
event.currentItem?.also { itemStack -> ItemManager.getInstanceByItemStack(itemStack)?.isSelected = false }
}
InventoryAction.PLACE_ALL,
InventoryAction.PLACE_SOME,
InventoryAction.PLACE_ONE -> {
nextTick {
if (event.slot == tttPlayer.player.inventory.heldItemSlot) {
tttPlayer.player.inventory.getItem(event.slot)?.also { itemStack ->
ItemManager.getInstanceByItemStack(itemStack)?.isSelected = true
}
}
}
}
else -> event.isCancelled = true
}
}
}
@EventHandler
fun onArmorEquip(event: ArmorEquipEvent) {
if (event.player.gameMode != GameMode.CREATIVE) event.isCancelled = true
}
@EventHandler(ignoreCancelled = true)
fun onPlayerInteract(event: PlayerInteractEvent) = handle(event) { tttPlayer ->
if (tttPlayer.ignoreNextInteract) {
tttPlayer.ignoreNextInteract = false
event.isCancelled = true
return@handle
}
val instance = event.item?.let { ItemManager.getInstanceByItemStack(it) } ?: return@handle
val clickEvent = ClickEvent()
if (event.action.isLeftClick) instance.onLeftClick(clickEvent)
else if (event.action.isRightClick) instance.onRightClick(clickEvent)
event.isCancelled = clickEvent.isCancelled
}
@EventHandler(ignoreCancelled = true)
fun onEntityDamageByEntity(event: EntityDamageByEntityEvent) {
val damager = event.damager
if (damager is Player) {
TTTPlayer.of(damager) ?: return
val item = damager.inventory.itemInMainHand
if (item.type != Material.AIR) {
val tttItem = ItemManager.getTTTItemByItemStack(item) ?: return
event.isCancelled = tttItem.disableDamage
}
}
}
@EventHandler
fun onPlayerSwapHandItems(event: PlayerSwapHandItemsEvent) = handle(event) { _ ->
val instance = event.offHandItem?.let { ItemManager.getInstanceByItemStack(it) } ?: return@handle
instance.onHandSwap()
event.isCancelled = true
}
@EventHandler
fun onPlayerItemHeld(event: PlayerItemHeldEvent) = handle(event) { tttPlayer ->
tttPlayer.player.inventory.getItem(event.previousSlot)
?.also { itemStack -> ItemManager.getInstanceByItemStack(itemStack)?.isSelected = false }
tttPlayer.player.inventory.getItem(event.newSlot)
?.also { itemStack -> ItemManager.getInstanceByItemStack(itemStack)?.isSelected = true }
}
@EventHandler
fun onPlayerDropItem(event: PlayerDropItemEvent) = handle(event) { tttPlayer ->
val instance = ItemManager.getInstanceByItemStack(event.itemDrop.itemStack) ?: return@handle
val notDroppableReason = instance.notDroppableReason
if (notDroppableReason == null) {
instance.carrier = null
} else {
tttPlayer.player.sendActionBarMessage(notDroppableReason)
event.isCancelled = true
}
}
@EventHandler
fun onEntityPickupItem(event: EntityPickupItemEvent) {
val player = event.entity
if (player !is Player) return
val tttPlayer = TTTPlayer.of(player) ?: return
val instance = ItemManager.getInstanceByItemStack(event.item.itemStack)
if (instance != null) {
if (runCatching { tttPlayer.checkAddItemPreconditions(instance.tttItem) }.isSuccess) {
instance.carrier = tttPlayer
return
}
}
event.isCancelled = true
}
@EventHandler
fun onItemDespawn(event: ItemDespawnEvent) {
if (ItemManager.getTTTItemByItemStack(event.entity.itemStack) != null) {
event.entity.ticksLived = 1
event.isCancelled = true
}
}
@EventHandler
fun onTTTPlayerDeathInPreparing(event: TTTPlayerDeathInPreparingEvent) {
val itemStackInHand = event.tttPlayer.player.inventory.itemInMainHand
if (itemStackInHand.type != Material.AIR) {
val instance = ItemManager.getInstanceByItemStack(itemStackInHand)
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 = ItemManager.getInstanceByItemStack(itemStackInHand)
if (instance != null && instance.notDroppableReason == null) {
event.tttPlayer.removeItem(instance.tttItem, removeInstance = false, becauseOfDeath = true)
GameManager.world.dropItem(event.location, instance.createItemStack())
}
}
}
}

View file

@ -1,37 +1,14 @@
package de.moritzruth.spigot_ttt.game.items package de.moritzruth.spigot_ttt.game.items
import com.codingforcookies.armorequip.ArmorEquipEvent
import de.moritzruth.spigot_ttt.game.GameListener
import de.moritzruth.spigot_ttt.game.GameManager import de.moritzruth.spigot_ttt.game.GameManager
import de.moritzruth.spigot_ttt.game.items.impl.* import de.moritzruth.spigot_ttt.game.items.impl.*
import de.moritzruth.spigot_ttt.game.items.impl.weapons.BaseballBat import de.moritzruth.spigot_ttt.game.items.impl.weapons.BaseballBat
import de.moritzruth.spigot_ttt.game.items.impl.weapons.Fireball import de.moritzruth.spigot_ttt.game.items.impl.weapons.Fireball
import de.moritzruth.spigot_ttt.game.items.impl.weapons.Knife 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.items.impl.weapons.guns.*
import de.moritzruth.spigot_ttt.game.players.TTTPlayer
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.nextTick
import de.moritzruth.spigot_ttt.utils.sendActionBarMessage
import org.bukkit.GameMode
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.Item 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
import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.InventoryAction
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.player.PlayerDropItemEvent
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.event.player.PlayerItemHeldEvent
import org.bukkit.event.player.PlayerSwapHandItemsEvent
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
object ItemManager { object ItemManager {
@ -41,8 +18,8 @@ object ItemManager {
Shotgun, Radar, SecondChance, BoomBody, TreeGun Shotgun, Radar, SecondChance, BoomBody, TreeGun
) )
val listeners get () = ITEMS.mapNotNull { it.listener }.plus(listener) val listeners get () = ITEMS.flatMap { it.listeners }.plus(ItemListener)
val packetListeners get () = ITEMS.mapNotNull { it.packetListener } val packetListeners get () = ITEMS.flatMap { it.packetListeners }
private fun getTTTItemByMaterial(material: Material) = ITEMS.find { tttItem -> material == tttItem.material } private fun getTTTItemByMaterial(material: Material) = ITEMS.find { tttItem -> material == tttItem.material }
fun getTTTItemByItemStack(itemStack: ItemStack) = getTTTItemByMaterial(itemStack.type) fun getTTTItemByItemStack(itemStack: ItemStack) = getTTTItemByMaterial(itemStack.type)
@ -57,153 +34,4 @@ object ItemManager {
GameManager.world.getEntitiesByClass(Item::class.java).forEach(Item::remove) GameManager.world.getEntitiesByClass(Item::class.java).forEach(Item::remove)
ITEMS.forEach(TTTItem<*>::reset) ITEMS.forEach(TTTItem<*>::reset)
} }
val listener = object : GameListener() {
@EventHandler(priority = EventPriority.LOW)
fun onInventoryClick(event: InventoryClickEvent) = handle(event) { tttPlayer ->
if (event.click === ClickType.CREATIVE || event.clickedInventory?.holder != event.whoClicked) return@handle
if (event.slot in 0..8) {
// is in hotbar
when(event.action) {
InventoryAction.PICKUP_ALL,
InventoryAction.PICKUP_HALF,
InventoryAction.PICKUP_ONE -> {
event.currentItem?.also { itemStack -> getInstanceByItemStack(itemStack)?.isSelected = false }
}
InventoryAction.PLACE_ALL,
InventoryAction.PLACE_SOME,
InventoryAction.PLACE_ONE -> {
nextTick {
if (event.slot == tttPlayer.player.inventory.heldItemSlot) {
tttPlayer.player.inventory.getItem(event.slot)?.also { itemStack ->
getInstanceByItemStack(itemStack)?.isSelected = true
}
}
}
}
else -> event.isCancelled = true
}
}
}
@EventHandler
fun onArmorEquip(event: ArmorEquipEvent) {
if (event.player.gameMode != GameMode.CREATIVE) event.isCancelled = true
}
@EventHandler(ignoreCancelled = true)
fun onPlayerInteract(event: PlayerInteractEvent) = handle(event) { tttPlayer ->
if (tttPlayer.ignoreNextInteract) {
tttPlayer.ignoreNextInteract = false
event.isCancelled = true
return@handle
}
val instance = event.item?.let { getInstanceByItemStack(it) } ?: return@handle
val clickEvent = ClickEvent()
if (event.action.isLeftClick) instance.onLeftClick(clickEvent)
else if (event.action.isRightClick) instance.onRightClick(clickEvent)
event.isCancelled = clickEvent.isCancelled
}
@EventHandler(ignoreCancelled = true)
fun onEntityDamageByEntity(event: EntityDamageByEntityEvent) {
val damager = event.damager
if (damager is Player) {
TTTPlayer.of(damager) ?: return
val item = damager.inventory.itemInMainHand
if (item.type != Material.AIR) {
val tttItem = getTTTItemByItemStack(item) ?: return
event.isCancelled = tttItem.disableDamage
}
}
}
@EventHandler
fun onPlayerSwapHandItems(event: PlayerSwapHandItemsEvent) = handle(event) { _ ->
val instance = event.offHandItem?.let { getInstanceByItemStack(it) } ?: return@handle
instance.onHandSwap()
event.isCancelled = true
}
@EventHandler
fun onPlayerItemHeld(event: PlayerItemHeldEvent) = handle(event) { tttPlayer ->
tttPlayer.player.inventory.getItem(event.previousSlot)
?.also { itemStack -> getInstanceByItemStack(itemStack)?.isSelected = false }
tttPlayer.player.inventory.getItem(event.newSlot)
?.also { itemStack -> getInstanceByItemStack(itemStack)?.isSelected = true }
}
@EventHandler
fun onPlayerDropItem(event: PlayerDropItemEvent) = handle(event) { tttPlayer ->
val instance = getInstanceByItemStack(event.itemDrop.itemStack) ?: return@handle
val notDroppableReason = instance.notDroppableReason
if (notDroppableReason == null) {
instance.carrier = null
} else {
tttPlayer.player.sendActionBarMessage(notDroppableReason)
event.isCancelled = true
}
}
@EventHandler
fun onEntityPickupItem(event: EntityPickupItemEvent) {
val player = event.entity
if (player !is Player) return
val tttPlayer = TTTPlayer.of(player) ?: return
val instance = getInstanceByItemStack(event.item.itemStack)
if (instance != null) {
if (runCatching { tttPlayer.checkAddItemPreconditions(instance.tttItem) }.isSuccess) {
instance.carrier = tttPlayer
return
}
}
event.isCancelled = true
}
@EventHandler
fun onItemDespawn(event: ItemDespawnEvent) {
if (getTTTItemByItemStack(event.entity.itemStack) != null) {
event.entity.ticksLived = 1
event.isCancelled = true
}
}
@EventHandler
fun onTTTPlayerDeathInPreparing(event: TTTPlayerDeathInPreparingEvent) {
val itemStackInHand = event.tttPlayer.player.inventory.itemInMainHand
if (itemStackInHand.type != Material.AIR) {
val instance = getInstanceByItemStack(itemStackInHand)
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())
}
}
}
}
} }

View file

@ -24,8 +24,16 @@ open class TTTItem<InstanceT: TTTItem.Instance>(
val disableDamage: Boolean = true, val disableDamage: Boolean = true,
val removeInstanceOnDeath: Boolean = true val removeInstanceOnDeath: Boolean = true
) { ) {
open val listener: Listener? = null var listeners: Set<Listener> = emptySet(); private set
open val packetListener: PacketListener? = null var packetListeners: Set<PacketListener> = emptySet(); private set
protected fun addListener(listener: Listener) {
listeners = listeners + listener
}
protected fun addListener(packetListener: PacketListener) {
packetListeners = packetListeners + packetListener
}
val material = templateItemStack.type val material = templateItemStack.type

View file

@ -55,52 +55,54 @@ object BoomBody: TTTItem<BoomBody.Instance>(
val boomBodies: MutableSet<TTTCorpse> = Collections.newSetFromMap(WeakHashMap<TTTCorpse, Boolean>()) val boomBodies: MutableSet<TTTCorpse> = Collections.newSetFromMap(WeakHashMap<TTTCorpse, Boolean>())
override val listener = object : TTTItemListener<Instance>(this) { init {
@EventHandler addListener(object : TTTItemListener<Instance>(this) {
fun onCorpseClick(event: CorpseClickEvent) { @EventHandler
if (boomBodies.contains(event.tttCorpse)) { fun onCorpseClick(event: CorpseClickEvent) {
boomBodies.remove(event.tttCorpse) if (boomBodies.contains(event.tttCorpse)) {
event.tttCorpse.destroy() boomBodies.remove(event.tttCorpse)
event.isCancelled = true event.tttCorpse.destroy()
createKillExplosion(event.tttCorpse.spawnedBy!!, event.tttCorpse.location, 5.0) event.isCancelled = true
} createKillExplosion(event.tttCorpse.spawnedBy!!, event.tttCorpse.location, 5.0)
}
@EventHandler
fun onInventoryClick(event: InventoryClickEvent) = handle(event) { tttPlayer ->
val instance = getInstance(tttPlayer) ?: return@handle
if (event.clickedInventory !== instance.choosePlayerInventory) return@handle
event.isCancelled = true
val item = event.currentItem
if (item != null && event.click == ClickType.LEFT) {
tttPlayer.player.closeInventory()
val corpsePlayer = plugin.server.getPlayer((item.itemMeta as SkullMeta).owningPlayer!!.uniqueId)!!
val corpseTTTPlayer = TTTPlayer.of(corpsePlayer)
if (corpseTTTPlayer == null) {
tttPlayer.player.sendActionBarMessage("${ChatColor.RED}Das hat nicht funktioniert")
} else {
GameManager.world.playSound(
tttPlayer.player.location,
Resourcepack.Sounds.playerDeath,
SoundCategory.PLAYERS,
1F,
1F
)
boomBodies.add(TTTCorpse.spawnFake(
Role.INNOCENT,
corpseTTTPlayer,
tttPlayer,
tttPlayer.player.location
))
tttPlayer.removeItem(BoomBody)
} }
} }
}
@EventHandler
fun onInventoryClick(event: InventoryClickEvent) = handle(event) { tttPlayer ->
val instance = getInstance(tttPlayer) ?: return@handle
if (event.clickedInventory !== instance.choosePlayerInventory) return@handle
event.isCancelled = true
val item = event.currentItem
if (item != null && event.click == ClickType.LEFT) {
tttPlayer.player.closeInventory()
val corpsePlayer = plugin.server.getPlayer((item.itemMeta as SkullMeta).owningPlayer!!.uniqueId)!!
val corpseTTTPlayer = TTTPlayer.of(corpsePlayer)
if (corpseTTTPlayer == null) {
tttPlayer.player.sendActionBarMessage("${ChatColor.RED}Das hat nicht funktioniert")
} else {
GameManager.world.playSound(
tttPlayer.player.location,
Resourcepack.Sounds.playerDeath,
SoundCategory.PLAYERS,
1F,
1F
)
boomBodies.add(TTTCorpse.spawnFake(
Role.INNOCENT,
corpseTTTPlayer,
tttPlayer,
tttPlayer.player.location
))
tttPlayer.removeItem(BoomBody)
}
}
}
})
} }
} }

View file

@ -81,10 +81,12 @@ object CloakingDevice: TTTItem<CloakingDevice.Instance>(
} }
} }
override val listener = object : TTTItemListener<Instance>(CloakingDevice) { init {
@EventHandler addListener(object : TTTItemListener<Instance>(CloakingDevice) {
fun onPlayerToggleSprint(event: PlayerToggleSprintEvent) = handleWithInstance(event) { instance -> @EventHandler
if (event.isSprinting && instance.enabled) event.isCancelled = true fun onPlayerToggleSprint(event: PlayerToggleSprintEvent) = handleWithInstance(event) { instance ->
} if (event.isSprinting && instance.enabled) event.isCancelled = true
}
})
} }
} }

View file

@ -65,37 +65,39 @@ object Defibrillator: TTTItem<Defibrillator.Instance>(
it.stopSound(Resourcepack.Sounds.Item.Defibrillator.use, SoundCategory.PLAYERS) it.stopSound(Resourcepack.Sounds.Item.Defibrillator.use, SoundCategory.PLAYERS)
} }
override val listener = object : TTTItemListener<Instance>(this) { init {
@EventHandler(ignoreCancelled = true) addListener(object : TTTItemListener<Instance>(this) {
fun onCorpseClick(event: CorpseClickEvent) { @EventHandler(ignoreCancelled = true)
val instance = getInstance(event.tttPlayer.player.inventory.itemInMainHand) ?: return fun onCorpseClick(event: CorpseClickEvent) {
event.isCancelled = true val instance = getInstance(event.tttPlayer.player.inventory.itemInMainHand) ?: return
event.isCancelled = true
when(val action = instance.action) { when(val action = instance.action) {
null -> instance.action = Action.Reviving(event.tttPlayer, instance) null -> instance.action = Action.Reviving(event.tttPlayer, instance)
is Action.Reviving -> { is Action.Reviving -> {
action.cancelTask.cancel() action.cancelTask.cancel()
action.cancelTask = action.createCancelTask() action.cancelTask = action.createCancelTask()
val progress = action.duration / REVIVE_DURATION val progress = action.duration / REVIVE_DURATION
if (progress >= 1) { if (progress >= 1) {
try { try {
event.tttCorpse.revive() event.tttCorpse.revive()
event.tttPlayer.player.sendActionBarMessage( event.tttPlayer.player.sendActionBarMessage(
"${ChatColor.BOLD}${event.tttCorpse.tttPlayer.player.displayName} " + "${ChatColor.BOLD}${event.tttCorpse.tttPlayer.player.displayName} " +
"${ChatColor.GREEN}wurde wiederbelebt" "${ChatColor.GREEN}wurde wiederbelebt"
) )
action.cancelTask.cancel() action.cancelTask.cancel()
event.tttPlayer.removeItem(Defibrillator) event.tttPlayer.removeItem(Defibrillator)
} catch(e: TTTPlayer.AlreadyLivingException) { } catch(e: TTTPlayer.AlreadyLivingException) {
action.cancel() action.cancel()
} }
} else instance.bossBar.progress = progress } else instance.bossBar.progress = progress
}
is Action.Canceled -> noop()
} }
is Action.Canceled -> noop()
} }
} })
} }
sealed class Action(val tttPlayer: TTTPlayer) { sealed class Action(val tttPlayer: TTTPlayer) {

View file

@ -69,61 +69,63 @@ object FakeCorpse: TTTItem<FakeCorpse.Instance>(
.toTypedArray()) .toTypedArray())
} }
override val listener = object : TTTItemListener<Instance>(this) { init {
@EventHandler addListener(object : TTTItemListener<Instance>(this) {
fun onInventoryClick(event: InventoryClickEvent) = handle(event) { tttPlayer -> @EventHandler
val instance = getInstance(tttPlayer) ?: return@handle fun onInventoryClick(event: InventoryClickEvent) = handle(event) { tttPlayer ->
val instance = getInstance(tttPlayer) ?: return@handle
if ( if (
!setOf( !setOf(
instance.choosePlayerInventory, instance.choosePlayerInventory,
chooseRoleInventory chooseRoleInventory
).contains(event.clickedInventory) ).contains(event.clickedInventory)
) return@handle ) return@handle
event.isCancelled = true event.isCancelled = true
val item = event.currentItem val item = event.currentItem
if (item != null && event.click == ClickType.LEFT) { if (item != null && event.click == ClickType.LEFT) {
when (event.clickedInventory) { when (event.clickedInventory) {
chooseRoleInventory -> { chooseRoleInventory -> {
instance.chosenRole = Role.values()[event.slot] instance.chosenRole = Role.values()[event.slot]
val choosePlayerInventory = createPlayerHeadInventory( val choosePlayerInventory = createPlayerHeadInventory(
"${INVENTORY_TITLE}${ChatColor.RESET} - Spieler", "${INVENTORY_TITLE}${ChatColor.RESET} - Spieler",
PlayerManager.tttPlayers.map { it.player } PlayerManager.tttPlayers.map { it.player }
)
instance.choosePlayerInventory = choosePlayerInventory
tttPlayer.player.openInventory(choosePlayerInventory)
}
instance.choosePlayerInventory -> {
tttPlayer.player.closeInventory()
val corpsePlayer = plugin.server.getPlayer((item.itemMeta as SkullMeta).owningPlayer!!.uniqueId)!!
val corpseTTTPlayer = TTTPlayer.of(corpsePlayer)
if (corpseTTTPlayer == null) {
tttPlayer.player.sendActionBarMessage("${ChatColor.RED}Das hat nicht funktioniert")
} else {
GameManager.world.playSound(
tttPlayer.player.location,
Resourcepack.Sounds.playerDeath,
SoundCategory.PLAYERS,
1F,
1F
) )
instance.choosePlayerInventory = choosePlayerInventory
tttPlayer.player.openInventory(choosePlayerInventory)
}
instance.choosePlayerInventory -> {
tttPlayer.player.closeInventory()
TTTCorpse.spawnFake( val corpsePlayer = plugin.server.getPlayer((item.itemMeta as SkullMeta).owningPlayer!!.uniqueId)!!
instance.chosenRole!!, val corpseTTTPlayer = TTTPlayer.of(corpsePlayer)
corpseTTTPlayer,
tttPlayer,
tttPlayer.player.location
)
tttPlayer.removeItem(FakeCorpse) if (corpseTTTPlayer == null) {
tttPlayer.player.sendActionBarMessage("${ChatColor.RED}Das hat nicht funktioniert")
} else {
GameManager.world.playSound(
tttPlayer.player.location,
Resourcepack.Sounds.playerDeath,
SoundCategory.PLAYERS,
1F,
1F
)
TTTCorpse.spawnFake(
instance.chosenRole!!,
corpseTTTPlayer,
tttPlayer,
tttPlayer.player.location
)
tttPlayer.removeItem(FakeCorpse)
}
} }
} }
} }
} }
} })
} }
} }

View file

@ -39,13 +39,15 @@ object HealingPotion: TTTItem<HealingPotion.Instance>(
buyLimit = 2 buyLimit = 2
) )
) { ) {
override val listener = object : TTTItemListener<Instance>(this) { init {
@EventHandler addListener(object : TTTItemListener<Instance>(this) {
fun onPlayerItemConsume(event: PlayerItemConsumeEvent) = handle(event) { @EventHandler
event.isCancelled = true fun onPlayerItemConsume(event: PlayerItemConsumeEvent) = handle(event) {
event.player.inventory.clear(event.player.inventory.indexOf(event.item)) event.isCancelled = true
event.player.health = event.player.getAttribute(Attribute.GENERIC_MAX_HEALTH)?.value ?: 100.0 event.player.inventory.clear(event.player.inventory.indexOf(event.item))
} event.player.health = event.player.getAttribute(Attribute.GENERIC_MAX_HEALTH)?.value ?: 100.0
}
})
} }
class Instance: TTTItem.Instance(HealingPotion) class Instance: TTTItem.Instance(HealingPotion)

View file

@ -47,24 +47,26 @@ object MartyrdomGrenade: TTTItem<MartyrdomGrenade.Instance>(
} }
} }
override val listener = object : TTTItemListener<Instance>(this) { init {
@EventHandler addListener(object : TTTItemListener<Instance>(this) {
fun onTTTPlayerTrueDeath(event: TTTPlayerTrueDeathEvent) { @EventHandler
val instance = getInstance(event.tttPlayer) ?: return fun onTTTPlayerTrueDeath(event: TTTPlayerTrueDeathEvent) {
instance.tttPlayer = event.tttPlayer val instance = getInstance(event.tttPlayer) ?: return
instance.tttPlayer = event.tttPlayer
instance.explodeTask = plugin.server.scheduler.runTaskLater(plugin, fun() { instance.explodeTask = plugin.server.scheduler.runTaskLater(plugin, fun() {
GameManager.world.playSound( GameManager.world.playSound(
event.location, event.location,
Resourcepack.Sounds.grenadeExplode, Resourcepack.Sounds.grenadeExplode,
SoundCategory.PLAYERS, SoundCategory.PLAYERS,
1F, 1F,
1F 1F
) )
createKillExplosion(event.tttPlayer, event.location, 5.0) createKillExplosion(event.tttPlayer, event.location, 5.0)
instance.remove() instance.remove()
}, secondsToTicks(3).toLong()) }, secondsToTicks(3).toLong())
} }
})
} }
} }

View file

@ -106,27 +106,29 @@ object Radar: TTTItem<Radar.Instance>(
} }
} }
override val packetListener = object : PacketAdapter(plugin, PacketType.Play.Server.ENTITY_METADATA) { init {
override fun onPacketSending(event: PacketEvent) { addListener(object : PacketAdapter(plugin, PacketType.Play.Server.ENTITY_METADATA) {
val receivingTTTPlayer = TTTPlayer.of(event.player) ?: return override fun onPacketSending(event: PacketEvent) {
val receivingTTTPlayer = TTTPlayer.of(event.player) ?: return
val packet = WrapperPlayServerEntityMetadata(event.packet) val packet = WrapperPlayServerEntityMetadata(event.packet)
val tttPlayerOfPacket = plugin.server.onlinePlayers val tttPlayerOfPacket = plugin.server.onlinePlayers
.find { it.entityId == packet.entityID } .find { it.entityId == packet.entityID }
?.let { TTTPlayer.of(it) } ?: return ?.let { TTTPlayer.of(it) } ?: return
val instance = getInstance(receivingTTTPlayer) ?: return val instance = getInstance(receivingTTTPlayer) ?: return
if (tttPlayerOfPacket.alive) { if (tttPlayerOfPacket.alive) {
// https://wiki.vg/Entity_metadata#Entity_Metadata_Format // https://wiki.vg/Entity_metadata#Entity_Metadata_Format
try { try {
val modifiers = packet.metadata[0].value as Byte val modifiers = packet.metadata[0].value as Byte
packet.metadata[0].value = packet.metadata[0].value =
if (instance.active) modifiers or 0x40.toByte() if (instance.active) modifiers or 0x40.toByte()
else modifiers and 0b10111111.toByte() else modifiers and 0b10111111.toByte()
} catch (ignored: Exception) { } catch (ignored: Exception) {
// Idk why this throws exceptions, but it works anyways // Idk why this throws exceptions, but it works anyways
}
} }
} }
} })
} }
} }

View file

@ -155,44 +155,46 @@ object SecondChance: TTTItem<SecondChance.Instance>(
}) })
} }
override val listener = object : TTTItemListener<Instance>(this) { init {
@EventHandler addListener(object : TTTItemListener<Instance>(this) {
fun onTTTPlayerTrueDeath(event: TTTPlayerTrueDeathEvent) { @EventHandler
val instance = getInstance(event.tttPlayer) ?: return fun onTTTPlayerTrueDeath(event: TTTPlayerTrueDeathEvent) {
instance.possiblyTrigger(event.tttCorpse) val instance = getInstance(event.tttPlayer) ?: return
event.winnerRoleGroup = PlayerManager.getOnlyRemainingRoleGroup() instance.possiblyTrigger(event.tttCorpse)
} event.winnerRoleGroup = PlayerManager.getOnlyRemainingRoleGroup()
}
@EventHandler @EventHandler
fun onInventoryClose(event: InventoryCloseEvent) { fun onInventoryClose(event: InventoryCloseEvent) {
if (event.inventory === chooseSpawnInventory || event.inventory === chooseSpawnWithoutCorpseInventory) { if (event.inventory === chooseSpawnInventory || event.inventory === chooseSpawnWithoutCorpseInventory) {
nextTick { nextTick {
handleWithInstance(event) { instance -> handleWithInstance(event) { instance ->
instance.timeoutAction?.openInventory() instance.timeoutAction?.openInventory()
}
} }
} }
} }
}
@EventHandler @EventHandler
fun onInventoryClick(event: InventoryClickEvent) { fun onInventoryClick(event: InventoryClickEvent) {
if (event.inventory !== chooseSpawnInventory && event.inventory !== chooseSpawnWithoutCorpseInventory) return if (event.inventory !== chooseSpawnInventory && event.inventory !== chooseSpawnWithoutCorpseInventory) return
handleWithInstance(event) { instance -> handleWithInstance(event) { instance ->
val timeoutAction = instance.timeoutAction!! val timeoutAction = instance.timeoutAction!!
val location = when (event.currentItem?.type) { val location = when (event.currentItem?.type) {
ON_SPAWN -> GameManager.world.spawnLocation ON_SPAWN -> GameManager.world.spawnLocation
ON_CORPSE -> timeoutAction.tttCorpse?.location ?: return@handleWithInstance ON_CORPSE -> timeoutAction.tttCorpse?.location ?: return@handleWithInstance
else -> return@handleWithInstance else -> return@handleWithInstance
}
timeoutAction.stop()
instance.tttPlayer.revive(location)
} }
timeoutAction.stop()
instance.tttPlayer.revive(location)
} }
}
@EventHandler @EventHandler
fun onTTTPlayerRevive(event: TTTPlayerReviveEvent) = handle(event) { it.timeoutAction?.stop() } fun onTTTPlayerRevive(event: TTTPlayerReviveEvent) = handle(event) { it.timeoutAction?.stop() }
})
} }
} }

View file

@ -57,31 +57,33 @@ object BaseballBat: TTTItem<BaseballBat.Instance>(
} }
} }
override val listener = object : TTTItemListener<Instance>(this) { init {
@EventHandler(ignoreCancelled = true) addListener(object : TTTItemListener<Instance>(this) {
fun onEntityDamageByEntity(event: EntityDamageByEntityEvent) = handle(event) { tttPlayer, _ -> @EventHandler(ignoreCancelled = true)
event.isCancelled = true fun onEntityDamageByEntity(event: EntityDamageByEntityEvent) = handle(event) { tttPlayer, _ ->
if (event.damage != 1.0) return@handle // Cooldown on weapon event.isCancelled = true
if (event.damage != 1.0) return@handle // Cooldown on weapon
val damagedPlayer = event.entity as Player val damagedPlayer = event.entity as Player
val distance = tttPlayer.player.location.distance(damagedPlayer.location) val distance = tttPlayer.player.location.distance(damagedPlayer.location)
if (distance < 2.5) { if (distance < 2.5) {
tttPlayer.removeItem(BaseballBat) tttPlayer.removeItem(BaseballBat)
GameManager.world.playSound( GameManager.world.playSound(
damagedPlayer.location, damagedPlayer.location,
Resourcepack.Sounds.Item.Weapon.BaseballBat.hit, Resourcepack.Sounds.Item.Weapon.BaseballBat.hit,
SoundCategory.PLAYERS, SoundCategory.PLAYERS,
1F, 1F,
1F 1F
) )
event.damage = 0.0 event.damage = 0.0
val direction = tttPlayer.player.location.direction val direction = tttPlayer.player.location.direction
damagedPlayer.velocity = Vector(direction.x * 5, 8.0, direction.z * 5) damagedPlayer.velocity = Vector(direction.x * 5, 8.0, direction.z * 5)
}
} }
} })
} }
} }

View file

@ -53,16 +53,18 @@ object Fireball: TTTItem<Fireball.Instance>(
val sendersByEntity = WeakHashMap<FireballEntity, TTTPlayer>() val sendersByEntity = WeakHashMap<FireballEntity, TTTPlayer>()
override val listener = object : TTTItemListener<Instance>(this) { init {
@EventHandler addListener(object : TTTItemListener<Instance>(this) {
fun onExplosionPrime(event: ExplosionPrimeEvent) { @EventHandler
val sender = sendersByEntity[event.entity] fun onExplosionPrime(event: ExplosionPrimeEvent) {
val sender = sendersByEntity[event.entity]
if (sender != null) { if (sender != null) {
event.isCancelled = true event.isCancelled = true
createKillExplosion(sender, event.entity.location, 2.5) createKillExplosion(sender, event.entity.location, 2.5)
}
} }
} })
} }
} }

View file

@ -48,42 +48,44 @@ object Knife: TTTItem<Knife.Instance>(
) { ) {
class Instance: TTTItem.Instance(Knife) class Instance: TTTItem.Instance(Knife)
override val listener = object : TTTItemListener<Instance>(this) { init {
@EventHandler(ignoreCancelled = true) addListener(object : TTTItemListener<Instance>(this) {
fun onEntityDamageByEntity(event: EntityDamageByEntityEvent) = handle(event) { damagerTTTPlayer, damagedTTTPlayer -> @EventHandler(ignoreCancelled = true)
event.isCancelled = true fun onEntityDamageByEntity(event: EntityDamageByEntityEvent) = handle(event) { damagerTTTPlayer, damagedTTTPlayer ->
event.isCancelled = true
if (event.damage == 1.0) { if (event.damage == 1.0) {
val distance = damagerTTTPlayer.player.location.distance(damagedTTTPlayer.player.location) val distance = damagerTTTPlayer.player.location.distance(damagedTTTPlayer.player.location)
if (distance <= 1.5) { if (distance <= 1.5) {
damagedTTTPlayer.damage( damagedTTTPlayer.damage(
1000.0, 1000.0,
DeathReason.Item(Knife), DeathReason.Item(Knife),
damagerTTTPlayer, damagerTTTPlayer,
false false
) )
GameManager.world.playSound( GameManager.world.playSound(
damagedTTTPlayer.player.location, damagedTTTPlayer.player.location,
Resourcepack.Sounds.Item.Weapon.Knife.hit, Resourcepack.Sounds.Item.Weapon.Knife.hit,
SoundCategory.PLAYERS, SoundCategory.PLAYERS,
1F, 1F,
1F 1F
) )
damagerTTTPlayer.player.playSound( damagerTTTPlayer.player.playSound(
damagerTTTPlayer.player.location, damagerTTTPlayer.player.location,
Sound.ENTITY_ITEM_BREAK, Sound.ENTITY_ITEM_BREAK,
SoundCategory.PLAYERS, SoundCategory.PLAYERS,
1F, 1F,
1F 1F
) )
damagerTTTPlayer.removeItem(Knife) damagerTTTPlayer.removeItem(Knife)
}
} }
} }
} })
} }
} }

View file

@ -10,5 +10,6 @@ sealed class DeathReason(val displayText: String) {
object DROWNED: DeathReason("Ertrunken") object DROWNED: DeathReason("Ertrunken")
object FIRE: DeathReason("Verbrannt") object FIRE: DeathReason("Verbrannt")
object POISON: DeathReason("Vergiftet") object POISON: DeathReason("Vergiftet")
object BEE: DeathReason("Zu Tode gestochen")
class Item(val item: TTTItem<*>): DeathReason("Getötet mit: ${item.templateItemStack.itemMeta!!.displayName}") class Item(val item: TTTItem<*>): DeathReason("Getötet mit: ${item.templateItemStack.itemMeta!!.displayName}")
} }