Update kit management & anchor kit

This commit is contained in:
TDSTOS
2025-12-09 01:01:00 +01:00
parent a3b521940c
commit 728b7534ac
6 changed files with 395 additions and 121 deletions

View File

@@ -5,11 +5,17 @@ import club.mcscrims.core.config.ConfigFormat
import club.mcscrims.core.config.ConfigLoader import club.mcscrims.core.config.ConfigLoader
import club.mcscrims.core.database.DatabaseConfig import club.mcscrims.core.database.DatabaseConfig
import club.mcscrims.core.database.mongodb.MongoManager import club.mcscrims.core.database.mongodb.MongoManager
import club.mcscrims.speedhg.ability.AbilityContext
import club.mcscrims.speedhg.ability.AbilityHitListener
import club.mcscrims.speedhg.ability.CooldownManager
import club.mcscrims.speedhg.ability.HitCounterManager
import club.mcscrims.speedhg.config.KitConfig import club.mcscrims.speedhg.config.KitConfig
import club.mcscrims.speedhg.config.MessageConfig import club.mcscrims.speedhg.config.MessageConfig
import club.mcscrims.speedhg.config.PluginConfig import club.mcscrims.speedhg.config.PluginConfig
import club.mcscrims.speedhg.database.StatsRepository import club.mcscrims.speedhg.database.StatsRepository
import club.mcscrims.speedhg.game.GameManager import club.mcscrims.speedhg.game.GameManager
import club.mcscrims.speedhg.kit.KitListener
import club.mcscrims.speedhg.kit.KitManager
import club.mcscrims.speedhg.listener.GameStateListener import club.mcscrims.speedhg.listener.GameStateListener
import club.mcscrims.speedhg.listener.LunarClientListener import club.mcscrims.speedhg.listener.LunarClientListener
import club.mcscrims.speedhg.world.WorldManager import club.mcscrims.speedhg.world.WorldManager
@@ -20,13 +26,22 @@ import club.mcscrims.spigot.scheduler.SchedulerManager
import club.mcscrims.spigot.util.WorldEditUtils import club.mcscrims.spigot.util.WorldEditUtils
import com.mongodb.client.model.Indexes import com.mongodb.client.model.Indexes
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import net.luckperms.api.LuckPerms import net.luckperms.api.LuckPerms
import org.bukkit.plugin.java.JavaPlugin import org.bukkit.plugin.java.JavaPlugin
class SpeedHG : JavaPlugin() { class SpeedHG : JavaPlugin() {
companion object { companion object {
internal lateinit var instance: SpeedHG internal lateinit var instance: SpeedHG
fun Component.content(): String
{
return LegacyComponentSerializer.legacySection().serialize( this )
}
} }
private lateinit var configLoader: ConfigLoader private lateinit var configLoader: ConfigLoader
@@ -47,6 +62,9 @@ class SpeedHG : JavaPlugin() {
internal lateinit var gameManager: GameManager internal lateinit var gameManager: GameManager
internal lateinit var worldManager: WorldManager internal lateinit var worldManager: WorldManager
internal lateinit var abilityContext: AbilityContext
internal lateinit var kitManager: KitManager
internal lateinit var worldEditUtils: WorldEditUtils internal lateinit var worldEditUtils: WorldEditUtils
internal lateinit var luckPerms: LuckPerms internal lateinit var luckPerms: LuckPerms
@@ -84,12 +102,20 @@ class SpeedHG : JavaPlugin() {
gameManager = GameManager( this ) gameManager = GameManager( this )
gameManager.initialize() gameManager.initialize()
val cooldownManager = CooldownManager()
val hitCounterManager = HitCounterManager()
abilityContext = AbilityContext( cooldownManager, hitCounterManager )
kitManager = KitManager( this )
kitManager.initialize()
setupLuckPerms() setupLuckPerms()
registerListener() registerListener()
} }
override fun onDisable() override fun onDisable()
{ {
kitManager.clearAll()
mongoManager.shutdown() mongoManager.shutdown()
networkManager.shutdown() networkManager.shutdown()
} }
@@ -97,6 +123,8 @@ class SpeedHG : JavaPlugin() {
private fun registerListener() private fun registerListener()
{ {
server.pluginManager.registerEvents(GameStateListener( this, gameManager ), this ) server.pluginManager.registerEvents(GameStateListener( this, gameManager ), this )
server.pluginManager.registerEvents(KitListener( this, kitManager ), this )
server.pluginManager.registerEvents(AbilityHitListener( this, abilityContext ), this )
LunarClientListener( this ) LunarClientListener( this )
} }

View File

@@ -39,12 +39,11 @@ class ImmunityState(
player.inventory.setItem( 8, ItemStack( Material.COMPASS )) player.inventory.setItem( 8, ItemStack( Material.COMPASS ))
TODO( "Give kits and perks" ) plugin.kitManager.startKitForPlayer( player )
TODO( "Give perks" )
} }
broadcast( "gameStates.immunity.warnings.butterfly" ) broadcast( "gameStates.immunity.warnings.butterfly" )
TODO( "register kits & perks" )
} }
override fun onTick() override fun onTick()

