1
0
Fork 0

Use events instead of reset functions for states

This commit is contained in:
Moritz Ruth 2020-06-08 20:37:41 +02:00
parent 44b376f5e4
commit 3aa2bdc082
No known key found for this signature in database
GPG key ID: AFD57E23E753841B
10 changed files with 75 additions and 40 deletions

View file

@ -0,0 +1,18 @@
package de.moritzruth.spigot_ttt.game
import org.bukkit.event.Event
import org.bukkit.event.HandlerList
class GameEndEvent(val aborted: Boolean): Event() {
override fun getHandlers(): HandlerList {
@Suppress("RedundantCompanionReference") // false positive
return Companion.handlers
}
companion object {
private val handlers = HandlerList()
@JvmStatic
fun getHandlerList() = handlers
}
}

View file

@ -42,9 +42,10 @@ object GameManager {
}
Timers.startOverPhaseTimer(plugin.config.getInt("duration.over", 10)) {
plugin.server.pluginManager.callEvent(GameEndEvent(false))
phase = null
resetWorld()
PlayerManager.resetAfterGame()
}
@ -80,6 +81,7 @@ object GameManager {
fun abortGame(broadcast: Boolean = false) {
if (phase === null) throw IllegalStateException("The game is not running")
plugin.server.pluginManager.callEvent(GameEndEvent(true))
phase = null
Timers.cancelCurrentTask()
resetWorld()

View file

@ -4,9 +4,7 @@ import com.google.common.collect.MutableClassToInstanceMap
import kotlin.reflect.KClass
import kotlin.reflect.KVisibility
interface IState {
fun reset(tttPlayer: TTTPlayer) {}
}
interface IState
class StateContainer(private val tttPlayer: TTTPlayer) {
private val instances = MutableClassToInstanceMap.create<IState>()
@ -22,6 +20,8 @@ class StateContainer(private val tttPlayer: TTTPlayer) {
fun <T: IState> get(stateClass: KClass<T>): T? = instances.getInstance(stateClass.java)
fun <T: IState> has(stateClass: KClass<T>): Boolean = instances.containsKey(stateClass.java)
fun <T: IState> put(stateClass: KClass<out T>, value: T) {
if (instances.containsKey(stateClass.java))
throw IllegalStateException("There is already a state instance in this container")
@ -30,15 +30,16 @@ class StateContainer(private val tttPlayer: TTTPlayer) {
}
fun <T: IState> remove(stateClass: KClass<T>) = instances.remove(stateClass.java)
fun resetAndClear() {
instances.values.forEach { it.reset(tttPlayer) }
instances.clear()
}
}
class InversedStateContainer<T: IState>(private val stateClass: KClass<T>) {
fun getOrCreate(tttPlayer: TTTPlayer) = tttPlayer.stateContainer.getOrCreate(stateClass)
fun get(tttPlayer: TTTPlayer) = tttPlayer.stateContainer.get(stateClass)
fun remove(tttPlayer: TTTPlayer) = tttPlayer.stateContainer.remove(stateClass)
val tttPlayers get() = PlayerManager.tttPlayers.filter { it.stateContainer.has(stateClass) }
fun forEachState(fn: (T, TTTPlayer) -> Unit) {
tttPlayers.forEach { it.stateContainer.get(stateClass)?.run { fn(this, it) } }
}
}

View file

@ -88,8 +88,8 @@ class TTTPlayer(player: Player, role: Role) {
alive = false
TTTCorpse.spawn(this, reason)
player.inventory.clear()
credits = 0
Shop.clear(this)
// PlayerManager.letRemainingRoleGroupWin()
plugin.server.pluginManager.callEvent(TTTPlayerDeathEvent(this, player.location))
@ -177,8 +177,6 @@ class TTTPlayer(player: Player, role: Role) {
}
}
stateContainer.resetAndClear()
invisible = false
player.gameMode = GameMode.SURVIVAL

View file

@ -3,6 +3,7 @@ package de.moritzruth.spigot_ttt.items
import com.comphenix.protocol.events.PacketListener
import de.moritzruth.spigot_ttt.game.players.Role
import de.moritzruth.spigot_ttt.game.players.TTTPlayer
import org.bukkit.ChatColor
import org.bukkit.entity.Item
import org.bukkit.event.Listener
import org.bukkit.inventory.ItemStack
@ -22,8 +23,12 @@ interface Buyable {
val buyableBy: EnumSet<Role>
val price: Int
val buyLimit: Int?
fun onBuy(tttPlayer: TTTPlayer) {}
}
val PASSIVE = "${ChatColor.RESET}${ChatColor.RED}(Passiv)"
// Marker
interface Spawning

View file

@ -3,6 +3,7 @@ package de.moritzruth.spigot_ttt.items.impl
import com.connorlinfoot.actionbarapi.ActionBarAPI
import de.moritzruth.spigot_ttt.ResourcePack
import de.moritzruth.spigot_ttt.TTTItemListener
import de.moritzruth.spigot_ttt.game.GameEndEvent
import de.moritzruth.spigot_ttt.game.corpses.CorpseManager
import de.moritzruth.spigot_ttt.game.players.*
import de.moritzruth.spigot_ttt.items.Buyable
@ -79,6 +80,9 @@ object Defibrillator: TTTItem, Buyable {
is Action.Canceled -> noop()
}
}
@EventHandler
fun onGameEnd(event: GameEndEvent) = isc.forEachState { state, tttPlayer -> state.reset(tttPlayer) }
}
sealed class Action(val tttPlayer: TTTPlayer) {
@ -137,7 +141,7 @@ object Defibrillator: TTTItem, Buyable {
BarStyle.SOLID
)
override fun reset(tttPlayer: TTTPlayer) {
fun reset(tttPlayer: TTTPlayer) {
bossBar.removePlayer(tttPlayer.player)
action?.reset()
}

View file

@ -2,9 +2,11 @@ package de.moritzruth.spigot_ttt.items.impl
import de.moritzruth.spigot_ttt.ResourcePack
import de.moritzruth.spigot_ttt.TTTItemListener
import de.moritzruth.spigot_ttt.game.GameEndEvent
import de.moritzruth.spigot_ttt.game.GameManager
import de.moritzruth.spigot_ttt.game.players.*
import de.moritzruth.spigot_ttt.items.Buyable
import de.moritzruth.spigot_ttt.items.PASSIVE
import de.moritzruth.spigot_ttt.items.TTTItem
import de.moritzruth.spigot_ttt.plugin
import de.moritzruth.spigot_ttt.utils.applyMeta
@ -14,17 +16,14 @@ import de.moritzruth.spigot_ttt.utils.secondsToTicks
import org.bukkit.ChatColor
import org.bukkit.SoundCategory
import org.bukkit.event.EventHandler
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.scheduler.BukkitTask
object MartyrdomGrenade: TTTItem, Buyable {
val DISPLAY_NAME = "${ChatColor.DARK_PURPLE}${ChatColor.BOLD}Märtyriumsgranate"
override val type = TTTItem.Type.SPECIAL
override val itemStack = ItemStack(ResourcePack.Items.martyrdomGrenade).applyMeta {
hideInfo()
setDisplayName(DISPLAY_NAME)
setDisplayName("${ChatColor.DARK_PURPLE}${ChatColor.BOLD}Märtyriumsgranate $PASSIVE")
lore = listOf(
"",
@ -37,20 +36,11 @@ object MartyrdomGrenade: TTTItem, Buyable {
override val price = 1
val isc = InversedStateContainer(State::class)
override fun onBuy(tttPlayer: TTTPlayer) {
isc.getOrCreate(tttPlayer)
}
override val listener = object : TTTItemListener(this, true) {
override fun onRightClick(data: Data<PlayerInteractEvent>) {
val state = isc.getOrCreate(data.tttPlayer)
state.enabled = !state.enabled
data.event.item!!.applyMeta {
if (state.enabled) {
setDisplayName(DISPLAY_NAME + "${ChatColor.RESET} - ${ChatColor.GREEN}Aktiviert")
} else {
setDisplayName(DISPLAY_NAME)
}
}
}
@EventHandler
fun onTTTPlayerDeath(event: TTTPlayerDeathEvent) {
val state = isc.get(event.tttPlayer) ?: return
@ -67,15 +57,15 @@ object MartyrdomGrenade: TTTItem, Buyable {
createKillExplosion(event.tttPlayer, event.location, 2.5)
}, secondsToTicks(3).toLong())
}
@EventHandler
fun onGameEnd(event: GameEndEvent) = isc.forEachState { state, _ ->
state.explodeTask?.cancel()
state.explodeTask = null
}
}
class State: IState {
var enabled = false
var explodeTask: BukkitTask? = null
override fun reset(tttPlayer: TTTPlayer) {
explodeTask?.cancel()
explodeTask = null
}
}
}

View file

@ -6,6 +6,7 @@ import com.comphenix.protocol.events.PacketAdapter
import com.comphenix.protocol.events.PacketEvent
import de.moritzruth.spigot_ttt.ResourcePack
import de.moritzruth.spigot_ttt.TTTItemListener
import de.moritzruth.spigot_ttt.game.GameEndEvent
import de.moritzruth.spigot_ttt.game.players.*
import de.moritzruth.spigot_ttt.items.Buyable
import de.moritzruth.spigot_ttt.items.TTTItem
@ -16,6 +17,7 @@ import org.bukkit.ChatColor
import org.bukkit.boss.BarColor
import org.bukkit.boss.BarStyle
import org.bukkit.boss.BossBar
import org.bukkit.event.EventHandler
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.scheduler.BukkitTask
@ -107,6 +109,12 @@ object Radar: TTTItem, Buyable {
override fun onRightClick(data: Data<PlayerInteractEvent>) {
use(data.tttPlayer, data.event.item!!)
}
@EventHandler
fun onTTTPlayerDeath(event: TTTPlayerDeathEvent) = isc.get(event.tttPlayer)?.reset(event.tttPlayer)
@EventHandler
fun onGameEnd(event: GameEndEvent) = isc.forEachState { state, tttPlayer -> state.reset(tttPlayer) }
}
override val packetListener = object : PacketAdapter(plugin, PacketType.Play.Server.ENTITY_METADATA) {
@ -136,7 +144,7 @@ object Radar: TTTItem, Buyable {
lateinit var timestamp: Instant
lateinit var bossBar: BossBar
override fun reset(tttPlayer: TTTPlayer) {
fun reset(tttPlayer: TTTPlayer) {
setActive(tttPlayer, false)
task?.cancel()

View file

@ -1,6 +1,7 @@
package de.moritzruth.spigot_ttt.items.weapons.guns
import de.moritzruth.spigot_ttt.TTTItemListener
import de.moritzruth.spigot_ttt.game.GameEndEvent
import de.moritzruth.spigot_ttt.game.GameManager
import de.moritzruth.spigot_ttt.game.GamePhase
import de.moritzruth.spigot_ttt.game.players.*
@ -15,6 +16,7 @@ import de.moritzruth.spigot_ttt.utils.startItemDamageProgress
import org.bukkit.*
import org.bukkit.entity.Item
import org.bukkit.entity.Player
import org.bukkit.event.EventHandler
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack
@ -194,6 +196,12 @@ abstract class Gun(
shoot(data.tttPlayer, data.event.item!!)
} catch (e: ActionInProgressError) {}
}
@EventHandler
fun onTTTPlayerDeath(event: TTTPlayerDeathEvent) = isc.get(event.tttPlayer)?.reset()
@EventHandler
fun onGameEnd(event: GameEndEvent) = isc.forEachState { state, _ -> state.reset() }
}
class ActionInProgressError: RuntimeException("The gun has an ongoing action which may not be canceled")
@ -202,9 +210,7 @@ abstract class Gun(
var currentAction: Action? = null
var remainingShots = magazineSize
override fun reset(tttPlayer: TTTPlayer) {
currentAction?.task?.cancel()
}
fun reset() { currentAction?.task?.cancel() }
}
sealed class Action(var itemStack: ItemStack) {

View file

@ -47,6 +47,9 @@ object ShopListener: Listener {
tttPlayer.addItem(tttItem)
tttPlayer.boughtItems.add(tttItem)
tttPlayer.credits -= tttItem.price
tttItem.onBuy(tttPlayer)
Shop.setItems(tttPlayer)
} catch (e: TTTPlayer.AlreadyHasItemException) {
ActionBarAPI.sendActionBar(tttPlayer.player, "${ChatColor.RED}Du hast dieses Item bereits")