Skip to content

Commit 3848846

Browse files
committed
water splash
1 parent 3187bc4 commit 3848846

File tree

6 files changed

+250
-12
lines changed

6 files changed

+250
-12
lines changed

plugin/src/main/kotlin/dev/betrix/superSmashMobsBrawl/abilities/BrawlAbility.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ abstract class BrawlAbility(val id: String, val player: Player) : Manageable(),
4646

4747
private val abilityKey = NamespacedKey(plugin, "abilityId")
4848

49-
private var lastUsed: Long = 0
49+
protected var lastUsed: Long = 0
5050

5151
private var lastCheckForCanActivate = true
5252

plugin/src/main/kotlin/dev/betrix/superSmashMobsBrawl/abilities/ChickenMissileAbility.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@ import dev.betrix.superSmashMobsBrawl.events.BrawlDamageEvent
44
import dev.betrix.superSmashMobsBrawl.events.BrawlDamageType
55
import dev.betrix.superSmashMobsBrawl.events.Damager
66
import dev.betrix.superSmashMobsBrawl.extensions.setVelocity
7-
import dev.betrix.superSmashMobsBrawl.services.MinigameService
87
import gg.flyte.twilight.extension.getNearbyEntities
98
import gg.flyte.twilight.scheduler.repeatingTask
109
import org.bukkit.*
1110
import org.bukkit.entity.Chicken
1211
import org.bukkit.entity.LivingEntity
1312
import org.bukkit.entity.Player
14-
import org.bukkit.util.Vector
15-
import org.koin.core.component.inject
1613

1714
class ChickenMissileAbility(player: Player) : BrawlAbility("chicken_missile", player) {
1815
private val damage = metadata.double("damage") ?: 8.0
@@ -164,7 +161,4 @@ class ChickenMissileAbility(player: Player) : BrawlAbility("chicken_missile", pl
164161
val minigame = minigameService.getMinigameForPlayer(player) ?: return false
165162
return !minigame.arePlayersOnSameTeam(player, entity)
166163
}
167-
168-
private val lastUsed: Long
169-
get() = System.currentTimeMillis() - elapsedSinceLastActivation
170164
}
Lines changed: 234 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,244 @@
11
package dev.betrix.superSmashMobsBrawl.abilities
22

3+
import dev.betrix.superSmashMobsBrawl.events.BrawlDamageEvent
4+
import dev.betrix.superSmashMobsBrawl.events.BrawlDamageType
5+
import dev.betrix.superSmashMobsBrawl.events.Damager
6+
import dev.betrix.superSmashMobsBrawl.extensions.event
7+
import dev.betrix.superSmashMobsBrawl.extensions.isOnBlock
38
import dev.betrix.superSmashMobsBrawl.extensions.sendDebugMessage
9+
import dev.betrix.superSmashMobsBrawl.extensions.setVelocity
10+
import gg.flyte.twilight.event.event
11+
import gg.flyte.twilight.extension.getNearbyEntities
12+
import gg.flyte.twilight.scheduler.TwilightRunnable
13+
import gg.flyte.twilight.scheduler.repeatingTask
14+
import kotlin.random.Random
15+
import org.bukkit.Effect
16+
import org.bukkit.Material
17+
import org.bukkit.Particle
18+
import org.bukkit.Sound
19+
import org.bukkit.block.BlockFace
20+
import org.bukkit.entity.LivingEntity
421
import org.bukkit.entity.Player
22+
import org.bukkit.util.Vector
523

