-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExplodeAbility.kt
More file actions
152 lines (121 loc) · 4.87 KB
/
ExplodeAbility.kt
File metadata and controls
152 lines (121 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package dev.betrix.superSmashMobsBrawl.abilities
import com.github.shynixn.mccoroutine.bukkit.launch
import com.github.shynixn.mccoroutine.bukkit.ticks
import dev.betrix.superSmashMobsBrawl.events.BrawlDamageEvent
import dev.betrix.superSmashMobsBrawl.events.BrawlDamageType
import dev.betrix.superSmashMobsBrawl.events.Damager
import dev.betrix.superSmashMobsBrawl.extensions.doKnockback
import dev.betrix.superSmashMobsBrawl.extensions.setVelocity
import gg.flyte.twilight.event.event
import gg.flyte.twilight.extension.getNearbyEntities
import gg.flyte.twilight.scheduler.repeatingTask
import kotlin.math.min
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import org.bukkit.Particle
import org.bukkit.Sound
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
import org.bukkit.event.player.PlayerToggleSneakEvent
import org.bukkit.util.Vector
class ExplodeAbility(player: Player) : BrawlAbility("explode", player) {
private var isExplodeActive = false
private val fuseTimeTicks = metadata.int("fuseTimeTicks") ?: 30
private val explosionRadius = metadata.double("explosionRadius") ?: 8.0
private val explosionKnockbackMultiplier =
metadata.double("explosionKnockbackMultiplier") ?: 2.5
private val explosionVelocityStrength = metadata.double("explosionVelocityStrength") ?: 1.8
override fun canActivate(sendMessage: Boolean): Boolean {
if (isExplodeActive) {
if (sendMessage) {
player.sendMessage(lang.t("messages.abilities.explode.alreadyCharging"))
}
return false
}
return super.canActivate(sendMessage) && !isExplodeActive
}
override fun teardown() {
isExplodeActive = false
super.teardown()
}
override fun setup() {
listeners.add(
event<PlayerToggleSneakEvent> {
if (this@ExplodeAbility.player != player || !isExplodeActive) {
return@event
}
setCooldown()
isExplodeActive = false
resetPlayerData()
}
)
super.setup()
}
override fun activate() {
val currentTimeAtActivation = System.currentTimeMillis()
super.activate()
isExplodeActive = true
player.velocity = Vector()
player.level = 0
player.exp = 0f
var iteration = 0
runnables.add(
repeatingTask(1) {
if (iteration == fuseTimeTicks || !isExplodeActive) {
cancel()
return@repeatingTask
}
player.exp = min((iteration + 1) / fuseTimeTicks.toFloat(), 0.9999f)
val volume = 0.5f + iteration / 20f
player.world.playSound(player.location, Sound.ENTITY_CREEPER_PRIMED, volume, volume)
iteration++
}
)
jobs.add(
plugin.launch {
withContext(Dispatchers.IO) { delay(fuseTimeTicks.ticks) }
if (!isExplodeActive) {
cancel()
return@launch
}
resetPlayerData()
isExplodeActive = false
player.world.playSound(player.location, Sound.ENTITY_GENERIC_EXPLODE, 1f, 1f)
player.world.spawnParticle(Particle.EXPLOSION, player.location, 3)
player
.getNearbyEntities(explosionRadius)
.filter { it is LivingEntity && it != player }
.forEach { entity ->
val distance = player.location.distance(entity.location)
val damage =
((0.1 + 0.9 * ((explosionRadius - distance) / explosionRadius)) * 20) *
0.75
entity.doKnockback(
explosionKnockbackMultiplier,
damage,
(entity as LivingEntity).health,
player.location.toVector(),
null,
)
val damageEvent =
BrawlDamageEvent(
entity,
Damager.DamagerLivingEntity(player),
damage,
explosionKnockbackMultiplier,
BrawlDamageType.Explosion,
)
damageEvent.callEvent()
}
player.setVelocity(explosionVelocityStrength, 0.2, 1.4, true)
setCooldown(currentTimeAtActivation)
}
)
}
private fun resetPlayerData() {
player.level = 0
player.exp = 0f
}
}