From 1d7ff8bd2f2c422d789008aaea883e51d0aa4703 Mon Sep 17 00:00:00 2001 From: TDSTOS Date: Tue, 9 Dec 2025 19:57:55 +0100 Subject: [PATCH] Add new kit & register --- .../kotlin/club/mcscrims/speedhg/SpeedHG.kt | 5 + .../club/mcscrims/speedhg/config/KitConfig.kt | 13 + .../club/mcscrims/speedhg/kit/KitManager.kt | 18 ++ .../speedhg/kit/impl/BlackPantherKit.kt | 5 + .../speedhg/kit/impl/BlitzcrankKit.kt | 233 ++++++++++++++++++ .../mcscrims/speedhg/util/DirectionUtil.kt | 28 +++ 6 files changed, 302 insertions(+) create mode 100644 src/main/kotlin/club/mcscrims/speedhg/kit/impl/BlitzcrankKit.kt diff --git a/src/main/kotlin/club/mcscrims/speedhg/SpeedHG.kt b/src/main/kotlin/club/mcscrims/speedhg/SpeedHG.kt index fd9fbb9..8899f2b 100644 --- a/src/main/kotlin/club/mcscrims/speedhg/SpeedHG.kt +++ b/src/main/kotlin/club/mcscrims/speedhg/SpeedHG.kt @@ -18,6 +18,8 @@ import club.mcscrims.speedhg.kit.KitListener import club.mcscrims.speedhg.kit.KitManager import club.mcscrims.speedhg.listener.GameStateListener import club.mcscrims.speedhg.listener.LunarClientListener +import club.mcscrims.speedhg.recraft.RecraftInspector +import club.mcscrims.speedhg.recraft.RecraftUtils import club.mcscrims.speedhg.world.WorldManager import club.mcscrims.spigot.chat.ChatFormatter import club.mcscrims.spigot.chat.ChatManager @@ -111,6 +113,9 @@ class SpeedHG : JavaPlugin() { setupLuckPerms() registerListener() + + RecraftUtils.registerRecipes() + RecraftInspector( this ).startRunnable() } override fun onDisable() diff --git a/src/main/kotlin/club/mcscrims/speedhg/config/KitConfig.kt b/src/main/kotlin/club/mcscrims/speedhg/config/KitConfig.kt index 54849da..dad59be 100644 --- a/src/main/kotlin/club/mcscrims/speedhg/config/KitConfig.kt +++ b/src/main/kotlin/club/mcscrims/speedhg/config/KitConfig.kt @@ -19,6 +19,9 @@ data class KitConfig( @ConfigField(name = "blackpanther", description = "BlackPanther configurations") val blackPanther: Map = getBlackPantherConfigurations(), + @ConfigField(name = "blitzcrank", description = "Blitzcrank configurations") + val blitzcrank: Map = getBlitzcrankConfigurations(), + @ConfigField(name = "gladiator", description = "Gladiator configurations") val gladiator: Map = getGladiatorConfigurations(), @@ -84,6 +87,16 @@ private fun getBlackPantherConfigurations() = mapOf( "explosion multiplier" to 3.0 ) +private fun getBlitzcrankConfigurations() = mapOf( + "ultimate damage" to 10.0, + "ultimate radius" to 5.0, + "ultimate stun duration" to 0.5, + "hook range" to 8.0, + "stun height" to 4.0, + "stun radius" to 3.0, + "stun slow duration" to 5.0 +) + private fun getGladiatorConfigurations() = mapOf( "cage radius" to 23.0, "cage height" to 10.0, diff --git a/src/main/kotlin/club/mcscrims/speedhg/kit/KitManager.kt b/src/main/kotlin/club/mcscrims/speedhg/kit/KitManager.kt index da98a35..e10b5e1 100644 --- a/src/main/kotlin/club/mcscrims/speedhg/kit/KitManager.kt +++ b/src/main/kotlin/club/mcscrims/speedhg/kit/KitManager.kt @@ -5,6 +5,8 @@ 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 @@ -38,6 +40,22 @@ class KitManager( description = emptyList(), icon = Material.IRON_CHESTPLATE ) + + registerKit( + kitClass = BlackPantherKit::class.java, + id = "blackpanther", + displayName = plugin.chatFormatter.format( "kits.blackpanther.displayName" ), + description = emptyList(), + icon = Material.DRAGON_EGG + ) + + registerKit( + kitClass = BlitzcrankKit::class.java, + id = "blitzcrank", + displayName = plugin.chatFormatter.format( "kits.blitzcrank.displayName" ), + description = emptyList(), + icon = Material.FISHING_ROD + ) } fun registerKit( diff --git a/src/main/kotlin/club/mcscrims/speedhg/kit/impl/BlackPantherKit.kt b/src/main/kotlin/club/mcscrims/speedhg/kit/impl/BlackPantherKit.kt index 802b4d5..6c604ef 100644 --- a/src/main/kotlin/club/mcscrims/speedhg/kit/impl/BlackPantherKit.kt +++ b/src/main/kotlin/club/mcscrims/speedhg/kit/impl/BlackPantherKit.kt @@ -50,6 +50,8 @@ class BlackPantherKit( .unbreakable( true ) .hideAttributes() .build() + + player.inventory.setItem( 0, blackDye ) } PlayStyle.OFFENSIVE -> @@ -65,6 +67,9 @@ class BlackPantherKit( .unbreakable( true ) .hideAttributes() .build() + + player.inventory.setItem( 0, blackDye ) + player.inventory.setItem( 1, blazePowder ) } else -> {} diff --git a/src/main/kotlin/club/mcscrims/speedhg/kit/impl/BlitzcrankKit.kt b/src/main/kotlin/club/mcscrims/speedhg/kit/impl/BlitzcrankKit.kt new file mode 100644 index 0000000..262b1d8 --- /dev/null +++ b/src/main/kotlin/club/mcscrims/speedhg/kit/impl/BlitzcrankKit.kt @@ -0,0 +1,233 @@ +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, + 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.chatFormatter.format( "kits.blitzcrank.items.hots" ).content()) + .unbreakable( true ) + .hideAttributes() + .build() + + player.inventory.setItem( 0, hotsItem ) + + when( playStyle ) + { + PlayStyle.DEFENSIVE -> + { + fishingRodItem = ItemBuilder( plugin, Material.FISHING_ROD ) + .name(plugin.chatFormatter.format( "kits.blitzcrank.items.fishing_rod" ).content()) + .unbreakable( true ) + .hideAttributes() + .build() + + player.inventory.setItem( 1, fishingRodItem ) + } + + PlayStyle.OFFENSIVE -> + { + pufferfishItem = ItemBuilder( plugin, Material.PUFFERFISH ) + .name(plugin.chatFormatter.format( "kits.blitzcrank.items.pufferfish" ).content()) + .unbreakable( true ) + .hideAttributes() + .build() + + player.inventory.setItem( 1, pufferfishItem ) + } + + else -> {} + } + } + + 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( player, "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() ) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/club/mcscrims/speedhg/util/DirectionUtil.kt b/src/main/kotlin/club/mcscrims/speedhg/util/DirectionUtil.kt index 28c5fa1..1d94d84 100644 --- a/src/main/kotlin/club/mcscrims/speedhg/util/DirectionUtil.kt +++ b/src/main/kotlin/club/mcscrims/speedhg/util/DirectionUtil.kt @@ -47,4 +47,32 @@ object DirectionUtil { return adjustedYaw } + fun getTargetPlayerInLineOfSight( + player: Player, + maxDistance: Double, + width: Double + ): Player? + { + val direction = player.eyeLocation.direction.normalize() + val origin = player.eyeLocation.toVector() + val world = player.world + + val nearbyPlayers = world.getNearbyEntitiesByType( Player::class.java, player.location, maxDistance, maxDistance, maxDistance ) + + return nearbyPlayers + .filter { it.uniqueId != player.uniqueId } + .filter { nearby -> + val nearbyLocation = nearby.location.add( 0.0, 0.5, 0.0 ).toVector() + + val toEntitiy = nearbyLocation.subtract( origin ) + + val distanceAlongLine = toEntitiy.dot( direction ) + if ( distanceAlongLine !in 0.0..maxDistance ) return@filter false + + val perpendicularDistance = toEntitiy.subtract(direction.multiply( distanceAlongLine )).length() + perpendicularDistance <= width + } + .minByOrNull { it.location.distanceSquared( player.location ) } + } + } \ No newline at end of file