624
class WaterSplashAbility(player: Player) : BrawlAbility("water_splash", player) {
25+
26+
private val minimumAirTimeMs: Long = metadata.long("minimumAirTimeMs") ?: 750L
27+
private val secondBoostTimeMs: Long = metadata.long("secondBoostTimeMs") ?: 800L
28+
private val firstVelocity: Double = metadata.double("firstVelocity") ?: 1.0
29+
private val secondVelocity: Double = metadata.double("secondVelocity") ?: 1.5
30+
private val pullInRadius: Double = metadata.double("pullInRadius") ?: 5.0
31+
private val damageRadius: Double = metadata.double("damageRadius") ?: 5.0
32+
private val damage: Double = metadata.double("damage") ?: 12.0
33+
private val pullYStrength: Double = metadata.double("pullYStrength") ?: 0.5
34+
private val knockbackMultiplier: Double = metadata.double("knockbackMultiplier") ?: 1.0
35+
private val blockEffectRadius: Int = (metadata.int("blockEffectRadius") ?: 5).coerceAtLeast(0)
36+
private val blockEffectChance: Double = metadata.double("blockEffectChance") ?: 0.1
37+
38+
private var splashTask: TwilightRunnable? = null
39+
private var boostUsed: Boolean = false
40+
741
override fun activate() {
842
super.activate()
9-
player.sendDebugMessage("Water Splash ability pending implementation")
43+
44+
// Initial upward velocity
45+
player.setVelocity(
46+
velocity = Vector(0.0, 1.0, 0.0),
47+
strength = firstVelocity,
48+
ySet = true,
49+
yBase = firstVelocity,
50+
yAdd = 0.0,
51+
yMax = 10.0,
52+
groundBoost = false,
53+
)
54+
55+
// Pull nearby players towards owner
56+
pullNearbyPlayers()
57+
58+
// Start the splash monitoring task
59+
boostUsed = false
60+
startSplashTask()
61+
}
62+
63+
override fun teardown() {
64+
splashTask?.cancel()
65+
splashTask = null
66+
super.teardown()
67+
}
68+
69+
private fun pullNearbyPlayers() {
70+
player.location
71+
.getNearbyEntities(pullInRadius, pullInRadius, pullInRadius)
72+
.filterIsInstance<LivingEntity>()
73+
.filter { it != player }
74+
.forEach { entity ->
75+
val trajectory =
76+
player.location
77+
.toVector()
78+
.subtract(entity.location.toVector())
79+
.normalize()
80+
trajectory.y = pullYStrength
81+
82+
entity.setVelocity(
83+
velocity = trajectory,
84+
strength = 1.0,
85+
ySet = false,
86+
yBase = 0.0,
87+
yAdd = 0.0,
88+
yMax = 10.0,
89+
groundBoost = false,
90+
)
91+
}
92+
}
93+
94+
private fun startSplashTask() {
95+
splashTask?.cancel()
96+
97+
val activationTime = elapsedSinceLastActivation
98+
99+
splashTask =
100+
repeatingTask(0, 1) {
101+
if (!player.isValid || player.isDead) {
102+
cancel()
103+
splashTask = null
104+
return@repeatingTask
105+
}
106+
107+
// Show water particles
108+
player.world.spawnParticle(
109+
Particle.DRIPPING_WATER,
110+
player.location,
111+
10,
112+
0.5,
113+
0.5,
114+
0.5,
115+
0.01,
116+
)
117+
118+
val timeElapsed = System.currentTimeMillis() - (lastUsed - activationTime)
119+
120+
// Check for landing
121+
if (player.isOnBlock() && timeElapsed >= minimumAirTimeMs) {
122+
performSplash()
123+
cancel()
124+
splashTask = null
125+
return@repeatingTask
126+
}
127+
128+
// Check for second boost
129+
if (player.isBlocking && timeElapsed >= secondBoostTimeMs && !boostUsed) {
130+
boostUsed = true
131+
player.sendDebugMessage("[WaterSplash] Second boost activated")
132+
133+
val direction = player.location.direction.multiply(secondVelocity)
134+
player.setVelocity(
135+
velocity = direction,
136+
strength = 1.0,
137+
ySet = false,
138+
yBase = 0.0,
139+
yAdd = 0.0,
140+
yMax = 10.0,
141+
groundBoost = false,
142+
)
143+
}
144+
}
145+
146+
splashTask?.let { runnables.add(it) }
147+
}
148+
149+
private fun performSplash() {
150+
val ownerLocation = player.location
151+
152+
player.sendDebugMessage("[WaterSplash] Landing splash at ${ownerLocation.x}, ${ownerLocation.y}, ${ownerLocation.z}")
153+
154+
// Firework particles
155+
player.world.spawnParticle(
156+
Particle.FIREWORK,
157+
player.eyeLocation,
158+
50,
159+
0.0,
160+
0.0,
161+
0.0,
162+
0.5,
163+
)
164+
165+
// Block effects
166+
triggerBlockEffects()
167+
168+
// Sound effect
169+
player.world.playSound(ownerLocation, Sound.ENTITY_GENERIC_SPLASH, 2f, 0f)
170+
171+
// Damage nearby entities
172+
ownerLocation
173+
.getNearbyEntities(damageRadius, damageRadius, damageRadius)
174+
.filterIsInstance<LivingEntity>()
175+
.filter { it != player }
176+
.forEach { target ->
177+
val distance = target.location.distance(ownerLocation)
178+
val normalizedDistance = ((damageRadius - distance) / damageRadius).coerceAtLeast(0.0)
179+
val scaledDamage = damage * normalizedDistance
180+
181+
player.sendDebugMessage("[WaterSplash] Damaging ${target.name} for $scaledDamage")
182+
183+
BrawlDamageEvent(
184+
target,
185+
Damager.DamagerLivingEntity(player),
186+
scaledDamage,
187+
knockbackMultiplier,
188+
BrawlDamageType.Explosion,
189+
)
190+
.callEvent()
191+
}
192+
}
193+
194+
private fun triggerBlockEffects() {
195+
if (blockEffectRadius <= 0 || blockEffectChance <= 0.0) {
196+
return
197+
}
198+
199+
val origin = player.location.block
200+
val world = origin.world
201+
202+
for (x in -blockEffectRadius..blockEffectRadius) {
203+
for (y in -blockEffectRadius..blockEffectRadius) {
204+
for (z in -blockEffectRadius..blockEffectRadius) {
205+
if (Random.nextDouble() >= blockEffectChance) {
206+
continue
207+
}
208+
209+
val checkBlock = origin.getRelative(x, y, z)
210+
211+
if (!checkBlock.type.isSolid || checkBlock.type == Material.AIR) {
212+
continue
213+
}
214+
215+
val aboveBlock = checkBlock.getRelative(BlockFace.UP)
216+
217+
if (aboveBlock.type.isSolid) {
218+
continue
219+
}
220+
221+
world.playEffect(checkBlock.location, Effect.STEP_SOUND, checkBlock.type)
222+
}
223+
}
224+
}
225+
}
226+
227+
override fun setup() {
228+
super.setup()
229+
230+
// Listen for damage events to cancel knockback while ability is active
231+
listeners.add(
232+
event<BrawlDamageEvent> {
233+
if (victim != this@WaterSplashAbility.player) {
234+
return@event
235+
}
236+
237+
if (splashTask != null) {
238+
player.sendDebugMessage("[WaterSplash] Cancelling knockback during splash")
239+
knockbackMultiplier = 0.0
240+
}
241+
}
242+
)
10243
}
11244
}

