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,60 +3,82 @@ 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 )
abstract fun onStart( player: Player )
abstract fun onHit( attacker: Player, victim: Player, event: EntityDamageByEntityEvent )
abstract fun onDamaged( attacker: Player, victim: Player, event: EntityDamageByEntityEvent )
abstract fun onInteract( player: Player, event: PlayerInteractEvent )
abstract fun onMove( player: Player, event: PlayerMoveEvent )
open fun cleanup(
player: Player
) {
abilityContext.clearPlayerData( player )
} }
open fun onStart(player: Player) { protected fun hasCooldown(
player: Player,
key: String
): Boolean
{
return abilityContext.getRemainingCooldown( player, key ) > 0
} }
open fun onHit(attacker: Player, victim: Player, event: EntityDamageByEntityEvent) { protected fun startCooldown(
player: Player,
key: String,
seconds: Int
) {
abilityContext.cooldownManager.startCooldown( player, key, seconds )
} }
open fun onInteract(player: Player, event: PlayerInteractEvent) { protected fun getRemainingCooldown(
player: Player,
key: String
): Double
{
return abilityContext.getRemainingCooldown( player, key )
} }
open fun cleanup(player: Player) { protected fun getHits(
abilityContext.clearPlayerData(player) player: Player,
} key: String
): Int
protected fun hasCooldown(player: Player, key: String): Boolean { {
return abilityContext.getRemainingCooldown(player, key) > 0
}
protected fun startCooldown(player: Player, key: String, seconds: Int) {
abilityContext.cooldownManager.startCooldown(player, key, seconds)
}
protected fun getRemainingCooldown(player: Player, key: String): Double {
return abilityContext.getRemainingCooldown(player, key)
}
protected fun incrementHits(player: Player, key: String): Int {
return abilityContext.incrementHit(player, key)
}
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(
abilityContext.hitCounterManager.resetHits(player, key) player: Player,
key: String
) {
abilityContext.hitCounterManager.resetHits( player, key )
} }
protected fun abilityResult( protected fun abilityResult(
@@ -65,6 +87,28 @@ abstract class AbstractKit(
requiredHits: Int? = null, requiredHits: Int? = null,
cooldownSeconds: Int? = null cooldownSeconds: Int? = null
): 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,41 +1,73 @@
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()
kit.config = plugin.kitConfig.data.getConfigForKit(kit.id) {
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 )
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(
val kit = getKit(kitId) ?: return false player: Player,
kitId: String
): Boolean
{
val kit = getKit( kitId ) ?: return false
val previousKit = selectedKits[player.uniqueId] val previousKit = selectedKits[player.uniqueId]
previousKit?.cleanup(player) previousKit?.cleanup( player )
selectedKits[player.uniqueId] = kit selectedKits[player.uniqueId] = kit
try { try {
kit.onSelect(player) kit.onSelect( player )
} catch (e: Exception) { } catch (e: Exception) {
plugin.logger.severe("Error during onSelect for kit ${kit.id} and player ${player.name}: ${e.message}") plugin.logger.severe("Error during onSelect for kit ${kit.id} and player ${player.name}: ${e.message}")
e.printStackTrace() e.printStackTrace()
@@ -44,56 +76,99 @@ 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 {
kit.onStart(player) kit.onStart( player )
} catch (e: Exception) { } catch (e: Exception) {
plugin.logger.severe("Error during onStart for kit ${kit.id} and player ${player.name}: ${e.message}") plugin.logger.severe("Error during onStart for kit ${kit.id} and player ${player.name}: ${e.message}")
e.printStackTrace() e.printStackTrace()
} }
} }
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 {
kit.onHit(attacker, victim, event) kit.onHit( attacker, victim, event )
} catch (e: Exception) { } catch (e: Exception) {
plugin.logger.severe("Error during onHit for kit ${kit.id} and player ${attacker.name}: ${e.message}") plugin.logger.severe("Error during onHit for kit ${kit.id} and player ${attacker.name}: ${e.message}")
e.printStackTrace() e.printStackTrace()
} }
} }
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 {
kit.onInteract(player, event) kit.onInteract( player, event )
} catch (e: Exception) { } catch (e: Exception) {
plugin.logger.severe("Error during onInteract for kit ${kit.id} and player ${player.name}: ${e.message}") plugin.logger.severe("Error during onInteract for kit ${kit.id} and player ${player.name}: ${e.message}")
e.printStackTrace() e.printStackTrace()
} }
} }
fun clearPlayerSelection(player: Player) { fun triggerMove(
val kit = selectedKits.remove(player.uniqueId) player: Player,
kit?.cleanup(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 clearAll() { fun clearPlayerSelection(
player: Player
) {
val kit = selectedKits.remove( player.uniqueId )
kit?.cleanup( player )
}
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(
"§7Heavy and strong.",
"§7Deal extra damage after 3 hits.",
"§7Gain resistance when standing still."
),
icon = Material.ANVIL,
plugin = plugin,
abilityContext = abilityContext
) {
private val abilityKey = "anchor_ability" private lateinit var anvilItem: ItemStack
private val hitCounterKey = "anchor_hits"
override fun onSelect(player: Player) { private var anvilPlaced: Boolean = false
player.sendMessage("§aYou selected §6Anchor§a!")
private val extraDamage: Double = plugin.kitConfig.data.anchor[ "offensive extra damage" ]!!
private val radius = if ( playStyle == PlayStyle.DEFENSIVE ) 7.5 else 5.0
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()
player.inventory.setItem( 0, anvilItem )
} }
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
if ( !anvilPlaced )
return
if ( playStyle != PlayStyle.OFFENSIVE )
return
event.damage += extraDamage
} }
override fun onHit(attacker: Player, victim: Player, event: EntityDamageByEntityEvent) { override fun onDamaged(
val currentHits = incrementHits(attacker, hitCounterKey) attacker: Player,
victim: Player,
event: EntityDamageByEntityEvent
) {
if ( !gameManager.isRunning() )
return
val result = abilityResult( if ( !anvilPlaced )
player = attacker, return
abilityKey = abilityKey,
requiredHits = 3,
cooldownSeconds = 10
)
if (result.success) { victim.velocity.setX( 0.0 )
val extraDamage = config["offensive extra damage"] ?: 1.0 victim.velocity.setZ( 0.0 )
event.damage += extraDamage victim.world.playSound( victim.location, Sound.BLOCK_ANVIL_HIT, 3f, 3f )
}
attacker.sendMessage("§6⚓ Anchor Ability! §eDealt ${extraDamage} extra damage!") override fun onInteract(
victim.sendMessage("§c${attacker.name} used Anchor ability!") player: Player,
} else if (result.missingHits > 0) { event: PlayerInteractEvent
attacker.sendMessage("§e⚓ Hits: $currentHits/3") ) {
} else if (result.remainingCooldown > 0) { if ( !gameManager.isRunning() )
attacker.sendMessage("§c⚓ Cooldown: ${String.format("%.1f", result.remainingCooldown)}s") 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
} }
}
override fun onInteract(player: Player, event: PlayerInteractEvent) { if ( anvilPlaced )
if (event.action.isRightClick && event.item?.type == Material.ANVIL) { {
if (!hasCooldown(player, "anchor_resistance")) { plugin.chatManager.sendMessage( player, "kits.anchor.messages.alreadyActivated" )
player.addPotionEffect(PotionEffect(PotionEffectType.RESISTANCE, 100, 0)) return
player.sendMessage("§6⚓ Resistance activated!") }
startCooldown(player, "anchor_resistance", 15)
} else { val result = abilityContext.canUseAbility( player, "anchor-anvil", 15 )
val remaining = getRemainingCooldown(player, "anchor_resistance")
player.sendMessage("§c⚓ Resistance on cooldown: ${String.format("%.1f", remaining)}s") 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 )
} }
}
}