Fix Knife and add Defibrillator
This commit is contained in:
parent
adc51120c8
commit
ccd269e4da
10 changed files with 225 additions and 25 deletions
|
@ -6,7 +6,7 @@ object ResourcePack {
|
|||
object Items {
|
||||
val textureless = Material.WHITE_STAINED_GLASS_PANE
|
||||
val deathReason = Material.GRAY_STAINED_GLASS_PANE
|
||||
val questionMark = Material.IRON_BLOCK
|
||||
val questionMark = Material.GRASS_BLOCK
|
||||
val time = Material.CLOCK
|
||||
|
||||
// Roles
|
||||
|
@ -22,6 +22,7 @@ object ResourcePack {
|
|||
val teleporter = Material.SPRUCE_WOOD
|
||||
val martyrdomGrenade = Material.BIRCH_LOG
|
||||
val fakeCorpse = Material.SPRUCE_LOG
|
||||
val defibrillator = Material.IRON_INGOT
|
||||
|
||||
// Weapons
|
||||
val deagle = Material.IRON_HOE
|
||||
|
|
|
@ -5,6 +5,7 @@ import de.moritzruth.spigot_ttt.game.players.Role
|
|||
import de.moritzruth.spigot_ttt.plugin
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.EventPriority
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.golde.bukkit.corpsereborn.CorpseAPI.events.CorpseClickEvent
|
||||
|
@ -25,7 +26,7 @@ object CorpseListener: Listener {
|
|||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
|
||||
fun onCorpseClick(event: CorpseClickEvent) {
|
||||
// bug: always ClickType.UNKNOWN
|
||||
// if (event.clickType !== ClickType.RIGHT) return
|
||||
|
|
|
@ -12,7 +12,6 @@ import de.moritzruth.spigot_ttt.utils.applyMeta
|
|||
import de.moritzruth.spigot_ttt.utils.secondsToTicks
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.inventory.InventoryType
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.scheduler.BukkitTask
|
||||
|
@ -21,7 +20,7 @@ import org.golde.bukkit.corpsereborn.nms.Corpses
|
|||
import java.time.Instant
|
||||
|
||||
class TTTCorpse private constructor(
|
||||
private val player: Player,
|
||||
val tttPlayer: TTTPlayer,
|
||||
location: Location,
|
||||
private val role: Role,
|
||||
private val reason: DeathReason,
|
||||
|
@ -29,8 +28,8 @@ class TTTCorpse private constructor(
|
|||
) {
|
||||
var status = Status.UNIDENTIFIED; private set
|
||||
|
||||
val corpse: Corpses.CorpseData?
|
||||
val inventory = player.server.createInventory(null, InventoryType.HOPPER, "${role.chatColor}${player.displayName}")
|
||||
val corpse: Corpses.CorpseData
|
||||
val inventory = tttPlayer.player.server.createInventory(null, InventoryType.HOPPER, "${role.chatColor}${tttPlayer.player.displayName}")
|
||||
|
||||
val timestamp: Instant = Instant.now()
|
||||
private var fullMinutesSinceDeath = 0
|
||||
|
@ -44,7 +43,7 @@ class TTTCorpse private constructor(
|
|||
|
||||
setItems()
|
||||
|
||||
corpse = CorpseAPI.spawnCorpse(player, location)
|
||||
corpse = CorpseAPI.spawnCorpse(tttPlayer.player, location)
|
||||
|
||||
updateTimeListener = plugin.server.scheduler.runTaskTimer(plugin, fun() {
|
||||
fullMinutesSinceDeath += 1
|
||||
|
@ -91,8 +90,9 @@ class TTTCorpse private constructor(
|
|||
}
|
||||
|
||||
fun identify(tttPlayer: TTTPlayer, inspect: Boolean) {
|
||||
ensureNotDestroyed()
|
||||
if (status == Status.UNIDENTIFIED) {
|
||||
GameMessenger.corpseIdentified(tttPlayer.player.displayName, player.displayName, role)
|
||||
GameMessenger.corpseIdentified(tttPlayer.player.displayName, tttPlayer.player.displayName, role)
|
||||
|
||||
if (!inspect) {
|
||||
status = Status.IDENTIFIED
|
||||
|
@ -117,13 +117,25 @@ class TTTCorpse private constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun revive() {
|
||||
ensureNotDestroyed()
|
||||
tttPlayer.revive(corpse.trueLocation, credits)
|
||||
destroy()
|
||||
}
|
||||
|
||||
fun destroy() {
|
||||
if (corpse !== null) CorpseAPI.removeCorpse(corpse)
|
||||
status = Status.DESTROYED
|
||||
CorpseAPI.removeCorpse(corpse)
|
||||
updateTimeListener.cancel()
|
||||
inventory.viewers.toSet().forEach { it.closeInventory() }
|
||||
}
|
||||
|
||||
private fun ensureNotDestroyed() {
|
||||
if (status == Status.DESTROYED) throw IllegalStateException("This corpse was destroyed")
|
||||
}
|
||||
|
||||
enum class Status {
|
||||
DESTROYED,
|
||||
UNIDENTIFIED,
|
||||
IDENTIFIED,
|
||||
INSPECTED
|
||||
|
@ -136,7 +148,7 @@ class TTTCorpse private constructor(
|
|||
|
||||
fun spawn(tttPlayer: TTTPlayer, reason: DeathReason) {
|
||||
CorpseManager.add(TTTCorpse(
|
||||
tttPlayer.player,
|
||||
tttPlayer,
|
||||
tttPlayer.player.location,
|
||||
tttPlayer.role,
|
||||
reason,
|
||||
|
@ -144,9 +156,9 @@ class TTTCorpse private constructor(
|
|||
))
|
||||
}
|
||||
|
||||
fun spawnFake(role: Role, player: Player, location: Location) {
|
||||
fun spawnFake(role: Role, tttPlayer: TTTPlayer, location: Location) {
|
||||
CorpseManager.add(TTTCorpse(
|
||||
player,
|
||||
tttPlayer,
|
||||
location,
|
||||
role,
|
||||
DeathReason.Item(Pistol),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package de.moritzruth.spigot_ttt.game.players
|
||||
|
||||
import de.moritzruth.spigot_ttt.TTTPlugin
|
||||
import de.moritzruth.spigot_ttt.game.GameManager
|
||||
import de.moritzruth.spigot_ttt.game.GamePhase
|
||||
import de.moritzruth.spigot_ttt.game.corpses.TTTCorpse
|
||||
|
@ -13,6 +14,7 @@ import de.moritzruth.spigot_ttt.utils.secondsToTicks
|
|||
import de.moritzruth.spigot_ttt.utils.teleportPlayerToWorldSpawn
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.GameMode
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.potion.PotionEffect
|
||||
|
@ -89,11 +91,30 @@ class TTTPlayer(player: Player, role: Role) {
|
|||
credits = 0
|
||||
Shop.clear(this)
|
||||
|
||||
PlayerManager.letRemainingRoleGroupWin()
|
||||
|
||||
// PlayerManager.letRemainingRoleGroupWin()
|
||||
plugin.server.pluginManager.callEvent(TTTPlayerDeathEvent(this, player.location))
|
||||
}
|
||||
|
||||
fun revive(location: Location, credits: Int = 0) {
|
||||
if (alive) throw AlreadyLivingException()
|
||||
|
||||
alive = true
|
||||
this.credits = credits
|
||||
|
||||
player.health = 20.0
|
||||
player.teleport(location)
|
||||
|
||||
Shop.setItems(this)
|
||||
|
||||
player.sendMessage(TTTPlugin.prefix + "${ChatColor.GREEN}${ChatColor.BOLD}Du wurdest wiederbelebt")
|
||||
|
||||
plugin.server.scheduler.runTask(plugin, fun() {
|
||||
player.gameMode = GameMode.SURVIVAL
|
||||
})
|
||||
}
|
||||
|
||||
class AlreadyLivingException: Exception("The player already lives")
|
||||
|
||||
private fun adjustPlayer() {
|
||||
player.scoreboard = scoreboard.scoreboard
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ object ItemManager {
|
|||
BaseballBat,
|
||||
CloakingDevice, Rifle,
|
||||
EnderPearl, Radar, HealingPotion, Fireball,
|
||||
Teleporter, MartyrdomGrenade, FakeCorpse
|
||||
Teleporter, MartyrdomGrenade, FakeCorpse, Defibrillator
|
||||
)
|
||||
|
||||
val droppedItemStates = mutableMapOf<Int, IState>()
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
package de.moritzruth.spigot_ttt.items.impl
|
||||
|
||||
import com.connorlinfoot.actionbarapi.ActionBarAPI
|
||||
import de.moritzruth.spigot_ttt.ResourcePack
|
||||
import de.moritzruth.spigot_ttt.game.corpses.CorpseManager
|
||||
import de.moritzruth.spigot_ttt.game.players.*
|
||||
import de.moritzruth.spigot_ttt.items.Buyable
|
||||
import de.moritzruth.spigot_ttt.items.TTTItem
|
||||
import de.moritzruth.spigot_ttt.items.isRelevant
|
||||
import de.moritzruth.spigot_ttt.plugin
|
||||
import de.moritzruth.spigot_ttt.utils.*
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.boss.BarColor
|
||||
import org.bukkit.boss.BarStyle
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.scheduler.BukkitTask
|
||||
import org.golde.bukkit.corpsereborn.CorpseAPI.events.CorpseClickEvent
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
||||
object Defibrillator: TTTItem, Buyable {
|
||||
private const val REVIVE_DURATION = 10.0
|
||||
|
||||
override val type = TTTItem.Type.SPECIAL
|
||||
override val itemStack = ItemStack(ResourcePack.Items.defibrillator).applyMeta {
|
||||
setDisplayName("${ChatColor.RESET}${ChatColor.BOLD}Defibrillator")
|
||||
hideInfo()
|
||||
lore = listOf(
|
||||
"",
|
||||
"${ChatColor.GOLD}Belebe einen Spieler wieder"
|
||||
)
|
||||
}
|
||||
override val buyableBy = roles(Role.TRAITOR, Role.DETECTIVE, Role.JACKAL)
|
||||
override val price = 2
|
||||
override val buyLimit = 1
|
||||
|
||||
private val isc = InversedStateContainer(State::class)
|
||||
|
||||
override val listener = object : Listener {
|
||||
@EventHandler
|
||||
fun onPlayerInteract(event: PlayerInteractEvent) {
|
||||
if (event.isRelevant(Defibrillator)) event.isCancelled = true
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onCorpseClick(event: CorpseClickEvent) {
|
||||
val tttPlayer = PlayerManager.getTTTPlayer(event.clicker) ?: return
|
||||
if (tttPlayer.player.inventory.itemInMainHand.type != itemStack.type) return
|
||||
|
||||
val tttCorpse = CorpseManager.getTTTCorpse(event.corpse) ?: return
|
||||
event.isCancelled = true
|
||||
|
||||
val state = isc.getOrCreate(tttPlayer)
|
||||
state.bossBar.addPlayer(tttPlayer.player)
|
||||
|
||||
when(val action = state.action) {
|
||||
null -> state.action = Action.Reviving(tttPlayer, state)
|
||||
is Action.Reviving -> {
|
||||
action.cancelTask.cancel()
|
||||
action.cancelTask = action.createCancelTask()
|
||||
|
||||
val progress = action.duration / REVIVE_DURATION
|
||||
|
||||
if (progress >= 1) {
|
||||
try {
|
||||
tttCorpse.revive()
|
||||
|
||||
ActionBarAPI.sendActionBar(
|
||||
tttPlayer.player,
|
||||
"${ChatColor.BOLD}${tttCorpse.tttPlayer.player.displayName} " +
|
||||
"${ChatColor.GREEN}wurde wiederbelebt"
|
||||
)
|
||||
|
||||
action.cancelTask.cancel()
|
||||
tttPlayer.player.inventory.removeTTTItemNextTick(Defibrillator)
|
||||
state.reset(tttPlayer)
|
||||
isc.remove(tttPlayer)
|
||||
} catch(e: TTTPlayer.AlreadyLivingException) {
|
||||
// do not cancel the cancelTask
|
||||
}
|
||||
} else state.bossBar.progress = progress
|
||||
}
|
||||
is Action.Canceled -> noop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Action(val tttPlayer: TTTPlayer) {
|
||||
open fun reset() {}
|
||||
|
||||
class Reviving(tttPlayer: TTTPlayer, val state: State): Action(tttPlayer) {
|
||||
var cancelTask = createCancelTask()
|
||||
private val startedAt: Instant = Instant.now()
|
||||
val duration get() = Duration.between(startedAt, Instant.now()).toMillis().toDouble() / 1000
|
||||
|
||||
fun createCancelTask() = plugin.server.scheduler.runTaskLater(plugin, fun() {
|
||||
state.action = Canceled(tttPlayer)
|
||||
}, 10)
|
||||
|
||||
init {
|
||||
state.bossBar.color = BarColor.GREEN
|
||||
state.bossBar.addPlayer(tttPlayer.player)
|
||||
}
|
||||
|
||||
override fun reset() = cancelTask.cancel()
|
||||
}
|
||||
|
||||
class Canceled(tttPlayer: TTTPlayer): Action(tttPlayer) {
|
||||
private var switches: Int = 0
|
||||
private lateinit var task: BukkitTask
|
||||
|
||||
init {
|
||||
task = plugin.server.scheduler.runTaskTimer(plugin, fun() {
|
||||
val state = isc.get(tttPlayer) ?: return@runTaskTimer
|
||||
|
||||
if (switches == SWITCHES_COUNT) {
|
||||
task.cancel()
|
||||
state.action = null
|
||||
state.bossBar.removePlayer(tttPlayer.player)
|
||||
} else {
|
||||
state.bossBar.progress = 1.0
|
||||
state.bossBar.color = if (switches % 2 == 0) BarColor.RED else BarColor.WHITE
|
||||
switches += 1
|
||||
}
|
||||
}, 0, secondsToTicks(0.2).toLong())
|
||||
}
|
||||
|
||||
override fun reset() = task.cancel()
|
||||
|
||||
companion object {
|
||||
const val SWITCHES_COUNT = 6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class State: IState {
|
||||
var action: Action? = null
|
||||
var bossBar = plugin.server.createBossBar(
|
||||
"${ChatColor.BOLD}Defibrillator",
|
||||
BarColor.GREEN,
|
||||
BarStyle.SOLID
|
||||
)
|
||||
|
||||
override fun reset(tttPlayer: TTTPlayer) {
|
||||
bossBar.removePlayer(tttPlayer.player)
|
||||
action?.reset()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package de.moritzruth.spigot_ttt.items.impl
|
||||
|
||||
import com.connorlinfoot.actionbarapi.ActionBarAPI
|
||||
import de.moritzruth.spigot_ttt.ResourcePack
|
||||
import de.moritzruth.spigot_ttt.game.corpses.TTTCorpse
|
||||
import de.moritzruth.spigot_ttt.game.players.*
|
||||
|
@ -10,6 +11,7 @@ import de.moritzruth.spigot_ttt.plugin
|
|||
import de.moritzruth.spigot_ttt.utils.applyMeta
|
||||
import de.moritzruth.spigot_ttt.utils.hideInfo
|
||||
import de.moritzruth.spigot_ttt.utils.isRightClick
|
||||
import de.moritzruth.spigot_ttt.utils.removeTTTItem
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
|
@ -117,11 +119,16 @@ object FakeCorpse: TTTItem, Buyable {
|
|||
state.choosePlayerInventory -> {
|
||||
tttPlayer.player.closeInventory()
|
||||
|
||||
val player = plugin.server.getPlayer((item.itemMeta as SkullMeta).owningPlayer!!.uniqueId)!!
|
||||
TTTCorpse.spawnFake(state.chosenRole!!, player, tttPlayer.player.location)
|
||||
val corpsePlayer = plugin.server.getPlayer((item.itemMeta as SkullMeta).owningPlayer!!.uniqueId)!!
|
||||
val corpseTTTPlayer = PlayerManager.getTTTPlayer(corpsePlayer)
|
||||
|
||||
val itemIndex = tttPlayer.player.inventory.indexOfFirst { it.type == itemStack.type }
|
||||
tttPlayer.player.inventory.clear(itemIndex)
|
||||
if (corpseTTTPlayer == null) {
|
||||
ActionBarAPI.sendActionBar(tttPlayer.player, "${ChatColor.RED}Das hat nicht funktioniert")
|
||||
} else {
|
||||
TTTCorpse.spawnFake(state.chosenRole!!, corpseTTTPlayer, tttPlayer.player.location)
|
||||
|
||||
tttPlayer.player.inventory.removeTTTItem(FakeCorpse)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import de.moritzruth.spigot_ttt.utils.createKillExplosion
|
|||
import de.moritzruth.spigot_ttt.utils.hideInfo
|
||||
import de.moritzruth.spigot_ttt.utils.secondsToTicks
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.SoundCategory
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
|
@ -71,7 +70,7 @@ object MartyrdomGrenade: TTTItem, Buyable {
|
|||
state.explodeTask = plugin.server.scheduler.runTaskLater(plugin, fun() {
|
||||
GameManager.world.playSound(
|
||||
event.location,
|
||||
Sound.ENTITY_GENERIC_EXPLODE,
|
||||
ResourcePack.Sounds.grenadeExplode,
|
||||
SoundCategory.PLAYERS,
|
||||
1F,
|
||||
1F
|
||||
|
|
|
@ -6,10 +6,7 @@ import de.moritzruth.spigot_ttt.items.Buyable
|
|||
import de.moritzruth.spigot_ttt.items.TTTItem
|
||||
import de.moritzruth.spigot_ttt.items.isRelevant
|
||||
import de.moritzruth.spigot_ttt.items.weapons.LoreHelper
|
||||
import de.moritzruth.spigot_ttt.utils.applyMeta
|
||||
import de.moritzruth.spigot_ttt.utils.clearHeldItemSlot
|
||||
import de.moritzruth.spigot_ttt.utils.hideInfo
|
||||
import de.moritzruth.spigot_ttt.utils.isLeftClick
|
||||
import de.moritzruth.spigot_ttt.utils.*
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.SoundCategory
|
||||
|
@ -60,6 +57,9 @@ object Knife: TTTItem, Buyable {
|
|||
if (distance > 1.5) event.isCancelled = true else {
|
||||
damagedTTTPlayer.damageInfo = DamageInfo(damagerTTTPlayer, DeathReason.Item(Knife))
|
||||
event.damage = 1000.0
|
||||
|
||||
damagerTTTPlayer.player.playSound(damagerTTTPlayer.player.location, Sound.ENTITY_ITEM_BREAK, SoundCategory.PLAYERS, 1F, 1F)
|
||||
damagerTTTPlayer.player.inventory.removeTTTItemNextTick(Knife)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package de.moritzruth.spigot_ttt.utils
|
||||
|
||||
import de.moritzruth.spigot_ttt.items.TTTItem
|
||||
import de.moritzruth.spigot_ttt.plugin
|
||||
import org.bukkit.inventory.Inventory
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.PlayerInventory
|
||||
|
@ -8,6 +10,11 @@ fun Inventory.setAllToItem(indexes: Iterable<Int>, itemStack: ItemStack) {
|
|||
indexes.forEach { setItem(it, itemStack) }
|
||||
}
|
||||
|
||||
fun Inventory.removeTTTItem(tttItem: TTTItem) = clear(indexOfFirst { it.type == tttItem.itemStack.type })
|
||||
fun Inventory.removeTTTItemNextTick(tttItem: TTTItem) = plugin.server.scheduler.runTask(plugin, fun() {
|
||||
removeTTTItem(tttItem)
|
||||
})
|
||||
|
||||
fun PlayerInventory.clearHeldItemSlot() = clear(heldItemSlot)
|
||||
|
||||
val PlayerInventory.hotbarContents get() = this.contents.slice(0..8) as List<ItemStack?>
|
||||
|
|
Reference in a new issue