plugin/src/main/kotlin/dev/betrix/superSmashMobsBrawl/abilities/WhirlpoolAxeAbility.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import org.bukkit.inventory.ItemStack
1515

1616
class WhirlpoolAxeAbility(player: Player) : BrawlAbility("whirlpool_axe", player) {
1717

18-
private val damage = metadata.double("damage") ?: 4.0
18+
private val damage = metadata.double("damage") ?: 3.0
1919
private val hitboxSize = metadata.double("hitboxSize") ?: 0.5
2020
private val knockbackMultiplier = metadata.double("knockbackMultiplier") ?: 0.0
2121
private val expirationTicks = metadata.long("expirationTicks") ?: 60L

plugin/src/main/resources/data/abilities.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ abilities:
238238
hotbarItem: iron_axe
239239
displayItem: prismarine_shard
240240
metadata:
241-
damage: 4.0
241+
damage: 3.0
242242
hitboxSize: 0.5
243243
knockbackMultiplier: 0.0
244244
expirationTicks: 60
@@ -252,7 +252,18 @@ abilities:
252252
usage: right_click
253253
hotbarItem: iron_shovel
254254
displayItem: water_bucket
255-
metadata: {}
255+
metadata:
256+
minimumAirTimeMs: 750
257+
secondBoostTimeMs: 800
258+
firstVelocity: 1.0
259+
secondVelocity: 1.5
260+
pullInRadius: 5.0
261+
damageRadius: 5.0
262+
damage: 12.0
263+
pullYStrength: 0.5
264+
knockbackMultiplier: 1.0
265+
blockEffectRadius: 5
266+
blockEffectChance: 0.1
256267

257268
- id: target_laser
258269
cooldown: 15.0

plugin/src/main/resources/data/kits.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ kits:
253253

254254
# Guardian
255255
- id: guardian
256-
meleeDamage: 5.0
256+
meleeDamage: 4.5
257257
armor: 4.5
258258
knockbackMultiplier: 1.25
259259
disguiseId: "guardian"

0 commit comments

Comments
 (0)