Added flash roll
This commit is contained in:
@@ -233,31 +233,47 @@ class Crate(
|
||||
if (!hasKeysAndNotify(player, physicalKey = true)) {
|
||||
return
|
||||
}
|
||||
if (hasRanOutOfRewardsAndNotify(player)) {
|
||||
return
|
||||
|
||||
if (open(player, location, physicalKey)) {
|
||||
if (physicalKey) {
|
||||
usePhysicalKey(player)
|
||||
} else {
|
||||
adjustKeys(player, -1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (physicalKey) {
|
||||
usePhysicalKey(player)
|
||||
} else {
|
||||
adjustKeys(player, -1)
|
||||
}
|
||||
|
||||
open(player, location, physicalKey)
|
||||
}
|
||||
|
||||
fun open(player: Player, location: Location? = null, physicalKey: Boolean = false) {
|
||||
fun open(player: Player, location: Location? = null, physicalKey: Boolean = false): Boolean {
|
||||
/* Prevent server crashes */
|
||||
if (hasRanOutOfRewardsAndNotify(player)) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
if (player.isOpeningCrate) {
|
||||
return false
|
||||
}
|
||||
|
||||
val event = CrateOpenEvent(player, this, physicalKey, getRandomReward(player))
|
||||
Bukkit.getPluginManager().callEvent(event)
|
||||
|
||||
val roll = makeRoll(player, location ?: player.location, event.reward)
|
||||
var tick = 0
|
||||
|
||||
plugin.runnableFactory.create {
|
||||
roll.tick(tick)
|
||||
|
||||
tick++
|
||||
if (!roll.shouldContinueTicking(tick) || !player.isOpeningCrate) {
|
||||
it.cancel()
|
||||
roll.onFinish()
|
||||
player.isOpeningCrate = false
|
||||
this.handleFinish(player, roll, location ?: player.location)
|
||||
}
|
||||
}.runTaskTimer(1, 1)
|
||||
|
||||
player.isOpeningCrate = true
|
||||
roll.roll()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun previewForPlayer(player: Player) {
|
||||
@@ -316,3 +332,15 @@ class Crate(
|
||||
return Objects.hash(this.id)
|
||||
}
|
||||
}
|
||||
|
||||
private val openingCrates = mutableSetOf<UUID>()
|
||||
|
||||
var Player.isOpeningCrate: Boolean
|
||||
get() = openingCrates.contains(this.uniqueId)
|
||||
set(value) {
|
||||
if (value) {
|
||||
openingCrates.add(this.uniqueId)
|
||||
} else {
|
||||
openingCrates.remove(this.uniqueId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.willfp.ecocrates.crate.placed.particle
|
||||
|
||||
import com.willfp.eco.util.NumberUtils
|
||||
import com.willfp.ecocrates.util.lerp
|
||||
import org.bukkit.util.Vector
|
||||
import kotlin.math.PI
|
||||
|
||||
@@ -26,6 +27,3 @@ class TwirlParticleAnimation : ParticleAnimation("twirl") {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun lerp(start: Double, end: Double, fraction: Double): Double =
|
||||
(start * (1 - fraction)) + (end * fraction)
|
||||
|
||||
@@ -3,6 +3,36 @@ package com.willfp.ecocrates.crate.roll
|
||||
import com.willfp.ecocrates.reward.Reward
|
||||
|
||||
interface Roll {
|
||||
/**
|
||||
* The reward that will be given.
|
||||
*/
|
||||
val reward: Reward
|
||||
|
||||
/**
|
||||
* Called on start - once the player begins opening the crate.
|
||||
*/
|
||||
fun roll()
|
||||
|
||||
/**
|
||||
* Tick the roll.
|
||||
*
|
||||
* @param tick The current tick.
|
||||
*/
|
||||
fun tick(tick: Int)
|
||||
|
||||
/**
|
||||
* Get if the crate should continue ticking,
|
||||
* if this returns false then the roll is finished,
|
||||
* and onFinish will be called, rewards will be given, etc.
|
||||
*
|
||||
* @param tick The current tick.
|
||||
* @return If ticking should continue.
|
||||
*/
|
||||
fun shouldContinueTicking(tick: Int): Boolean
|
||||
|
||||
/**
|
||||
* Called once the crate is finished, useful if the
|
||||
* roll has an inventory as it can then be closed.
|
||||
*/
|
||||
fun onFinish()
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.willfp.eco.core.gui.slot.MaskItems
|
||||
import com.willfp.eco.core.items.Items
|
||||
import com.willfp.eco.util.NumberUtils
|
||||
import com.willfp.ecocrates.crate.Crate
|
||||
import com.willfp.ecocrates.crate.isOpeningCrate
|
||||
import com.willfp.ecocrates.reward.Reward
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Material
|
||||
@@ -33,7 +34,7 @@ class RollCSGO private constructor(
|
||||
a maximum tick value of 25 (rather than 1);
|
||||
essentially doing f(x/<scrolls>) * <max delay>.
|
||||
*/
|
||||
private val delays = (1..scrollTimes)
|
||||
private val delays = (1..scrollTimes + 1)
|
||||
.asSequence()
|
||||
.map { it / scrollTimes.toDouble() }
|
||||
.map { NumberUtils.bias(it, bias) }
|
||||
@@ -50,32 +51,7 @@ class RollCSGO private constructor(
|
||||
}
|
||||
|
||||
private var scroll = 0
|
||||
private var tick = 0
|
||||
|
||||
private val runnable = plugin.runnableFactory.create {
|
||||
val currentDelay = delays[scroll]
|
||||
|
||||
if (tick % currentDelay == 0) {
|
||||
tick = 0
|
||||
scroll++
|
||||
|
||||
gui.refresh(player)
|
||||
|
||||
player.playSound(
|
||||
player.location,
|
||||
Sound.BLOCK_STONE_BUTTON_CLICK_ON,
|
||||
1.0f,
|
||||
1.0f
|
||||
)
|
||||
|
||||
if (scroll >= scrollTimes) {
|
||||
it.cancel()
|
||||
plugin.scheduler.runLater(60) { player.closeInventory() }
|
||||
}
|
||||
}
|
||||
|
||||
tick++
|
||||
}
|
||||
private var ticksSinceLastScroll = 0
|
||||
|
||||
private val gui = menu(3) {
|
||||
setMask(
|
||||
@@ -106,21 +82,41 @@ class RollCSGO private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
onClose { event, _ ->
|
||||
handleFinish(event.player as Player)
|
||||
onClose { _, _ ->
|
||||
player.isOpeningCrate = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun roll() {
|
||||
gui.open(player)
|
||||
|
||||
// Run the scroll animation
|
||||
runnable.runTaskTimer(1, 1)
|
||||
}
|
||||
|
||||
private fun handleFinish(player: Player) {
|
||||
runnable.cancel()
|
||||
crate.handleFinish(player, this, location)
|
||||
override fun tick(tick: Int) {
|
||||
val currentDelay = delays[scroll]
|
||||
|
||||
if (ticksSinceLastScroll % currentDelay == 0) {
|
||||
ticksSinceLastScroll = 0
|
||||
scroll++
|
||||
|
||||
gui.refresh(player)
|
||||
|
||||
player.playSound(
|
||||
player.location,
|
||||
Sound.BLOCK_STONE_BUTTON_CLICK_ON,
|
||||
1.0f,
|
||||
1.0f
|
||||
)
|
||||
}
|
||||
|
||||
ticksSinceLastScroll++
|
||||
}
|
||||
|
||||
override fun shouldContinueTicking(tick: Int): Boolean {
|
||||
return scroll <= scrollTimes
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
player.closeInventory()
|
||||
}
|
||||
|
||||
object Factory : RollFactory<RollCSGO>("csgo") {
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.willfp.ecocrates.crate.roll
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.ecocrates.crate.Crate
|
||||
import com.willfp.ecocrates.reward.Reward
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.entity.Item
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.potion.PotionEffect
|
||||
import org.bukkit.potion.PotionEffectType
|
||||
import org.bukkit.util.Vector
|
||||
|
||||
class RollFlash private constructor(
|
||||
override val reward: Reward,
|
||||
private val crate: Crate,
|
||||
private val plugin: EcoPlugin,
|
||||
private val player: Player,
|
||||
private val location: Location
|
||||
) : Roll {
|
||||
private val wait = plugin.configYml.getInt("rolls.flash.wait")
|
||||
private val display = crate.getRandomRewards(player, 100, displayWeight = true)
|
||||
|
||||
private lateinit var item: Item
|
||||
|
||||
override fun roll() {
|
||||
val world = location.world!!
|
||||
|
||||
item = world.dropItem(location, display[0].display)
|
||||
item.pickupDelay = Int.MAX_VALUE
|
||||
item.setGravity(false)
|
||||
item.isCustomNameVisible = true
|
||||
|
||||
player.addPotionEffect(
|
||||
PotionEffect(
|
||||
PotionEffectType.BLINDNESS,
|
||||
wait * 2,
|
||||
1,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun tick(tick: Int) {
|
||||
if (tick % 5 == 0) {
|
||||
item.velocity = player.eyeLocation.toVector()
|
||||
.add(player.eyeLocation.direction.normalize().multiply(1.5)) // Make it stop in front of the player
|
||||
.subtract(item.location.toVector())
|
||||
.multiply(tick.toDouble() / wait)
|
||||
.multiply(0.5)
|
||||
|
||||
item.itemStack = display[tick.floorDiv(4)].display
|
||||
item.customName = display[tick.floorDiv(4)].displayName
|
||||
}
|
||||
|
||||
if (tick % 4 == 0) {
|
||||
player.playSound(
|
||||
player.location,
|
||||
Sound.BLOCK_NOTE_BLOCK_PLING,
|
||||
1f,
|
||||
0.5f
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun shouldContinueTicking(tick: Int): Boolean {
|
||||
return tick < wait
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
player.removePotionEffect(PotionEffectType.BLINDNESS)
|
||||
|
||||
player.playSound(
|
||||
player.location,
|
||||
Sound.ENTITY_FIREWORK_ROCKET_TWINKLE,
|
||||
1f,
|
||||
1f
|
||||
)
|
||||
|
||||
item.itemStack = reward.display
|
||||
item.customName = reward.displayName
|
||||
item.velocity = Vector(0, 0, 0)
|
||||
|
||||
plugin.scheduler.runLater(80) {
|
||||
item.remove()
|
||||
}
|
||||
}
|
||||
|
||||
object Factory : RollFactory<RollFlash>("flash") {
|
||||
override fun create(options: RollOptions): RollFlash =
|
||||
RollFlash(
|
||||
options.reward,
|
||||
options.crate,
|
||||
options.plugin,
|
||||
options.player,
|
||||
options.location
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ object Rolls {
|
||||
private val BY_ID = HashBiMap.create<String, RollFactory<*>>()
|
||||
|
||||
val CSGO: RollFactory<*> = RollCSGO.Factory
|
||||
val FLASH: RollFactory<*> = RollFlash.Factory
|
||||
|
||||
/**
|
||||
* Get roll factory matching id.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.willfp.ecocrates.util
|
||||
|
||||
fun lerp(start: Double, end: Double, fraction: Double): Double =
|
||||
(start * (1 - fraction)) + (end * fraction)
|
||||
@@ -46,3 +46,5 @@ rolls:
|
||||
bias: 0.65
|
||||
scrolls: 35
|
||||
max-delay: 25
|
||||
flash:
|
||||
wait: 80
|
||||
Reference in New Issue
Block a user