View File

@@ -3,59 +3,81 @@ package club.mcscrims.speedhg.kit
import club.mcscrims.speedhg.SpeedHG import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.ability.AbilityContext import club.mcscrims.speedhg.ability.AbilityContext
import club.mcscrims.speedhg.ability.AbilityResult import club.mcscrims.speedhg.ability.AbilityResult
import club.mcscrims.speedhg.game.GameManager
import net.kyori.adventure.text.Component
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.EntityDamageByEntityEvent
import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.event.player.PlayerMoveEvent
abstract class AbstractKit( abstract class AbstractKit(
val id: String, val id: String,
val displayName: String, val displayName: Component,
val description: List<String>, val description: List<String>,
val icon: Material, val icon: Material,
val playStyle: PlayStyle,
protected val plugin: SpeedHG, protected val plugin: SpeedHG,
protected val abilityContext: AbilityContext protected val abilityContext: AbilityContext,
protected val gameManager: GameManager
) { ) {
lateinit var config: Map<String, Double> lateinit var config: Map<String, Double>
open fun onSelect(player: Player) { abstract fun onSelect( player: Player )
}
open fun onStart(player: Player) { abstract fun onStart( player: Player )
}
open fun onHit(attacker: Player, victim: Player, event: EntityDamageByEntityEvent) { abstract fun onHit( attacker: Player, victim: Player, event: EntityDamageByEntityEvent )
}
open fun onInteract(player: Player, event: PlayerInteractEvent) { abstract fun onDamaged( attacker: Player, victim: Player, event: EntityDamageByEntityEvent )
}
open fun cleanup(player: Player) { abstract fun onInteract( player: Player, event: PlayerInteractEvent )
abstract fun onMove( player: Player, event: PlayerMoveEvent )
open fun cleanup(
player: Player
) {
abilityContext.clearPlayerData( player ) abilityContext.clearPlayerData( player )
} }
protected fun hasCooldown(player: Player, key: String): Boolean { protected fun hasCooldown(
player: Player,
key: String
): Boolean
{
return abilityContext.getRemainingCooldown( player, key ) > 0 return abilityContext.getRemainingCooldown( player, key ) > 0
} }
protected fun startCooldown(player: Player, key: String, seconds: Int) { protected fun startCooldown(
player: Player,
key: String,
seconds: Int
) {
abilityContext.cooldownManager.startCooldown( player, key, seconds ) abilityContext.cooldownManager.startCooldown( player, key, seconds )
} }
protected fun getRemainingCooldown(player: Player, key: String): Double { protected fun getRemainingCooldown(
player: Player,
key: String
): Double
{
return abilityContext.getRemainingCooldown( player, key ) return abilityContext.getRemainingCooldown( player, key )
} }
protected fun incrementHits(player: Player, key: String): Int { protected fun getHits(
return abilityContext.incrementHit(player, key) player: Player,
} key: String
): Int
protected fun getHits(player: Player, key: String): Int { {
return abilityContext.getHits(player, key) return abilityContext.getHits(player, key)
} }
protected fun resetHits(player: Player, key: String) { protected fun resetHits(
player: Player,
key: String
) {
abilityContext.hitCounterManager.resetHits( player, key ) abilityContext.hitCounterManager.resetHits( player, key )
} }
@@ -67,4 +89,26 @@ abstract class AbstractKit(
): AbilityResult { ): AbilityResult {
return abilityContext.canUseAbility( player, abilityKey, requiredHits, cooldownSeconds ) return abilityContext.canUseAbility( player, abilityKey, requiredHits, cooldownSeconds )
} }
}
enum class PlayStyle {
OFFENSIVE, DEFENSIVE, NULL
}
enum class KitMetaData {
IN_GLADIATOR,
GLADIATOR_BLOCK,
IS_ANVIL,
IS_BLACK_PANTHER,
BP_EXTRA_DAMAGE,
VOODOO_HOLD,
ICEMAGE_SNOWBALL,
ICEMAGE_SPEED;
fun getKey(): String
{
return name
}
} }

