昨日烂活 —— 在 BukkitAPI 上实现眨眼的效果

发布于 2021-05-09  22 次阅读


(这个代码很久以前写的,实现真的太脏了,完全就是写出来娱乐的,所以大家也图个乐就好,仅供参考)
↓之所以要发是因为~刚才~前几天整理仓库突然看到这个觉得挺有意思就分享出来了
代码源: https://github.com/shaokeyibb/CityCore/blob/master/src/main/java/kim/minecraft/citycore/features/BlinkMe.kt

package kim.minecraft.citycore.features

import io.izzel.taboolib.internal.xseries.messages.ActionBar
import kim.minecraft.citycore.CityCore
import kim.minecraft.citycore.player.Player
import kim.minecraft.citycore.player.PlayerManager.toCCPlayer
import kim.minecraft.citycore.utils.HologramTags
import kim.minecraft.citycore.utils.storage.SettingsStorage
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerQuitEvent
import org.bukkit.potion.PotionEffect
import org.bukkit.potion.PotionEffectType
import org.bukkit.scheduler.BukkitRunnable
import kotlin.random.Random

object BlinkMe : Listener {

    private val list = mutableMapOf<Player, Action>()

    @EventHandler
    fun onRegister(e: PlayerJoinEvent) {
        if (e.player.toCCPlayer() == null) return
        list[e.player.toCCPlayer()!!] = Action(e.player.toCCPlayer()!!)
    }

    @EventHandler
    fun onUnregister(e: PlayerQuitEvent) {
        if (e.player.toCCPlayer() == null) return
        list.remove(e.player.toCCPlayer()!!)!!.also { it.unregister() }
    }

    class Action(val player: Player) {

        val blindTime = Random.nextLong(SettingsStorage.settings.getLong("HumanRaceEyesBlindMinDelay", 40), SettingsStorage.settings.getLong("HumanRaceEyesBlindMaxDelay", 120))
        val refreshTime = SettingsStorage.settings.getLong("HumanRaceEyesBlindRefreshTimeTicks", 5)

        fun unregister() {
            action.cancel()
        }

        private val action = object : BukkitRunnable() {
            override fun run() {
                val time = Random.nextInt(SettingsStorage.settings.getInt("HumanRaceEyesBlindMinDuration", 24), SettingsStorage.settings.getInt("HumanRaceEyesBlindMaxDuration", 28))
                player.getBukkitPlayer().addPotionEffect(PotionEffect(PotionEffectType.BLINDNESS, time, 255, false, false, false))
                player.getBukkitPlayer().addPotionEffect(PotionEffect(PotionEffectType.NIGHT_VISION, time, 255, false, false, false))
                HologramTags.addTags(player, "!眨眼!")
                object : BukkitRunnable() {
                    override fun run() {
                        HologramTags.removeTag(player, "!眨眼!")
                    }
                }.runTaskLater(CityCore.plugin, time.toLong())
                object : BukkitRunnable() {
                    var now = blindTime.toInt()
                    override fun run() {
                        try {
                            var i = 0
                            val string = StringBuilder()
                            while (i <= now) {
                                if ((i % refreshTime.toInt()) == 0) string.append("█")
                                i++
                            }
                            ActionBar.sendActionBar(player.getBukkitPlayer(), string.toString())
                            now--
                            if (now == 0) cancel()
                        } catch (ignored: NullPointerException) {
                            cancel()
                        }
                    }
                }.runTaskTimerAsynchronously(CityCore.plugin, 0, 1)
            }
        }

        init {
            action.runTaskTimer(CityCore.plugin, 20, blindTime)
        }
    }
}

运行原理: 每隔一定时间给予玩家失明和夜视的效果,这样玩家看起来会先啥都看不见然后逐渐恢复视野,就像眨眼一样。
虽然实现比较脏,但是玩起来还是挺有意思的,甚至挺真实2333。
(源代码上还有一个当玩家眨眼时会在头顶显示的眨眼 Tag 和一个类似 SCPSL 的剩余眨眼时间 Actionbar,可以说很真实了