Fix Second Chance
This commit is contained in:
parent
87d0e6c43c
commit
4f7058d892
7 changed files with 108 additions and 67 deletions
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ open class TTTItem<InstanceT: TTTItem.Instance>(
|
|||
val instanceType: KClass<out InstanceT>,
|
||||
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<InstanceT: TTTItem.Instance>(
|
|||
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<InstanceT: TTTItem.Instance>(
|
|||
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 {
|
||||
|
|
|
@ -37,11 +37,7 @@ open class TTTItemListener<InstanceT: TTTItem.Instance>(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) {
|
||||
|
|
|
@ -40,18 +40,23 @@ object SecondChance: TTTItem<SecondChance.Instance>(
|
|||
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<SecondChance.Instance>(
|
|||
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<SecondChance.Instance>(
|
|||
"${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<SecondChance.Instance>(
|
|||
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<SecondChance.Instance>(
|
|||
@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<SecondChance.Instance>(
|
|||
}
|
||||
|
||||
timeoutAction.stop()
|
||||
instance.carrier!!.revive(location)
|
||||
instance.tttPlayer.revive(location)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue