Update kit management & anchor kit
This commit is contained in:
@@ -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 )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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" )
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 )
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user