diff --git a/src/main/kotlin/club/mcscrims/speedhg/kit/impl/PuppetKit.kt b/src/main/kotlin/club/mcscrims/speedhg/kit/impl/PuppetKit.kt index 7586eb8..0cf0210 100644 --- a/src/main/kotlin/club/mcscrims/speedhg/kit/impl/PuppetKit.kt +++ b/src/main/kotlin/club/mcscrims/speedhg/kit/impl/PuppetKit.kt @@ -6,10 +6,12 @@ import club.mcscrims.speedhg.kit.Playstyle import club.mcscrims.speedhg.kit.ability.AbilityResult import club.mcscrims.speedhg.kit.ability.ActiveAbility import club.mcscrims.speedhg.kit.ability.PassiveAbility +import club.mcscrims.speedhg.util.AbilityUtils import club.mcscrims.speedhg.util.ItemBuilder import club.mcscrims.speedhg.util.trans import net.kyori.adventure.text.Component import org.bukkit.Bukkit +import org.bukkit.Color import org.bukkit.Material import org.bukkit.Particle import org.bukkit.Sound @@ -274,6 +276,11 @@ class PuppetKit : Kit() enemies.forEach { enemy -> enemy.damage( capturedDrainDmg, player ) + AbilityUtils.drawColoredParticleLine( + player.location, + enemy.location, + 10, Color.RED + ) } val remainingHealBudget = capturedMaxTotalHeal - totalHealedHp @@ -285,11 +292,6 @@ class PuppetKit : Kit() totalHealedHp += actualHeal // Audio-visual feedback - player.world.spawnParticle( - Particle.HEART, - player.location.clone().add( 0.0, 2.0, 0.0 ), - 3, 0.4, 0.2, 0.4, 0.0 - ) player.playSound( player.location, Sound.ENTITY_GENERIC_DRINK, 0.5f, 0.4f ) player.sendActionBar( player.trans( diff --git a/src/main/kotlin/club/mcscrims/speedhg/util/AbilityFeedback.kt b/src/main/kotlin/club/mcscrims/speedhg/util/AbilityFeedback.kt deleted file mode 100644 index e6475ac..0000000 --- a/src/main/kotlin/club/mcscrims/speedhg/util/AbilityFeedback.kt +++ /dev/null @@ -1,37 +0,0 @@ -package club.mcscrims.speedhg.util - -import org.bukkit.Location -import org.bukkit.Sound -import org.bukkit.entity.Player - -object AbilityFeedback { - - // ── Charge Feedback ──────────────────────────────────────────────────── - - fun playChargeReady( player: Player ) { - player.playSound( player.location, Sound.BLOCK_BEACON_POWER_SELECT, 1f, 1.6f ) - } - - fun playCharging( player: Player ) { - player.playSound( player.location, Sound.BLOCK_COMPARATOR_CLICK, 0.6f, 1.2f ) - } - - // ── Activation Feedback ──────────────────────────────────────────────── - - fun playActivation( player: Player ) { - player.playSound( player.location, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 0.8f, 1.0f ) - } - - // ── Impact Feedback ─────────────────────────────────────────────────── - - fun playImpact( location: Location ) { - location.world?.playSound( location, Sound.BLOCK_ANVIL_LAND, 1f, 1.2f ) - } - - // ── Cooldown Feedback ────────────────────────────────────────────────── - - fun playCooldownExpired( player: Player ) { - player.playSound( player.location, Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 1.8f ) - } - -} \ No newline at end of file diff --git a/src/main/kotlin/club/mcscrims/speedhg/util/AbilityParticles.kt b/src/main/kotlin/club/mcscrims/speedhg/util/AbilityParticles.kt deleted file mode 100644 index 26324c9..0000000 --- a/src/main/kotlin/club/mcscrims/speedhg/util/AbilityParticles.kt +++ /dev/null @@ -1,50 +0,0 @@ -package club.mcscrims.speedhg.util - -import org.bukkit.Location -import org.bukkit.Particle - -object AbilityParticles { - - // ── Directional Impact Ring ──────────────────────────────────────────── - - fun spawnImpactRing( center: Location, radius: Double = 1.5 ) { - val particleCount = 12 - for ( i in 0 until particleCount ) { - val angle = ( 2 * Math.PI * i / particleCount ) - val x = kotlin.math.cos( angle ) * radius - val z = kotlin.math.sin( angle ) * radius - - center.world?.spawnParticle( - Particle.FLAME, - center.clone().add( x, 0.5, z ), - 1, 0.0, 0.0, 0.0, 0.0 - ) - } - } - - // ── Charge Build Indicator ──────────────────────────────────────────── - - fun spawnChargeRing( center: Location, scale: Double ) { - val radius = 0.5 + ( scale * 1.5 ) - center.world?.spawnParticle( - Particle.ELECTRIC_SPARK, - center, - 8, - radius, radius, radius, - 0.1 - ) - } - - // ── Cooldown Indicator ──────────────────────────────────────────────── - - fun spawnCooldownIndicator( location: Location ) { - location.world?.spawnParticle( - Particle.FLAME, - location.clone().add( 0.0, 1.0, 0.0 ), - 6, - 0.3, 0.3, 0.3, - 0.0 - ) - } - -} \ No newline at end of file diff --git a/src/main/kotlin/club/mcscrims/speedhg/util/AbilityUtils.kt b/src/main/kotlin/club/mcscrims/speedhg/util/AbilityUtils.kt index d4b479c..4e67ad5 100644 --- a/src/main/kotlin/club/mcscrims/speedhg/util/AbilityUtils.kt +++ b/src/main/kotlin/club/mcscrims/speedhg/util/AbilityUtils.kt @@ -5,6 +5,7 @@ import org.bukkit.Color import org.bukkit.GameMode import org.bukkit.Location import org.bukkit.Particle +import org.bukkit.World import org.bukkit.entity.Player import org.bukkit.scheduler.BukkitRunnable import org.bukkit.util.Vector @@ -56,15 +57,46 @@ object AbilityUtils { }.runTaskTimer( plugin, 0L, 1L ) } - fun drawParticleLine( + fun drawColoredParticleLine( startLocation: Location, endLocation: Location, - particle: Particle, steps: Int, dustColor: Color ) { - if ( steps <= 0 ) throw IllegalArgumentException( "Steps must be greater than 0." ) val world = startLocation.world ?: throw IllegalStateException( "World cannot be null." ) + val options = Particle.DustOptions( dustColor, 1f ) + + spawnParticleLine( + startLocation, + endLocation, steps + ) { ( x, y, z ) -> + world.spawnParticle( Particle.DUST, x, y, z, 1, 0.0, 0.0, 0.0, 0.0, options ) + } + } + + fun drawGenericParticleLine( + startLocation: Location, + endLocation: Location, + steps: Int, + particle: Particle + ) { + val world = startLocation.world ?: throw IllegalStateException( "World cannot be null." ) + + spawnParticleLine( + startLocation, + endLocation, steps + ) { ( x, y, z ) -> + world.spawnParticle( particle, x, y, z, 1, 0.0, 0.0, 0.0, 0.0 ) + } + } + + private fun spawnParticleLine( + startLocation: Location, + endLocation: Location, + steps: Int, + onParticle: (Triple) -> Unit + ) { + if ( steps <= 0 ) throw IllegalArgumentException( "Steps must be greater than 0." ) if ( startLocation.world != endLocation.world ) throw IllegalStateException( "Locations must be in the same world." ) val diffX = ( endLocation.x - startLocation.x ) / steps @@ -76,26 +108,8 @@ object AbilityUtils { val x = startLocation.x + diffX * i val y = startLocation.y + diffY * i val z = startLocation.z + diffZ * i - - world.spawnParticle( particle, x, y, z, 1, Particle.DustOptions( dustColor, 1f )) + onParticle(Triple( x, y, z )) } } - fun runForNearbyPlayers( - player: Player, - radius: Double, - filter: (Player) -> Boolean, - runnable: Consumer - ): MutableCollection - { - if ( radius <= 0.0 ) throw IllegalArgumentException( "Radius must be greater than 0.0." ) - - val world = player.world - val nearbyPlayers = world.getNearbyPlayers( player.location, radius ).filter( filter ) - .filter { it != player && it.gameMode == GameMode.SURVIVAL }.toMutableList() - - nearbyPlayers.forEach( runnable ) - return nearbyPlayers - } - } \ No newline at end of file