Remove legacy modules, add language & scoreboard
Large refactor removing many legacy subsystems (abilities, kit system, database repos, recraft, world manager, extensive config classes, lunar/luckperms integrations and various listeners/commands). Introduces a lightweight LanguageManager, AntiRunningManager, ScoreboardManager, ConnectListener and a SoupListener; simplifies the main SpeedHG plugin to initialize these components and register the connection listener. Build changes: update Gradle wrapper to 8.10, remove paperweight and several external dependencies, add fr.mrmicky:fastboard and simplify shadowJar/build task configuration. Adds default language resource (languages/en_US.yml) and updates plugin/config resources. Purpose: simplify and decouple the plugin, reduce dependency surface and prepare for a leaner, modular rewrite.
This commit is contained in:
@@ -1,116 +0,0 @@
|
||||
package club.mcscrims.speedhg.kit
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import club.mcscrims.speedhg.ability.AbilityContext
|
||||
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.entity.Player
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
abstract class AbstractKit(
|
||||
val id: String,
|
||||
val displayName: Component,
|
||||
val description: List<Component>,
|
||||
val icon: Material,
|
||||
val playStyle: PlayStyle,
|
||||
protected val plugin: SpeedHG,
|
||||
protected val abilityContext: AbilityContext,
|
||||
protected val gameManager: GameManager
|
||||
) {
|
||||
|
||||
lateinit var config: Map<String, Double>
|
||||
val items = mutableListOf<ItemStack>()
|
||||
|
||||
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 )
|
||||
}
|
||||
|
||||
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 getHits(
|
||||
player: Player,
|
||||
key: String
|
||||
): Int
|
||||
{
|
||||
return abilityContext.getHits(player, key)
|
||||
}
|
||||
|
||||
protected fun resetHits(
|
||||
player: Player,
|
||||
key: String
|
||||
) {
|
||||
abilityContext.hitCounterManager.resetHits( player, key )
|
||||
}
|
||||
|
||||
protected fun abilityResult(
|
||||
player: Player,
|
||||
abilityKey: String,
|
||||
requiredHits: Int? = null,
|
||||
cooldownSeconds: Int? = null
|
||||
): AbilityResult {
|
||||
return abilityContext.canUseAbility( player, abilityKey, requiredHits, cooldownSeconds )
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum class PlayStyle {
|
||||
OFFENSIVE, DEFENSIVE
|
||||
}
|
||||
|
||||
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,20 +0,0 @@
|
||||
package club.mcscrims.speedhg.kit
|
||||
|
||||
import org.bukkit.inventory.Inventory
|
||||
import org.bukkit.inventory.InventoryHolder
|
||||
|
||||
class KitInventoryHolder(
|
||||
val page: Int
|
||||
) : InventoryHolder {
|
||||
|
||||
private lateinit var inventory: Inventory
|
||||
|
||||
override fun getInventory(): Inventory = inventory
|
||||
|
||||
fun setInventory(
|
||||
inventory: Inventory
|
||||
) {
|
||||
this.inventory = inventory
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package club.mcscrims.speedhg.kit
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import club.mcscrims.speedhg.SpeedHG.Companion.content
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.inventory.InventoryDragEvent
|
||||
|
||||
class KitInventoryListener(
|
||||
private val plugin: SpeedHG,
|
||||
private val kitManager: KitManager,
|
||||
private val kitInventoryManager: KitInventoryManager
|
||||
) : Listener {
|
||||
|
||||
@EventHandler
|
||||
fun onInventoryClick(
|
||||
event: InventoryClickEvent
|
||||
) {
|
||||
val holder = event.inventory.holder
|
||||
|
||||
if ( holder !is KitInventoryHolder )
|
||||
return
|
||||
|
||||
event.isCancelled = true
|
||||
|
||||
val player = event.whoClicked as? Player ?: return
|
||||
val clickedItem = event.currentItem ?: return
|
||||
|
||||
if ( clickedItem.type == Material.AIR )
|
||||
return
|
||||
|
||||
when( event.rawSlot )
|
||||
{
|
||||
45 -> {
|
||||
if ( holder.page > 1 )
|
||||
{
|
||||
player.playSound( player.location, Sound.UI_BUTTON_CLICK, 1f, 1f )
|
||||
kitInventoryManager.openKitInventory( player, holder.page - 1 )
|
||||
}
|
||||
}
|
||||
49 -> {
|
||||
player.playSound( player.location, Sound.UI_BUTTON_CLICK, 1f, 0.8f )
|
||||
player.closeInventory()
|
||||
}
|
||||
53 -> {
|
||||
val totalKits = kitManager.getAllKits().size
|
||||
val totalPages = ( totalKits + 27 ) / 28
|
||||
if ( holder.page < totalPages )
|
||||
{
|
||||
player.playSound( player.location, Sound.UI_BUTTON_CLICK, 1f, 1f )
|
||||
kitInventoryManager.openKitInventory( player, holder.page + 1 )
|
||||
}
|
||||
}
|
||||
in 10..43 -> {
|
||||
val allKits = kitManager.getAllKits().toList()
|
||||
val startIndex = ( holder.page - 1 ) * 28
|
||||
val endIndex = ( startIndex + 28 ).coerceAtMost( allKits.size )
|
||||
val kitsOnPage = allKits.subList( startIndex, endIndex )
|
||||
|
||||
val kitSlots = listOf(
|
||||
10, 11, 12, 13, 14, 15, 16,
|
||||
19, 20, 21, 22, 23, 24, 25,
|
||||
28, 29, 30, 31, 32, 33, 34,
|
||||
37, 38, 39, 40, 41, 42, 43
|
||||
)
|
||||
|
||||
val slotIndex = kitSlots.indexOf( event.rawSlot )
|
||||
if ( slotIndex != -1 && slotIndex < kitsOnPage.size )
|
||||
{
|
||||
val selectedKit = kitsOnPage[slotIndex]
|
||||
|
||||
if (kitManager.selectKit( player, selectedKit.id ))
|
||||
{
|
||||
player.playSound( player.location, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 1.2f )
|
||||
plugin.chatManager.sendMessage(
|
||||
player,
|
||||
"kits.selected",
|
||||
"{kit}" to selectedKit.displayName.content()
|
||||
)
|
||||
kitInventoryManager.openKitInventory( player, holder.page )
|
||||
} else {
|
||||
player.playSound( player.location, Sound.ENTITY_VILLAGER_NO, 1f, 1f )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onInventoryDrag(
|
||||
event: InventoryDragEvent
|
||||
) {
|
||||
val holder = event.inventory.holder
|
||||
|
||||
if ( holder is KitInventoryHolder )
|
||||
event.isCancelled = true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
package club.mcscrims.speedhg.kit
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.kyori.adventure.text.format.NamedTextColor
|
||||
import net.kyori.adventure.text.format.TextDecoration
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemFlag
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class KitInventoryManager(
|
||||
private val plugin: SpeedHG,
|
||||
private val kitManager: KitManager
|
||||
) {
|
||||
|
||||
private val kitsPerPage = 28
|
||||
private val rows = 6
|
||||
|
||||
fun openKitInventory(
|
||||
player: Player,
|
||||
page: Int = 1
|
||||
) {
|
||||
val allKits = kitManager.getAllKits().toList()
|
||||
val totalPages = ( allKits.size + kitsPerPage - 1 ) / kitsPerPage
|
||||
val validPage = page.coerceIn( 1, totalPages.coerceAtLeast( 1 ))
|
||||
|
||||
val holder = KitInventoryHolder( validPage )
|
||||
val title = Component.text("Kits - Page $validPage/$totalPages")
|
||||
.color( NamedTextColor.DARK_PURPLE )
|
||||
.decoration( TextDecoration.BOLD, true )
|
||||
|
||||
val inventory = Bukkit.createInventory( holder, rows * 9, title )
|
||||
holder.setInventory( inventory )
|
||||
|
||||
fillBorder( inventory )
|
||||
fillKits( inventory, allKits, validPage, player )
|
||||
fillNavigationItems( inventory, validPage, totalPages )
|
||||
|
||||
player.openInventory( inventory )
|
||||
}
|
||||
|
||||
private fun fillBorder(
|
||||
inventory: org.bukkit.inventory.Inventory
|
||||
) {
|
||||
val borderItem = createBorderItem()
|
||||
|
||||
for ( i in 0..8 )
|
||||
inventory.setItem( i, borderItem )
|
||||
|
||||
for ( i in 45..53 )
|
||||
inventory.setItem( i, borderItem )
|
||||
}
|
||||
|
||||
private fun fillKits(
|
||||
inventory: org.bukkit.inventory.Inventory,
|
||||
allKits: List<AbstractKit>,
|
||||
page: Int,
|
||||
player: Player
|
||||
) {
|
||||
val startIndex = ( page - 1 ) * kitsPerPage
|
||||
val endIndex = ( startIndex + kitsPerPage ).coerceAtMost( allKits.size )
|
||||
val kitsOnPage = allKits.subList( startIndex, endIndex )
|
||||
|
||||
val selectedKit = kitManager.getSelectedKit( player )
|
||||
|
||||
val kitSlots = listOf(
|
||||
10, 11, 12, 13, 14, 15, 16,
|
||||
19, 20, 21, 22, 23, 24, 25,
|
||||
28, 29, 30, 31, 32, 33, 34,
|
||||
37, 38, 39, 40, 41, 42, 43
|
||||
)
|
||||
|
||||
kitsOnPage.forEachIndexed { index, kit ->
|
||||
if ( index < kitSlots.size )
|
||||
{
|
||||
val isSelected = selectedKit?.id == kit.id
|
||||
val kitItem = createKitItem( kit, isSelected, player )
|
||||
inventory.setItem(kitSlots[ index ], kitItem )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillNavigationItems(
|
||||
inventory: org.bukkit.inventory.Inventory,
|
||||
page: Int,
|
||||
totalPages: Int
|
||||
) {
|
||||
if ( page > 1 )
|
||||
inventory.setItem( 45, createPreviousPageItem() )
|
||||
|
||||
inventory.setItem( 49, createCloseItem() )
|
||||
|
||||
if ( page < totalPages )
|
||||
inventory.setItem( 53, createNextPageItem() )
|
||||
}
|
||||
|
||||
private fun createBorderItem(): ItemStack
|
||||
{
|
||||
val item = ItemStack( Material.GRAY_STAINED_GLASS_PANE )
|
||||
val meta = item.itemMeta
|
||||
meta.displayName(Component.text( " " ))
|
||||
item.itemMeta = meta
|
||||
return item
|
||||
}
|
||||
|
||||
private fun createKitItem(
|
||||
kit: AbstractKit,
|
||||
isSelected: Boolean,
|
||||
player: Player
|
||||
): ItemStack
|
||||
{
|
||||
val item = ItemStack( kit.icon )
|
||||
val meta = item.itemMeta
|
||||
|
||||
meta.displayName(kit.displayName.decoration( TextDecoration.ITALIC, false ))
|
||||
|
||||
val lore = mutableListOf<Component>()
|
||||
|
||||
if ( isSelected ) {
|
||||
lore.add(
|
||||
Component.text("✔ Currently Selected")
|
||||
.color( NamedTextColor.GREEN )
|
||||
.decoration( TextDecoration.ITALIC, false )
|
||||
)
|
||||
} else {
|
||||
lore.add(
|
||||
Component.text("Click to select")
|
||||
.color( NamedTextColor.YELLOW )
|
||||
.decoration( TextDecoration.ITALIC, false )
|
||||
)
|
||||
}
|
||||
|
||||
lore.add( Component.empty() )
|
||||
|
||||
kit.description.forEach { line ->
|
||||
lore.add(
|
||||
line.color( NamedTextColor.GRAY )
|
||||
.decoration( TextDecoration.ITALIC, false )
|
||||
)
|
||||
}
|
||||
|
||||
if (canUseKit( player, kit )) {
|
||||
if ( isSelected )
|
||||
{
|
||||
meta.addEnchant( Enchantment.UNBREAKING, 1, true )
|
||||
meta.addItemFlags( ItemFlag.HIDE_ENCHANTS )
|
||||
}
|
||||
} else {
|
||||
lore.add( Component.empty() )
|
||||
lore.add(
|
||||
Component.text("⚠ Locked")
|
||||
.color( NamedTextColor.RED )
|
||||
.decoration( TextDecoration.ITALIC, false )
|
||||
.decoration( TextDecoration.BOLD, true )
|
||||
)
|
||||
}
|
||||
|
||||
meta.lore( lore )
|
||||
meta.addItemFlags( ItemFlag.HIDE_ATTRIBUTES )
|
||||
item.itemMeta = meta
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
private fun createPreviousPageItem(): ItemStack
|
||||
{
|
||||
val item = ItemStack( Material.ARROW )
|
||||
val meta = item.itemMeta
|
||||
meta.displayName(
|
||||
Component.text("← Previous Page")
|
||||
.color( NamedTextColor.YELLOW )
|
||||
.decoration( TextDecoration.ITALIC, false )
|
||||
)
|
||||
item.itemMeta = meta
|
||||
return item
|
||||
}
|
||||
|
||||
private fun createNextPageItem(): ItemStack
|
||||
{
|
||||
val item = ItemStack( Material.ARROW )
|
||||
val meta = item.itemMeta
|
||||
meta.displayName(
|
||||
Component.text("Next Page →")
|
||||
.color( NamedTextColor.YELLOW )
|
||||
.decoration( TextDecoration.ITALIC, false )
|
||||
)
|
||||
item.itemMeta = meta
|
||||
return item
|
||||
}
|
||||
|
||||
private fun createCloseItem(): ItemStack
|
||||
{
|
||||
val item = ItemStack( Material.BARRIER )
|
||||
val meta = item.itemMeta
|
||||
meta.displayName(
|
||||
Component.text("Close")
|
||||
.color( NamedTextColor.RED )
|
||||
.decoration( TextDecoration.ITALIC, false )
|
||||
)
|
||||
item.itemMeta = meta
|
||||
return item
|
||||
}
|
||||
|
||||
private fun canUseKit(
|
||||
player: Player,
|
||||
kit: AbstractKit
|
||||
): Boolean
|
||||
{
|
||||
val unlockedKits = mutableListOf<String>()
|
||||
|
||||
runBlocking {
|
||||
val kitPlayer = plugin.playerRepository.findByUuid( player.uniqueId )
|
||||
if ( kitPlayer != null ) unlockedKits.addAll( kitPlayer.unlockedKits )
|
||||
}
|
||||
|
||||
return unlockedKits.contains( kit.id )
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
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.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.block.BlockBreakEvent
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
|
||||
class KitListener(
|
||||
private val plugin: SpeedHG,
|
||||
private val kitManager: KitManager
|
||||
) : Listener {
|
||||
|
||||
@EventHandler
|
||||
fun onDamage(
|
||||
event: EntityDamageByEntityEvent
|
||||
) {
|
||||
val attacker = event.damager as? Player ?: return
|
||||
val victim = event.entity as? Player ?: return
|
||||
|
||||
if (kitManager.getSelectedKit( attacker ) != null )
|
||||
kitManager.triggerHit( attacker, victim, event )
|
||||
|
||||
if (kitManager.getSelectedKit( victim ) != null )
|
||||
kitManager.triggerDamaged( victim, attacker, event )
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onPlayerInteract(
|
||||
event: PlayerInteractEvent
|
||||
) {
|
||||
val player = event.player
|
||||
|
||||
if (kitManager.getSelectedKit( player ) != null )
|
||||
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,224 +0,0 @@
|
||||
package club.mcscrims.speedhg.kit
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import club.mcscrims.speedhg.ability.AbilityContext
|
||||
import club.mcscrims.speedhg.game.GameManager
|
||||
import club.mcscrims.speedhg.kit.impl.AnchorKit
|
||||
import club.mcscrims.speedhg.kit.impl.ArmorerKit
|
||||
import club.mcscrims.speedhg.kit.impl.BlackPantherKit
|
||||
import club.mcscrims.speedhg.kit.impl.BlitzcrankKit
|
||||
import net.kyori.adventure.text.Component
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class KitManager(
|
||||
private val plugin: SpeedHG
|
||||
) {
|
||||
|
||||
private val kits = ConcurrentHashMap<String, AbstractKit>()
|
||||
private val selectedKits = ConcurrentHashMap<UUID, AbstractKit>()
|
||||
|
||||
fun initialize()
|
||||
{
|
||||
registerKit(
|
||||
kitClass = AnchorKit::class.java,
|
||||
id = "anchor",
|
||||
displayName = plugin.chatFormatter.format( "kits.anchor.displayName" ),
|
||||
description = plugin.chatFormatter.formatList( "kits.anchor.lore" ),
|
||||
icon = Material.ANVIL
|
||||
)
|
||||
|
||||
registerKit(
|
||||
kitClass = ArmorerKit::class.java,
|
||||
id = "armorer",
|
||||
displayName = plugin.chatFormatter.format( "kits.armorer.displayName" ),
|
||||
description = plugin.chatFormatter.formatList( "kits.armorer.lore" ),
|
||||
icon = Material.IRON_CHESTPLATE
|
||||
)
|
||||
|
||||
registerKit(
|
||||
kitClass = BlackPantherKit::class.java,
|
||||
id = "blackpanther",
|
||||
displayName = plugin.chatFormatter.format( "kits.blackpanther.displayName" ),
|
||||
description = plugin.chatFormatter.formatList( "kits.blackpanther.lore" ),
|
||||
icon = Material.DRAGON_EGG
|
||||
)
|
||||
|
||||
registerKit(
|
||||
kitClass = BlitzcrankKit::class.java,
|
||||
id = "blitzcrank",
|
||||
displayName = plugin.chatFormatter.format( "kits.blitzcrank.displayName" ),
|
||||
description = plugin.chatFormatter.formatList( "kits.blitzcrank.lore" ),
|
||||
icon = Material.FISHING_ROD
|
||||
)
|
||||
}
|
||||
|
||||
fun registerKit(
|
||||
kitClass: Class<out AbstractKit>,
|
||||
id: String,
|
||||
displayName: Component,
|
||||
description: List<Component>,
|
||||
icon: Material
|
||||
) {
|
||||
val constructor = kitClass.getDeclaredConstructor(
|
||||
String::class.java,
|
||||
Component::class.java,
|
||||
List::class.java,
|
||||
Material::class.java,
|
||||
PlayStyle::class.java,
|
||||
SpeedHG::class.java,
|
||||
AbilityContext::class.java,
|
||||
GameManager::class.java
|
||||
)
|
||||
|
||||
val kit = constructor.newInstance(
|
||||
id,
|
||||
displayName,
|
||||
description,
|
||||
icon,
|
||||
PlayStyle.DEFENSIVE,
|
||||
plugin,
|
||||
plugin.abilityContext,
|
||||
plugin.gameManager
|
||||
)
|
||||
|
||||
kit.config = plugin.kitConfig.data.getConfigForKit( kit.id )
|
||||
kits[kit.id.lowercase()] = kit
|
||||
plugin.logger.info("Registered kit: ${kit.displayName} (${kit.id})")
|
||||
}
|
||||
|
||||
fun getKit(
|
||||
id: String
|
||||
): AbstractKit?
|
||||
{
|
||||
return kits[id.lowercase()]
|
||||
}
|
||||
|
||||
fun getAllKits(): Collection<AbstractKit>
|
||||
{
|
||||
return kits.values
|
||||
}
|
||||
|
||||
fun selectKit(
|
||||
player: Player,
|
||||
kitId: String
|
||||
): Boolean
|
||||
{
|
||||
val kit = getKit( kitId ) ?: return false
|
||||
|
||||
val previousKit = selectedKits[player.uniqueId]
|
||||
previousKit?.cleanup( player )
|
||||
|
||||
selectedKits[player.uniqueId] = kit
|
||||
|
||||
try {
|
||||
kit.onSelect( player )
|
||||
} catch (e: Exception) {
|
||||
plugin.logger.severe("Error during onSelect for kit ${kit.id} and player ${player.name}: ${e.message}")
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun getSelectedKit(
|
||||
player: Player
|
||||
): AbstractKit?
|
||||
{
|
||||
return selectedKits[player.uniqueId]
|
||||
}
|
||||
|
||||
fun startKitForPlayer(
|
||||
player: Player
|
||||
) {
|
||||
val kit = selectedKits[player.uniqueId] ?: return
|
||||
|
||||
try {
|
||||
kit.onStart( player )
|
||||
} catch (e: Exception) {
|
||||
plugin.logger.severe("Error during onStart for kit ${kit.id} and player ${player.name}: ${e.message}")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun triggerHit(
|
||||
attacker: Player,
|
||||
victim: Player,
|
||||
event: EntityDamageByEntityEvent
|
||||
) {
|
||||
val kit = selectedKits[attacker.uniqueId] ?: return
|
||||
|
||||
try {
|
||||
kit.onHit( attacker, victim, event )
|
||||
} catch (e: Exception) {
|
||||
plugin.logger.severe("Error during onHit for kit ${kit.id} and player ${attacker.name}: ${e.message}")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
try {
|
||||
kit.onInteract( player, event )
|
||||
} catch (e: Exception) {
|
||||
plugin.logger.severe("Error during onInteract for kit ${kit.id} and player ${player.name}: ${e.message}")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
kit?.cleanup( player )
|
||||
}
|
||||
|
||||
fun clearAll()
|
||||
{
|
||||
selectedKits.values.forEach { kit ->
|
||||
plugin.server.onlinePlayers.forEach { player ->
|
||||
if ( selectedKits[player.uniqueId] == kit ) kit.cleanup( player )
|
||||
}
|
||||
}
|
||||
selectedKits.clear()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
package club.mcscrims.speedhg.kit.impl
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import club.mcscrims.speedhg.SpeedHG.Companion.content
|
||||
import club.mcscrims.speedhg.ability.AbilityContext
|
||||
import club.mcscrims.speedhg.game.GameManager
|
||||
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.Sound
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.block.Action
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.metadata.FixedMetadataValue
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class AnchorKit(
|
||||
id: String,
|
||||
displayName: Component,
|
||||
description: List<Component>,
|
||||
icon: Material,
|
||||
playStyle: PlayStyle,
|
||||
plugin: SpeedHG,
|
||||
abilityContext: AbilityContext,
|
||||
gameManager: GameManager
|
||||
) : AbstractKit( id, displayName, description, icon, playStyle, plugin, abilityContext, gameManager ) {
|
||||
|
||||
private lateinit var anvilItem: ItemStack
|
||||
|
||||
private val extraDamage: Double = plugin.kitConfig.data.anchor[ "offensive extra damage" ]!!
|
||||
|
||||
private val radius = if ( playStyle == PlayStyle.DEFENSIVE ) 7.5 else 5.0
|
||||
private val anvilList = ConcurrentHashMap<UUID, Location>()
|
||||
|
||||
override fun onSelect( player: Player ) {}
|
||||
|
||||
override fun onStart(
|
||||
player: Player
|
||||
) {
|
||||
anvilItem = ItemBuilder( plugin, Material.ANVIL )
|
||||
.name(plugin.messageConfig.data.getKitItemNames( "anchor", "anvil" )!![ playStyle.name.lowercase() ]!!)
|
||||
.unbreakable( true )
|
||||
.hideAttributes()
|
||||
.build()
|
||||
|
||||
items.add( anvilItem )
|
||||
player.inventory.setItem( 0, anvilItem )
|
||||
}
|
||||
|
||||
override fun onHit(
|
||||
attacker: Player,
|
||||
victim: Player,
|
||||
event: EntityDamageByEntityEvent
|
||||
) {
|
||||
if ( !gameManager.isRunning() )
|
||||
return
|
||||
|
||||
if (!anvilList.contains( attacker.uniqueId ))
|
||||
return
|
||||
|
||||
if ( playStyle != PlayStyle.OFFENSIVE )
|
||||
return
|
||||
|
||||
event.damage += extraDamage
|
||||
}
|
||||
|
||||
override fun onDamaged(
|
||||
attacker: Player,
|
||||
victim: Player,
|
||||
event: EntityDamageByEntityEvent
|
||||
) {
|
||||
if ( !gameManager.isRunning() )
|
||||
return
|
||||
|
||||
if (!anvilList.contains( attacker.uniqueId ))
|
||||
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 (anvilList.contains( player.uniqueId ))
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
val 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 ))
|
||||
|
||||
anvilList[ player.uniqueId ]= anvilLoc
|
||||
|
||||
plugin.schedulerManager.runLater( 20 * 30L ) {
|
||||
if (anvilList.contains( player.uniqueId ))
|
||||
{
|
||||
anvilList.remove( player.uniqueId )
|
||||
anvilLoc.block.type = Material.AIR
|
||||
anvilLoc.block.removeMetadata( KitMetaData.IS_ANVIL.getKey(), plugin )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMove(
|
||||
player: Player,
|
||||
event: PlayerMoveEvent
|
||||
) {
|
||||
if ( !gameManager.isRunning() )
|
||||
return
|
||||
|
||||
val anvilLoc = anvilList[ player.uniqueId ]
|
||||
?: return
|
||||
|
||||
if (player.location.distance( anvilLoc ) <= radius )
|
||||
return
|
||||
|
||||
player.teleport( player.location )
|
||||
player.playSound( player, Sound.BLOCK_NOTE_BLOCK_BASS, 1f, 1f )
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package club.mcscrims.speedhg.kit.impl
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import club.mcscrims.speedhg.ability.AbilityContext
|
||||
import club.mcscrims.speedhg.game.GameManager
|
||||
import club.mcscrims.speedhg.kit.AbstractKit
|
||||
import club.mcscrims.speedhg.kit.PlayStyle
|
||||
import net.kyori.adventure.text.Component
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.Statistic
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class ArmorerKit(
|
||||
id: String,
|
||||
displayName: Component,
|
||||
description: List<Component>,
|
||||
icon: Material,
|
||||
playStyle: PlayStyle,
|
||||
plugin: SpeedHG,
|
||||
abilityContext: AbilityContext,
|
||||
gameManager: GameManager
|
||||
) : AbstractKit( id, displayName, description, icon, playStyle, plugin, abilityContext, gameManager ) {
|
||||
|
||||
private val killsUntilNew: Double = plugin.kitConfig.data.armorer[ "kills until new armor" ]!!
|
||||
|
||||
override fun onSelect( player: Player ) {}
|
||||
|
||||
override fun onStart( player: Player ) {}
|
||||
|
||||
override fun onHit(
|
||||
attacker: Player,
|
||||
victim: Player,
|
||||
event: EntityDamageByEntityEvent
|
||||
) {
|
||||
if ( !gameManager.isRunning() )
|
||||
return
|
||||
|
||||
if ( victim.health > 0.0 )
|
||||
return
|
||||
|
||||
val kills = attacker.getStatistic( Statistic.PLAYER_KILLS )
|
||||
|
||||
if (( kills.toDouble() / killsUntilNew ) % 2 != 0.0 )
|
||||
return
|
||||
|
||||
upgradeArmor( attacker, kills )
|
||||
attacker.playSound( attacker, Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 1f )
|
||||
}
|
||||
|
||||
override fun onDamaged( attacker: Player, victim: Player, event: EntityDamageByEntityEvent ) {}
|
||||
|
||||
override fun onInteract( player: Player, event: PlayerInteractEvent ) {}
|
||||
|
||||
override fun onMove( player: Player, event: PlayerMoveEvent ) {}
|
||||
|
||||
private fun upgradeArmor(
|
||||
player: Player,
|
||||
killCount: Int
|
||||
) {
|
||||
val kills = killsUntilNew.roundToInt()
|
||||
|
||||
val armorType = when( killCount / kills )
|
||||
{
|
||||
1, 2 -> ArmorType.LEATHER
|
||||
3, 4 -> ArmorType.CHAINMAIL
|
||||
5, 6 -> ArmorType.GOLD
|
||||
7, 8 -> ArmorType.IRON
|
||||
else -> return
|
||||
}
|
||||
|
||||
val enchanted = ( killCount / kills ) % 2 == 0
|
||||
|
||||
val armor = createArmor( armorType, enchanted )
|
||||
player.inventory.armorContents = arrayOf( null, armor[0], null, armor[1] )
|
||||
|
||||
if ( !enchanted )
|
||||
{
|
||||
plugin.chatManager.sendMessage( player, "kits.armorer.messages.upgrade.normal", "{armorType}" to armorType.name )
|
||||
return
|
||||
}
|
||||
|
||||
plugin.chatManager.sendMessage( player, "kits.armorer.upgrade.enchanted" )
|
||||
}
|
||||
|
||||
private fun createArmor(
|
||||
type: ArmorType,
|
||||
enchanted: Boolean
|
||||
) = listOf(
|
||||
ItemStack( type.materialChestplate ).apply {
|
||||
if ( enchanted ) addEnchantment( Enchantment.PROTECTION, 1 )
|
||||
},
|
||||
ItemStack( type.materialBoots ).apply {
|
||||
if ( enchanted ) addEnchantment( Enchantment.PROTECTION, 1 )
|
||||
}
|
||||
)
|
||||
|
||||
enum class ArmorType(
|
||||
val materialChestplate: Material,
|
||||
val materialBoots: Material
|
||||
) {
|
||||
LEATHER( Material.LEATHER_CHESTPLATE, Material.LEATHER_BOOTS ),
|
||||
CHAINMAIL( Material.CHAINMAIL_CHESTPLATE, Material.CHAINMAIL_BOOTS ),
|
||||
GOLD( Material.GOLDEN_CHESTPLATE, Material.GOLDEN_BOOTS ),
|
||||
IRON( Material.IRON_CHESTPLATE, Material.IRON_BOOTS )
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
package club.mcscrims.speedhg.kit.impl
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import club.mcscrims.speedhg.ability.AbilityContext
|
||||
import club.mcscrims.speedhg.game.GameManager
|
||||
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 club.mcscrims.spigot.util.GroundDetector
|
||||
import net.kyori.adventure.text.Component
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.GameMode
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Particle
|
||||
import org.bukkit.entity.EnderPearl
|
||||
import org.bukkit.entity.EntityType
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.block.Action
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.metadata.FixedMetadataValue
|
||||
import org.bukkit.potion.PotionEffect
|
||||
import org.bukkit.potion.PotionEffectType
|
||||
import org.bukkit.scheduler.BukkitRunnable
|
||||
import org.bukkit.util.Vector
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class BlackPantherKit(
|
||||
id: String,
|
||||
displayName: Component,
|
||||
description: List<Component>,
|
||||
icon: Material,
|
||||
playStyle: PlayStyle,
|
||||
plugin: SpeedHG,
|
||||
abilityContext: AbilityContext,
|
||||
gameManager: GameManager
|
||||
) : AbstractKit( id, displayName, description, icon, playStyle, plugin, abilityContext, gameManager ) {
|
||||
|
||||
private lateinit var blackDye: ItemStack
|
||||
private lateinit var blazePowder: ItemStack
|
||||
|
||||
private val extraDamageAddition = plugin.kitConfig.data.blackPanther[ "extra damage on top" ]!!
|
||||
private val defaultRadius = plugin.kitConfig.data.blackPanther[ "default hit radius" ]!!
|
||||
private val explosionMultiplier = plugin.kitConfig.data.blackPanther[ "explosion multiplier" ]!!
|
||||
|
||||
override fun onSelect( player: Player ) {}
|
||||
|
||||
override fun onStart(
|
||||
player: Player
|
||||
) {
|
||||
when( playStyle )
|
||||
{
|
||||
PlayStyle.DEFENSIVE ->
|
||||
{
|
||||
blackDye = ItemBuilder( plugin, Material.BLACK_DYE )
|
||||
.name(plugin.messageConfig.data.getKitItemNames( "blackpanther", "blackDye" )!![ "null" ]!!)
|
||||
.unbreakable( true )
|
||||
.hideAttributes()
|
||||
.build()
|
||||
|
||||
items.add( blackDye )
|
||||
player.inventory.setItem( 0, blackDye )
|
||||
}
|
||||
|
||||
PlayStyle.OFFENSIVE ->
|
||||
{
|
||||
blackDye = ItemBuilder( plugin, Material.BLACK_DYE )
|
||||
.name(plugin.messageConfig.data.getKitItemNames( "blackpanther", "blackDye" )!![ playStyle.name.lowercase() ]!!)
|
||||
.unbreakable( true )
|
||||
.hideAttributes()
|
||||
.build()
|
||||
|
||||
blazePowder = ItemBuilder( plugin, Material.BLAZE_POWDER )
|
||||
.name(plugin.messageConfig.data.getKitItemNames( "blackpanther", "blazePowder" )!![ playStyle.name.lowercase() ]!!)
|
||||
.unbreakable( true )
|
||||
.hideAttributes()
|
||||
.build()
|
||||
|
||||
items.addAll(listOf( blackDye, blazePowder ))
|
||||
player.inventory.setItem( 0, blackDye )
|
||||
player.inventory.setItem( 1, blazePowder )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onHit(
|
||||
attacker: Player,
|
||||
victim: Player,
|
||||
event: EntityDamageByEntityEvent
|
||||
) {
|
||||
if ( !gameManager.isRunning() )
|
||||
return
|
||||
|
||||
if (!attacker.hasMetadata( KitMetaData.BP_EXTRA_DAMAGE.getKey() ))
|
||||
return
|
||||
|
||||
event.damage += extraDamageAddition
|
||||
}
|
||||
|
||||
override fun onDamaged( attacker: Player, victim: Player, event: EntityDamageByEntityEvent ) {}
|
||||
|
||||
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 != blackDye &&
|
||||
item != blazePowder )
|
||||
return
|
||||
|
||||
event.isCancelled = true
|
||||
|
||||
when( item.type )
|
||||
{
|
||||
Material.BLACK_DYE ->
|
||||
{
|
||||
val result = abilityContext.canUseAbility( player, "blackDye-blackPanther", 15 )
|
||||
|
||||
if ( result.missingHits > 0 )
|
||||
{
|
||||
plugin.chatManager.sendMessage( player, "kits.missingHits", "{hits]" to result.missingHits.toString() )
|
||||
return
|
||||
}
|
||||
|
||||
if ( playStyle == PlayStyle.DEFENSIVE )
|
||||
{
|
||||
launchAndDash( player )
|
||||
return
|
||||
}
|
||||
|
||||
push( player )
|
||||
}
|
||||
|
||||
Material.BLAZE_POWDER ->
|
||||
{
|
||||
val result = abilityContext.canUseAbility( player, "blazePowder-blackPanther", 15 )
|
||||
|
||||
if ( result.missingHits > 0 )
|
||||
{
|
||||
plugin.chatManager.sendMessage( player, "kits.missingHits", "{hits]" to result.missingHits.toString() )
|
||||
return
|
||||
}
|
||||
|
||||
extraDamage( player )
|
||||
}
|
||||
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMove( player: Player, event: PlayerMoveEvent ) {}
|
||||
|
||||
private fun push(
|
||||
player: Player
|
||||
) {
|
||||
plugin.getAlivePlayers().stream()
|
||||
.filter { it != player }
|
||||
.filter { it.location.distance( player.location ) <= defaultRadius }
|
||||
.forEach { nearby ->
|
||||
val pushDirection = nearby.location.toVector().subtract( player.location.toVector() ).normalize()
|
||||
pushDirection.multiply( 1.0 )
|
||||
pushDirection.setY( 0.5 )
|
||||
nearby.velocity = pushDirection
|
||||
|
||||
val enderPearl = player.world.spawnEntity( player.location, EntityType.ENDER_PEARL ) as EnderPearl
|
||||
enderPearl.velocity = pushDirection
|
||||
enderPearl.setMetadata( KitMetaData.IS_BLACK_PANTHER.getKey(), FixedMetadataValue( plugin, true ))
|
||||
|
||||
object : BukkitRunnable()
|
||||
{
|
||||
|
||||
override fun run()
|
||||
{
|
||||
if (GroundDetector.isOnGround( nearby ))
|
||||
{
|
||||
this.cancel()
|
||||
return
|
||||
}
|
||||
|
||||
nearby.world.spawnParticle( Particle.END_ROD, nearby.location, 5, 0.2, 0.2, 0.2 )
|
||||
}
|
||||
|
||||
}.runTaskTimer( plugin, 0L, 2L )
|
||||
}
|
||||
}
|
||||
|
||||
private fun launchAndDash(
|
||||
player: Player,
|
||||
upwardVelocity: Double = 2.2,
|
||||
waitTicks: Long = 60L,
|
||||
dashSpeed: Double = 2.8,
|
||||
horizontalOnly: Boolean = true,
|
||||
yBoost: Double = 0.2,
|
||||
noFallDamageMillis: Double = 1.0
|
||||
) {
|
||||
if ( !player.isOnline ) return
|
||||
if ( player.isInsideVehicle ) player.leaveVehicle()
|
||||
if ( player.gameMode == GameMode.SPECTATOR ) return
|
||||
|
||||
player.velocity = Vector( 0.0, upwardVelocity, 0.0 )
|
||||
player.fallDistance = 0f
|
||||
|
||||
if ( noFallDamageMillis > 0 )
|
||||
player.addPotionEffect(PotionEffect( PotionEffectType.RESISTANCE, ( noFallDamageMillis * 20 ).toInt(), 999, false, false, false ))
|
||||
|
||||
Bukkit.getScheduler().runTaskLater( plugin, { ->
|
||||
val p = Bukkit.getPlayer( player.uniqueId ) ?: return@runTaskLater
|
||||
if ( !p.isOnline ) return@runTaskLater
|
||||
|
||||
var dir = p.eyeLocation.direction
|
||||
if ( horizontalOnly ) dir = Vector( dir.x, 0.0, dir.z )
|
||||
dir = if ( dir.lengthSquared() < 1e-6 ) Vector( 0, 0, 0 ) else dir.normalize()
|
||||
|
||||
val dash = dir.multiply( dashSpeed ).add(Vector( 0.0, yBoost, 0.0 ))
|
||||
p.velocity = dash
|
||||
}, max( 0L, waitTicks ))
|
||||
|
||||
object : BukkitRunnable()
|
||||
{
|
||||
|
||||
override fun run()
|
||||
{
|
||||
if (GroundDetector.isOnGround( player ))
|
||||
{
|
||||
player.world.createExplosion(
|
||||
player.location,
|
||||
explosionMultiplier.roundToInt().toFloat(),
|
||||
false, true
|
||||
)
|
||||
|
||||
val alivePlayers = plugin.getAlivePlayers().stream()
|
||||
.filter { it != player }
|
||||
.filter { it.location.distance( player.location ) <= defaultRadius }
|
||||
.toList()
|
||||
|
||||
alivePlayers.forEach { nearby ->
|
||||
nearby.damage( 6.0, player )
|
||||
}
|
||||
|
||||
plugin.chatManager.sendMessage( player, "kits.blackPanther.messages.wakandaForever.hit", "{hit}" to alivePlayers.size.toString() )
|
||||
this.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
}.runTaskTimer( plugin, max( 0L, waitTicks ) + 5L, 5L )
|
||||
}
|
||||
|
||||
private fun extraDamage(
|
||||
player: Player
|
||||
) {
|
||||
player.setMetadata( KitMetaData.BP_EXTRA_DAMAGE.getKey(), FixedMetadataValue( plugin, true ))
|
||||
plugin.chatManager.sendMessage( player, "kits.blackPanther.messages.extraDamage.activated" )
|
||||
|
||||
plugin.schedulerManager.runLater( 12 * 30L ) {
|
||||
|
||||
player.removeMetadata( KitMetaData.BP_EXTRA_DAMAGE.getKey(), plugin )
|
||||
plugin.chatManager.sendMessage( player, "kits.blackPanther.messages.extraDamage.deactivated" )
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
package club.mcscrims.speedhg.kit.impl
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import club.mcscrims.speedhg.SpeedHG.Companion.content
|
||||
import club.mcscrims.speedhg.ability.AbilityContext
|
||||
import club.mcscrims.speedhg.game.GameManager
|
||||
import club.mcscrims.speedhg.kit.AbstractKit
|
||||
import club.mcscrims.speedhg.kit.PlayStyle
|
||||
import club.mcscrims.speedhg.util.DirectionUtil
|
||||
import club.mcscrims.spigot.chat.getDisplayName
|
||||
import club.mcscrims.spigot.item.ItemBuilder
|
||||
import net.kyori.adventure.text.Component
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.block.Action
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent
|
||||
import org.bukkit.event.player.PlayerInteractEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.potion.PotionEffect
|
||||
import org.bukkit.potion.PotionEffectType
|
||||
import org.bukkit.util.Vector
|
||||
|
||||
class BlitzcrankKit(
|
||||
id: String,
|
||||
displayName: Component,
|
||||
description: List<Component>,
|
||||
icon: Material,
|
||||
playStyle: PlayStyle,
|
||||
plugin: SpeedHG,
|
||||
abilityContext: AbilityContext,
|
||||
gameManager: GameManager
|
||||
) : AbstractKit( id, displayName, description, icon, playStyle, plugin, abilityContext, gameManager ) {
|
||||
|
||||
override fun onSelect( player: Player ) {}
|
||||
|
||||
private lateinit var hotsItem: ItemStack
|
||||
private lateinit var fishingRodItem: ItemStack
|
||||
private lateinit var pufferfishItem: ItemStack
|
||||
|
||||
override fun onStart(
|
||||
player: Player
|
||||
) {
|
||||
hotsItem = ItemBuilder( plugin, Material.HEART_OF_THE_SEA )
|
||||
.name(plugin.messageConfig.data.getKitItemNames( "blitzcrank", "hots" )!![ playStyle.name.lowercase() ]!!)
|
||||
.unbreakable( true )
|
||||
.hideAttributes()
|
||||
.build()
|
||||
|
||||
items.add( hotsItem )
|
||||
player.inventory.setItem( 0, hotsItem )
|
||||
|
||||
when( playStyle )
|
||||
{
|
||||
PlayStyle.DEFENSIVE ->
|
||||
{
|
||||
fishingRodItem = ItemBuilder( plugin, Material.FISHING_ROD )
|
||||
.name(plugin.messageConfig.data.getKitItemNames( "blitzcrank", "fishingrod" )!![ playStyle.name.lowercase() ]!!)
|
||||
.unbreakable( true )
|
||||
.hideAttributes()
|
||||
.build()
|
||||
|
||||
items.add( fishingRodItem )
|
||||
player.inventory.setItem( 1, fishingRodItem )
|
||||
}
|
||||
|
||||
PlayStyle.OFFENSIVE ->
|
||||
{
|
||||
pufferfishItem = ItemBuilder( plugin, Material.PUFFERFISH )
|
||||
.name(plugin.messageConfig.data.getKitItemNames( "blitzcrank", "pufferfish" )!![ playStyle.name.lowercase() ]!!)
|
||||
.unbreakable( true )
|
||||
.hideAttributes()
|
||||
.build()
|
||||
|
||||
items.add( pufferfishItem )
|
||||
player.inventory.setItem( 1, pufferfishItem )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onHit( attacker: Player, victim: Player, event: EntityDamageByEntityEvent ) {}
|
||||
|
||||
override fun onDamaged( attacker: Player, victim: Player, event: EntityDamageByEntityEvent ) {}
|
||||
|
||||
// Ultimate
|
||||
private val ultimateDamage = plugin.kitConfig.data.blitzcrank[ "ultimate damage" ]!!
|
||||
private val ultimateRadius = plugin.kitConfig.data.blitzcrank[ "ultimate radius" ]!!
|
||||
private val ultimateStunDuration = plugin.kitConfig.data.blitzcrank[ "ultimate stun duration" ]!!
|
||||
|
||||
// Hook
|
||||
private val hookRange = plugin.kitConfig.data.blitzcrank[ "hook range" ]!!
|
||||
|
||||
// Stun
|
||||
private val stunHeight = plugin.kitConfig.data.blitzcrank[ "stun height" ]!!
|
||||
private val stunRadius = plugin.kitConfig.data.blitzcrank[ "stun radius" ]!!
|
||||
private val stunSlowDuration = plugin.kitConfig.data.blitzcrank[ "stun slow duration" ]!!
|
||||
|
||||
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 != hotsItem &&
|
||||
item != fishingRodItem &&
|
||||
item != pufferfishItem )
|
||||
return
|
||||
|
||||
when( item.type )
|
||||
{
|
||||
Material.HEART_OF_THE_SEA ->
|
||||
{
|
||||
val result = abilityContext.canUseAbility( player, "hots-blitzcrank", 15 )
|
||||
|
||||
if ( result.missingHits > 0 )
|
||||
{
|
||||
plugin.chatManager.sendMessage( player, "kits.missingHits", "{hits]" to result.missingHits.toString() )
|
||||
return
|
||||
}
|
||||
|
||||
ultimate( player, ultimateRadius )
|
||||
}
|
||||
|
||||
Material.FISHING_ROD ->
|
||||
{
|
||||
val result = abilityContext.canUseAbility( player, "hook-blitzcrank", 15 )
|
||||
|
||||
if ( result.missingHits > 0 )
|
||||
{
|
||||
plugin.chatManager.sendMessage( player, "kits.missingHits", "{hits]" to result.missingHits.toString() )
|
||||
return
|
||||
}
|
||||
|
||||
hookPlayer( player )
|
||||
}
|
||||
|
||||
Material.PUFFERFISH ->
|
||||
{
|
||||
val result = abilityContext.canUseAbility( player, "stun-blitzcrank", 15 )
|
||||
|
||||
if ( result.missingHits > 0 )
|
||||
{
|
||||
plugin.chatManager.sendMessage( player, "kits.missingHits", "{hits]" to result.missingHits.toString() )
|
||||
return
|
||||
}
|
||||
|
||||
stunNearby( player, stunRadius )
|
||||
}
|
||||
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMove( player: Player, event: PlayerMoveEvent ) {}
|
||||
|
||||
private fun ultimate(
|
||||
player: Player,
|
||||
radius: Double
|
||||
) {
|
||||
val nearbyPlayers = player.world.getNearbyPlayers( player.location, radius )
|
||||
|
||||
nearbyPlayers.forEach { nearby ->
|
||||
|
||||
nearby.damage( ultimateDamage, player )
|
||||
|
||||
nearby.addPotionEffect(PotionEffect(
|
||||
PotionEffectType.SLOWNESS,
|
||||
ultimateStunDuration.toInt() * 20,
|
||||
255,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
))
|
||||
|
||||
plugin.chatManager.sendMessage( nearby, "kits.blitzcrank.messages.ultimate.target", "{player}" to player.getDisplayName )
|
||||
}
|
||||
|
||||
plugin.chatManager.sendMessage( player, "kits.blitzcrank.messages.ultimate.player", "{nearby}" to nearbyPlayers.size.toString() )
|
||||
}
|
||||
|
||||
private fun hookPlayer(
|
||||
player: Player
|
||||
) {
|
||||
val target = DirectionUtil.getTargetPlayerInLineOfSight( player, hookRange, 0.5 )
|
||||
|
||||
if ( target == null )
|
||||
{
|
||||
plugin.chatManager.sendMessage( player, "kits.blitzcrank.messages.no_player_in_sight" )
|
||||
return
|
||||
}
|
||||
|
||||
val hookDirection = target.location.toVector().add( player.location.toVector() ).normalize()
|
||||
hookDirection.multiply( 1.0 )
|
||||
hookDirection.setY( 0.5 )
|
||||
target.velocity = hookDirection
|
||||
|
||||
plugin.chatManager.sendMessage( player, "kits.blitzcrank.messages.hook.player", "{player}" to target.getDisplayName )
|
||||
plugin.chatManager.sendMessage( target, "kits.blitzcrank.messages.hook.target" )
|
||||
}
|
||||
|
||||
private fun stunNearby(
|
||||
player: Player,
|
||||
radius: Double
|
||||
) {
|
||||
val nearbyPlayers = player.world.getNearbyPlayers( player.location, radius )
|
||||
|
||||
nearbyPlayers.forEach { nearby ->
|
||||
|
||||
val velocity = nearby.velocity
|
||||
velocity.add(Vector( 0.0, stunHeight, 0.0 ))
|
||||
nearby.velocity = velocity
|
||||
|
||||
nearby.addPotionEffect(PotionEffect(
|
||||
PotionEffectType.SLOWNESS,
|
||||
20 * stunSlowDuration.toInt(),
|
||||
4, false, false, false
|
||||
))
|
||||
|
||||
plugin.chatManager.sendMessage( nearby, "kits.blitzcrank.messages.stun.target" )
|
||||
}
|
||||
|
||||
plugin.chatManager.sendMessage( player, "kits.blitzcrank.messages.stun.player", "{nearby}" to nearbyPlayers.size.toString() )
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user