View File

@@ -1,29 +1,75 @@
package club.mcscrims.speedhg.kit package club.mcscrims.speedhg.kit
import club.mcscrims.speedhg.SpeedHG
import org.bukkit.Material
import org.bukkit.Sound
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.block.BlockBreakEvent
import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.EntityDamageByEntityEvent
import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.event.player.PlayerMoveEvent
class KitListener(private val kitManager: KitManager) : Listener { class KitListener(
private val plugin: SpeedHG,
private val kitManager: KitManager
) : Listener {
@EventHandler @EventHandler
fun onEntityDamage(event: EntityDamageByEntityEvent) { fun onDamage(
event: EntityDamageByEntityEvent
) {
val attacker = event.damager as? Player ?: return val attacker = event.damager as? Player ?: return
val victim = event.entity as? Player ?: return val victim = event.entity as? Player ?: return
if (kitManager.getSelectedKit(attacker) != null) { if (kitManager.getSelectedKit( attacker ) != null )
kitManager.triggerHit( attacker, victim, event ) kitManager.triggerHit( attacker, victim, event )
}
if (kitManager.getSelectedKit( victim ) != null )
kitManager.triggerDamaged( victim, attacker, event )
} }
@EventHandler @EventHandler
fun onPlayerInteract(event: PlayerInteractEvent) { fun onPlayerInteract(
event: PlayerInteractEvent
) {
val player = event.player val player = event.player
if (kitManager.getSelectedKit(player) != null) { if (kitManager.getSelectedKit( player ) != null )
kitManager.triggerInteract( player, event ) kitManager.triggerInteract( player, event )
} }
@EventHandler
fun onPlayerMove(
event: PlayerMoveEvent
) {
val player = event.player
if (kitManager.getSelectedKit( player ) != null )
kitManager.triggerMove( player, event )
} }
@EventHandler
fun onAnvilBreak(
event: BlockBreakEvent
) {
if ( !plugin.gameManager.isRunning() )
return
val block = event.block
if ( block.type != Material.ANVIL ||
!block.hasMetadata( KitMetaData.IS_ANVIL.getKey() ))
return
event.isCancelled = true
block.type = Material.AIR
block.removeMetadata( KitMetaData.IS_ANVIL.getKey(), plugin )
block.world.playSound( block.location, Sound.ENTITY_IRON_GOLEM_DEATH, 3f, 3f )
plugin.chatManager.broadcast( "kits.anchor.messages.broken" )
}
} }

View File

