Added flash roll

This commit is contained in:
Auxilor
2022-03-17 12:27:25 +00:00
parent 3820e83589
commit 085b1ae234
8 changed files with 211 additions and 51 deletions

View File

@@ -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)
}
}

View File

@@ -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)

View File

@@ -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()
}

View File

@@ -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") {

View File

@@ -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
)
}
}

View File

@@ -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.

View File

@@ -0,0 +1,4 @@
package com.willfp.ecocrates.util
fun lerp(start: Double, end: Double, fraction: Double): Double =
(start * (1 - fraction)) + (end * fraction)

View File

@@ -46,3 +46,5 @@ rolls:
bias: 0.65
scrolls: 35
max-delay: 25
flash:
wait: 80