@@ -1,32 +1,64 @@
package club.mcscrims.speedhg.kit package club.mcscrims.speedhg.kit
import club.mcscrims.speedhg.SpeedHG import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.kit.impl.AnchorKit
import net.kyori.adventure.text.Component
import org.bukkit.Material
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.EntityDamageByEntityEvent
import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.event.player.PlayerMoveEvent
import java.util.UUID import java.util.UUID
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
class KitManager(private val plugin: SpeedHG) { class KitManager(
private val plugin: SpeedHG
) {
private val kits = ConcurrentHashMap<String, AbstractKit>() private val kits = ConcurrentHashMap<String, AbstractKit>()
private val selectedKits = ConcurrentHashMap<UUID, AbstractKit>() private val selectedKits = ConcurrentHashMap<UUID, AbstractKit>()
fun registerKit(kit: AbstractKit) { fun initialize()
{
registerKit(
kitClass = AnchorKit::class.java as Class<AbstractKit>,
id = "anchor",
displayName = plugin.chatFormatter.format( "kits.anchor.displayName" ),
description = emptyList(),
icon = Material.ANVIL
)
}
fun registerKit(
kitClass: Class<AbstractKit>,
id: String,
displayName: Component,
description: List<String>,
icon: Material
) {
val kit = kitClass.getDeclaredConstructor().newInstance( id, displayName, description, icon, PlayStyle.NULL, plugin, plugin.abilityContext, plugin.gameManager )
kit.config = plugin.kitConfig.data.getConfigForKit( kit.id ) kit.config = plugin.kitConfig.data.getConfigForKit( kit.id )
kits[kit.id.lowercase()] = kit kits[kit.id.lowercase()] = kit
plugin.logger.info("Registered kit: ${kit.displayName} (${kit.id})") plugin.logger.info("Registered kit: ${kit.displayName} (${kit.id})")
} }
fun getKit(id: String): AbstractKit? { fun getKit(
id: String
): AbstractKit?
{
return kits[id.lowercase()] return kits[id.lowercase()]
} }
fun getAllKits(): Collection<AbstractKit> { fun getAllKits(): Collection<AbstractKit>
{
return kits.values return kits.values
} }
fun selectKit(player: Player, kitId: String): Boolean { fun selectKit(
player: Player,
kitId: String
): Boolean
{
val kit = getKit( kitId ) ?: return false val kit = getKit( kitId ) ?: return false
val previousKit = selectedKits[player.uniqueId] val previousKit = selectedKits[player.uniqueId]
@@ -44,11 +76,16 @@ class KitManager(private val plugin: SpeedHG) {
return true return true
} }
fun getSelectedKit(player: Player): AbstractKit? { fun getSelectedKit(
player: Player
): AbstractKit?
{
return selectedKits[player.uniqueId] return selectedKits[player.uniqueId]
} }
fun startKitForPlayer(player: Player) { fun startKitForPlayer(
player: Player
) {
val kit = selectedKits[player.uniqueId] ?: return val kit = selectedKits[player.uniqueId] ?: return
try { try {
@@ -59,7 +96,11 @@ class KitManager(private val plugin: SpeedHG) {
} }
} }
fun triggerHit(attacker: Player, victim: Player, event: EntityDamageByEntityEvent) { fun triggerHit(
attacker: Player,
victim: Player,
event: EntityDamageByEntityEvent
) {
val kit = selectedKits[attacker.uniqueId] ?: return val kit = selectedKits[attacker.uniqueId] ?: return
try { try {
@@ -70,7 +111,25 @@ class KitManager(private val plugin: SpeedHG) {
} }
} }
fun triggerInteract(player: Player, event: PlayerInteractEvent) { fun triggerDamaged(
attacker: Player,
victim: Player,
event: EntityDamageByEntityEvent
) {
val kit = selectedKits[victim.uniqueId] ?: return
try {
kit.onDamaged( attacker, victim, event )
} catch (e: Exception) {
plugin.logger.severe("Error during onDamaged for kit ${kit.id} and player ${victim.name}: ${e.message}")
e.printStackTrace()
}
}
fun triggerInteract(
player: Player,
event: PlayerInteractEvent
) {
val kit = selectedKits[player.uniqueId] ?: return val kit = selectedKits[player.uniqueId] ?: return
try { try {
@@ -81,19 +140,35 @@ class KitManager(private val plugin: SpeedHG) {
} }
} }
fun clearPlayerSelection(player: Player) { fun triggerMove(
player: Player,
event: PlayerMoveEvent
) {
val kit = selectedKits[player.uniqueId] ?: return
try {
kit.onMove( player, event )
} catch (e: Exception) {
plugin.logger.severe("Error during onMove for kit ${kit.id} and player ${player.name}: ${e.message}")
e.printStackTrace()
}
}
fun clearPlayerSelection(
player: Player
) {
val kit = selectedKits.remove( player.uniqueId ) val kit = selectedKits.remove( player.uniqueId )
kit?.cleanup( player ) kit?.cleanup( player )
} }
fun clearAll() { fun clearAll()
{
selectedKits.values.forEach { kit -> selectedKits.values.forEach { kit ->
plugin.server.onlinePlayers.forEach { player -> plugin.server.onlinePlayers.forEach { player ->
if (selectedKits[player.uniqueId] == kit) { if ( selectedKits[player.uniqueId] == kit ) kit.cleanup( player )
kit.cleanup(player)
}
} }
} }
selectedKits.clear() selectedKits.clear()
} }
} }

View File

@@ -1,85 +1,167 @@
package club.mcscrims.speedhg.kit.impl package club.mcscrims.speedhg.kit.impl
import club.mcscrims.speedhg.SpeedHG import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.SpeedHG.Companion.content
import club.mcscrims.speedhg.ability.AbilityContext import club.mcscrims.speedhg.ability.AbilityContext
import club.mcscrims.speedhg.game.GameManager
import club.mcscrims.speedhg.kit.AbstractKit import club.mcscrims.speedhg.kit.AbstractKit
import club.mcscrims.speedhg.kit.KitMetaData
import club.mcscrims.speedhg.kit.PlayStyle
import club.mcscrims.spigot.item.ItemBuilder
import net.kyori.adventure.text.Component
import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.Sound
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.block.Action
import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.EntityDamageByEntityEvent
import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.event.player.PlayerMoveEvent
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.potion.PotionEffect import org.bukkit.metadata.FixedMetadataValue
import org.bukkit.potion.PotionEffectType
class AnchorKit( class AnchorKit(
id: String,
displayName: Component,
description: List<String>,
icon: Material,
playStyle: PlayStyle,
plugin: SpeedHG, plugin: SpeedHG,
abilityContext: AbilityContext abilityContext: AbilityContext,
) : AbstractKit( gameManager: GameManager
id = "anchor", ) : AbstractKit( id, displayName, description, icon, playStyle, plugin, abilityContext, gameManager ) {
displayName = "Anchor",
description = listOf( private lateinit var anvilItem: ItemStack
"§7Heavy and strong.",
"§7Deal extra damage after 3 hits.", private var anvilPlaced: Boolean = false
"§7Gain resistance when standing still."
), private val extraDamage: Double = plugin.kitConfig.data.anchor[ "offensive extra damage" ]!!
icon = Material.ANVIL,
plugin = plugin, private val radius = if ( playStyle == PlayStyle.DEFENSIVE ) 7.5 else 5.0
abilityContext = abilityContext private lateinit var anvilLoc: Location
override fun onSelect( player: Player ) {}
override fun onStart(
player: Player
) { ) {
anvilItem = ItemBuilder( plugin, Material.ANVIL )
.name(plugin.chatFormatter.format( "kits.anchor.items.anvil.${playStyle.name.lowercase()}" ).content())
.unbreakable( true )
.hideAttributes()
.build()
private val abilityKey = "anchor_ability" player.inventory.setItem( 0, anvilItem )
private val hitCounterKey = "anchor_hits"
override fun onSelect(player: Player) {
player.sendMessage("§aYou selected §6Anchor§a!")
} }
override fun onStart(player: Player) { override fun onHit(
player.inventory.addItem(ItemStack(Material.STONE_SWORD)) attacker: Player,
player.inventory.helmet = ItemStack(Material.IRON_HELMET) victim: Player,
player.inventory.chestplate = ItemStack(Material.IRON_CHESTPLATE) event: EntityDamageByEntityEvent
player.inventory.leggings = ItemStack(Material.IRON_LEGGINGS) ) {
player.inventory.boots = ItemStack(Material.IRON_BOOTS) if ( !gameManager.isRunning() )
} return
override fun onHit(attacker: Player, victim: Player, event: EntityDamageByEntityEvent) { if ( !anvilPlaced )
val currentHits = incrementHits(attacker, hitCounterKey) return
val result = abilityResult( if ( playStyle != PlayStyle.OFFENSIVE )
player = attacker, return
abilityKey = abilityKey,
requiredHits = 3,
cooldownSeconds = 10
)
if (result.success) {
val extraDamage = config["offensive extra damage"] ?: 1.0
event.damage += extraDamage event.damage += extraDamage
attacker.sendMessage("§6⚓ Anchor Ability! §eDealt ${extraDamage} extra damage!")
victim.sendMessage("§c${attacker.name} used Anchor ability!")
} else if (result.missingHits > 0) {
attacker.sendMessage("§e⚓ Hits: $currentHits/3")
} else if (result.remainingCooldown > 0) {
attacker.sendMessage("§c⚓ Cooldown: ${String.format("%.1f", result.remainingCooldown)}s")
}
} }
override fun onInteract(player: Player, event: PlayerInteractEvent) { override fun onDamaged(
if (event.action.isRightClick && event.item?.type == Material.ANVIL) { attacker: Player,
if (!hasCooldown(player, "anchor_resistance")) { victim: Player,
player.addPotionEffect(PotionEffect(PotionEffectType.RESISTANCE, 100, 0)) event: EntityDamageByEntityEvent
player.sendMessage("§6⚓ Resistance activated!") ) {
startCooldown(player, "anchor_resistance", 15) if ( !gameManager.isRunning() )
} else { return
val remaining = getRemainingCooldown(player, "anchor_resistance")
player.sendMessage("§c⚓ Resistance on cooldown: ${String.format("%.1f", remaining)}s") if ( !anvilPlaced )
return
victim.velocity.setX( 0.0 )
victim.velocity.setZ( 0.0 )
victim.world.playSound( victim.location, Sound.BLOCK_ANVIL_HIT, 3f, 3f )
}
override fun onInteract(
player: Player,
event: PlayerInteractEvent
) {
if ( !gameManager.isRunning() )
return
val action = event.action
if ( action != Action.RIGHT_CLICK_AIR &&
action != Action.RIGHT_CLICK_BLOCK )
return
val item = event.item ?: return
if ( item != anvilItem )
return
event.isCancelled = true
val eyeLocation = player.eyeLocation
if (eyeLocation.distance( player.location ) > radius )
{
plugin.chatManager.sendMessage( player, "kits.anchor.messages.tooFarAway" )
return
}
if ( anvilPlaced )
{
plugin.chatManager.sendMessage( player, "kits.anchor.messages.alreadyActivated" )
return
}
val result = abilityContext.canUseAbility( player, "anchor-anvil", 15 )
if ( result.missingHits > 0 )
{
plugin.chatManager.sendMessage( player, "kits.missingHits", "{hits]" to result.missingHits.toString() )
return
}
anvilLoc = eyeLocation.toBlockLocation()
anvilLoc.add( 0.0, 1.0, 0.0 )
anvilLoc.block.type = Material.ANVIL
anvilLoc.block.setMetadata( KitMetaData.IS_ANVIL.getKey(), FixedMetadataValue( plugin, true ))
anvilPlaced = true
plugin.schedulerManager.runLater( 20 * 30L ) {
if ( anvilPlaced )
{
anvilPlaced = false
anvilLoc.block.type = Material.AIR
anvilLoc.block.removeMetadata( KitMetaData.IS_ANVIL.getKey(), plugin )
} }
} }
} }
override fun cleanup(player: Player) { override fun onMove(
super.cleanup(player) player: Player,
player.sendMessage("§7Anchor kit cleaned up.") event: PlayerMoveEvent
) {
if ( !gameManager.isRunning() )
return
if ( !anvilPlaced )
return
if (player.location.distance( anvilLoc ) <= radius )
return
player.teleport( player.location )
player.playSound( player, Sound.BLOCK_NOTE_BLOCK_BASS, 1f, 1f )
} }
} }