✔️ Prepare plugin 1.2 version.
This commit is contained in:
@@ -3,16 +3,18 @@ plugins {
|
|||||||
id("com.gradleup.shadow") version "9.2.2"
|
id("com.gradleup.shadow") version "9.2.2"
|
||||||
id("xyz.jpenilla.run-paper") version "3.0.2"
|
id("xyz.jpenilla.run-paper") version "3.0.2"
|
||||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.19"
|
id("io.papermc.paperweight.userdev") version "2.0.0-beta.19"
|
||||||
|
id("org.jlleitschuh.gradle.ktlint") version "14.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "fr.azur"
|
group = "fr.azur"
|
||||||
version = "1.1-SNAPSHOT"
|
|
||||||
|
|
||||||
|
val version: String by project
|
||||||
val minecraftVersion: String by project
|
val minecraftVersion: String by project
|
||||||
val paperVersion: String by project
|
val paperVersion: String by project
|
||||||
val skinRestorerVersion: String by project
|
val skinRestorerVersion: String by project
|
||||||
val voiceChatVersion: String by project
|
val voiceChatVersion: String by project
|
||||||
val voiceChatApiVersion: String by project
|
val voiceChatApiVersion: String by project
|
||||||
|
val luckPermsVersion: String by project
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@@ -34,11 +36,11 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
paperweight.paperDevBundle("$minecraftVersion-$paperVersion")
|
paperweight.paperDevBundle("$minecraftVersion-$paperVersion")
|
||||||
|
|
||||||
|
compileOnly("net.skinsrestorer:skinsrestorer-api:$skinRestorerVersion")
|
||||||
implementation("net.skinsrestorer:skinsrestorer-api:$skinRestorerVersion")
|
compileOnly("de.maxhenkel.voicechat:voicechat-api:$voiceChatApiVersion")
|
||||||
implementation("de.maxhenkel.voicechat:voicechat-api:$voiceChatApiVersion")
|
|
||||||
|
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
implementation(kotlin("stdlib-jdk8"))
|
||||||
|
implementation(kotlin("reflect"))
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetJavaVersion = 21
|
val targetJavaVersion = 21
|
||||||
@@ -49,8 +51,9 @@ kotlin {
|
|||||||
tasks {
|
tasks {
|
||||||
runServer {
|
runServer {
|
||||||
downloadPlugins {
|
downloadPlugins {
|
||||||
modrinth("plasmo-voice", "bukkit-$voiceChatVersion")
|
|
||||||
modrinth("skinsrestorer", skinRestorerVersion)
|
modrinth("skinsrestorer", skinRestorerVersion)
|
||||||
|
modrinth("luckperms", luckPermsVersion)
|
||||||
|
modrinth("simple-voice-chat", voiceChatVersion)
|
||||||
}
|
}
|
||||||
minecraftVersion(minecraftVersion)
|
minecraftVersion(minecraftVersion)
|
||||||
}
|
}
|
||||||
@@ -69,8 +72,5 @@ tasks {
|
|||||||
archiveBaseName.set("tcoww")
|
archiveBaseName.set("tcoww")
|
||||||
|
|
||||||
minimize()
|
minimize()
|
||||||
|
|
||||||
// exclude("META-INF/*.kotlin_module")
|
|
||||||
// exclude("META-INF/*.version")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
version=1.2.0
|
||||||
paperVersion=R0.1-SNAPSHOT
|
paperVersion=R0.1-SNAPSHOT
|
||||||
minecraftVersion=1.21.8
|
minecraftVersion=1.21.10
|
||||||
skinRestorerVersion=15.8.2
|
skinRestorerVersion=15.9.0
|
||||||
voiceChatApiVersion=2.6.0
|
voiceChatApiVersion=2.6.0
|
||||||
voiceChatVersion=2.6.6
|
voiceChatVersion=2.6.6
|
||||||
|
luckPermsVersion=5.5.17
|
||||||
@@ -1,50 +1,64 @@
|
|||||||
package fr.azur.tcoww
|
package fr.azur.tcoww
|
||||||
|
|
||||||
import de.maxhenkel.voicechat.api.BukkitVoicechatService
|
import de.maxhenkel.voicechat.api.BukkitVoicechatService
|
||||||
import fr.azur.tcoww.events.GameEvent
|
import fr.azur.tcoww.events.GameEvents
|
||||||
|
import fr.azur.tcoww.events.PowerEvents
|
||||||
import fr.azur.tcoww.events.ToolsEvents
|
import fr.azur.tcoww.events.ToolsEvents
|
||||||
import fr.azur.tcoww.roles.*
|
import fr.azur.tcoww.events.UIEvents
|
||||||
import fr.azur.tcoww.utils.Skin
|
import fr.azur.tcoww.roles.Child
|
||||||
import fr.azur.tcoww.voicechat.VoiceChatPlugin
|
import fr.azur.tcoww.roles.FortuneTeller
|
||||||
import net.skinsrestorer.api.SkinsRestorer
|
import fr.azur.tcoww.roles.Hunter
|
||||||
import net.skinsrestorer.api.SkinsRestorerProvider
|
import fr.azur.tcoww.roles.Role
|
||||||
|
import fr.azur.tcoww.roles.Villager
|
||||||
|
import fr.azur.tcoww.roles.Werewolf
|
||||||
|
import fr.azur.tcoww.roles.Witch
|
||||||
|
import fr.azur.tcoww.utils.VoiceChatPlugin
|
||||||
|
import fr.azur.tcoww.utils.skins.Manager
|
||||||
|
import fr.azur.tcoww.utils.skins.WerewolfSkin
|
||||||
|
import org.bukkit.configuration.serialization.ConfigurationSerialization
|
||||||
import org.bukkit.plugin.java.JavaPlugin
|
import org.bukkit.plugin.java.JavaPlugin
|
||||||
|
import org.bukkit.scoreboard.Team
|
||||||
|
|
||||||
class Tcoww : JavaPlugin() {
|
object Tcoww : JavaPlugin() {
|
||||||
private lateinit var skinsRestorer: SkinsRestorer
|
|
||||||
private lateinit var skinManager: Skin
|
|
||||||
|
|
||||||
override fun onEnable() {
|
override fun onEnable() {
|
||||||
saveResource("config.yml", false)
|
ConfigurationSerialization.registerClass(WerewolfSkin::class.java)
|
||||||
|
|
||||||
saveDefaultConfig()
|
saveDefaultConfig()
|
||||||
|
|
||||||
skinsRestorer = SkinsRestorerProvider.get()
|
Manager.handle()
|
||||||
skinManager = Skin(this, skinsRestorer)
|
|
||||||
|
|
||||||
server.pluginManager.registerEvents(ToolsEvents(this), this)
|
server.pluginManager.apply {
|
||||||
server.pluginManager.registerEvents(GameEvent(this, skinManager), this)
|
registerEvents(UIEvents, this@Tcoww)
|
||||||
|
registerEvents(GameEvents, this@Tcoww)
|
||||||
|
registerEvents(PowerEvents, this@Tcoww)
|
||||||
|
registerEvents(ToolsEvents, this@Tcoww)
|
||||||
|
}
|
||||||
|
|
||||||
val vcservice = server.servicesManager.load(BukkitVoicechatService::class.java)
|
val service = server.servicesManager.load(BukkitVoicechatService::class.java)
|
||||||
vcservice?.registerPlugin(VoiceChatPlugin())
|
service?.registerPlugin(VoiceChatPlugin)
|
||||||
|
|
||||||
registerRoles()
|
registerRoles()
|
||||||
|
|
||||||
|
val mainScoreboard = server.scoreboardManager.mainScoreboard
|
||||||
|
if (mainScoreboard.getTeam("NoCollide") == null) {
|
||||||
|
val team = server.scoreboardManager.mainScoreboard.registerNewTeam("NoCollision")
|
||||||
|
team.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDisable() {
|
override fun onDisable() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reload() {
|
fun reload() {
|
||||||
this.reloadConfig()
|
this.reloadConfig()
|
||||||
skinManager.reloadSkin()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerRoles() {
|
private fun registerRoles() {
|
||||||
Role.registerRole(Villager())
|
Role.registerRole(Villager)
|
||||||
Role.registerRole(Werewolf())
|
Role.registerRole(Werewolf)
|
||||||
Role.registerRole(Child())
|
Role.registerRole(Child)
|
||||||
Role.registerRole(FortuneTeller())
|
Role.registerRole(FortuneTeller)
|
||||||
Role.registerRole(Hunter())
|
Role.registerRole(Hunter)
|
||||||
Role.registerRole(Witch())
|
Role.registerRole(Witch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
package fr.azur.tcoww
|
package fr.azur.tcoww
|
||||||
|
|
||||||
import fr.azur.tcoww.commands.Exclude
|
import fr.azur.tcoww.commands.Exclude
|
||||||
import fr.azur.tcoww.commands.Power
|
|
||||||
import fr.azur.tcoww.commands.GameCommand
|
import fr.azur.tcoww.commands.GameCommand
|
||||||
import fr.azur.tcoww.commands.ReloadCommands
|
import fr.azur.tcoww.commands.ReloadCommands
|
||||||
import fr.azur.tcoww.commands.TimeGest
|
|
||||||
import fr.azur.tcoww.commands.Tools
|
import fr.azur.tcoww.commands.Tools
|
||||||
import fr.azur.tcoww.commands.Vote
|
import fr.azur.tcoww.commands.Vote
|
||||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext
|
import io.papermc.paper.plugin.bootstrap.BootstrapContext
|
||||||
import io.papermc.paper.plugin.bootstrap.PluginBootstrap
|
import io.papermc.paper.plugin.bootstrap.PluginBootstrap
|
||||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents
|
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents
|
||||||
|
|
||||||
class TcowwBootstrap : PluginBootstrap {
|
object TcowwBootstrap : PluginBootstrap {
|
||||||
override fun bootstrap(context: BootstrapContext) {
|
override fun bootstrap(context: BootstrapContext) {
|
||||||
context.lifecycleManager.registerEventHandler(LifecycleEvents.COMMANDS) { commands ->
|
context.lifecycleManager.apply {
|
||||||
commands.registrar().register(Tools().root.build())
|
registerEventHandler(LifecycleEvents.COMMANDS) { commands ->
|
||||||
commands.registrar().register(TimeGest().root.build())
|
commands.registrar().apply {
|
||||||
commands.registrar().register(Power().root.build())
|
register(Tools.root)
|
||||||
commands.registrar().register(GameCommand().root.build())
|
register(GameCommand.root)
|
||||||
commands.registrar().register(Vote().root.build())
|
commands.registrar().register(Vote.root)
|
||||||
commands.registrar().register(ReloadCommands().root.build())
|
register(ReloadCommands.root)
|
||||||
commands.registrar().register(Exclude().root.build())
|
commands.registrar().register(Exclude.root)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,32 @@
|
|||||||
package fr.azur.tcoww.commands
|
package fr.azur.tcoww.commands
|
||||||
|
|
||||||
import com.mojang.brigadier.Command
|
import com.mojang.brigadier.Command
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder
|
|
||||||
import fr.azur.tcoww.game.Game
|
import fr.azur.tcoww.game.Game
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack
|
import fr.azur.tcoww.utils.Players.kill
|
||||||
import io.papermc.paper.command.brigadier.Commands
|
import io.papermc.paper.command.brigadier.Commands
|
||||||
import io.papermc.paper.command.brigadier.argument.ArgumentTypes
|
import io.papermc.paper.command.brigadier.argument.ArgumentTypes
|
||||||
import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver
|
import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.GameMode
|
|
||||||
|
|
||||||
class Exclude {
|
|
||||||
val root: LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("exclude")
|
|
||||||
.requires { sender ->
|
|
||||||
sender.sender.isOp
|
|
||||||
}.then(
|
|
||||||
Commands.literal("start")
|
|
||||||
.then(
|
|
||||||
Commands.argument("players", ArgumentTypes.playerProfiles()).executes { ctx ->
|
|
||||||
val targetResolver = ctx.getArgument("players", PlayerProfileListResolver::class.java)
|
|
||||||
val target = targetResolver.resolve(ctx.source).first()
|
|
||||||
val uuid = target.id
|
|
||||||
if (uuid != null) {
|
|
||||||
val player = Bukkit.getPlayer(uuid)
|
|
||||||
if (player != null) {
|
|
||||||
val game = Game.current ?: return@executes Command.SINGLE_SUCCESS
|
|
||||||
player.gameMode = GameMode.SPECTATOR
|
|
||||||
player.isInvulnerable = false
|
|
||||||
game.playersMutable.remove(player)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
object Exclude {
|
||||||
|
val root =
|
||||||
|
Commands
|
||||||
|
.literal("exclude")
|
||||||
|
.requires { sender ->
|
||||||
|
sender.sender.isOp
|
||||||
|
}.then(
|
||||||
|
Commands.argument("players", ArgumentTypes.playerProfiles()).executes { ctx ->
|
||||||
|
val targetResolver = ctx.getArgument("players", PlayerProfileListResolver::class.java)
|
||||||
|
val target = targetResolver.resolve(ctx.source).first()
|
||||||
|
val uuid = target.id
|
||||||
|
if (uuid != null) {
|
||||||
|
val player = Bukkit.getPlayer(uuid)
|
||||||
|
if (player != null) {
|
||||||
|
val game = Game.current ?: return@executes Command.SINGLE_SUCCESS
|
||||||
|
player.kill()
|
||||||
}
|
}
|
||||||
Command.SINGLE_SUCCESS
|
|
||||||
}
|
}
|
||||||
|
Command.SINGLE_SUCCESS
|
||||||
)
|
},
|
||||||
)
|
).build()
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,67 +1,90 @@
|
|||||||
package fr.azur.tcoww.commands
|
package fr.azur.tcoww.commands
|
||||||
|
|
||||||
import com.mojang.brigadier.Command
|
import com.mojang.brigadier.Command
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType
|
import com.mojang.brigadier.tree.LiteralCommandNode
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder
|
import fr.azur.tcoww.Tcoww
|
||||||
import fr.azur.tcoww.game.Game
|
import fr.azur.tcoww.game.Game
|
||||||
import fr.azur.tcoww.roles.Role
|
import fr.azur.tcoww.ui.GameConfig
|
||||||
import fr.azur.tcoww.roles.Villager
|
|
||||||
import fr.azur.tcoww.roles.Werewolf
|
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack
|
import io.papermc.paper.command.brigadier.CommandSourceStack
|
||||||
import io.papermc.paper.command.brigadier.Commands
|
import io.papermc.paper.command.brigadier.Commands
|
||||||
import io.papermc.paper.command.brigadier.argument.ArgumentTypes
|
import io.papermc.paper.dialog.Dialog
|
||||||
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver
|
import io.papermc.paper.registry.data.dialog.ActionButton
|
||||||
|
import io.papermc.paper.registry.data.dialog.DialogBase
|
||||||
|
import io.papermc.paper.registry.data.dialog.action.DialogAction
|
||||||
|
import io.papermc.paper.registry.data.dialog.type.DialogType
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.GameMode
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.bukkit.World
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.plugin.Plugin
|
||||||
|
|
||||||
|
object GameCommand {
|
||||||
class GameCommand {
|
private fun createDialog(
|
||||||
val root: LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("game")
|
plugin: Plugin,
|
||||||
.requires { sender ->
|
world: World,
|
||||||
sender.sender.isOp
|
players: Iterable<Player>,
|
||||||
}.then(
|
roles: Map<NamespacedKey, Int>,
|
||||||
Commands.literal("start")
|
): Dialog =
|
||||||
.then(
|
Dialog.create { builder ->
|
||||||
Commands.argument("players", ArgumentTypes.players()).then(
|
builder
|
||||||
Commands.argument("roles", StringArgumentType.greedyString()).suggests { ctx, builder ->
|
.empty()
|
||||||
val roleswithoutauto =
|
.base(
|
||||||
Role.registerRoles.filter { role -> role.value !is Villager && role.value !is Werewolf }
|
DialogBase
|
||||||
val rolessplit = builder.remaining.split(" ")
|
.builder(Component.text("Start the Game", NamedTextColor.GREEN))
|
||||||
val startstr = rolessplit.dropLast(1).joinToString(separator = " ")
|
.canCloseWithEscape(true)
|
||||||
|
.build(),
|
||||||
roleswithoutauto.forEach { role ->
|
).type(
|
||||||
if (role.key.toString().startsWith(rolessplit.last())) {
|
DialogType.confirmation(
|
||||||
builder.suggest("$startstr${if (startstr.isEmpty()) "" else " "}${role.key}")
|
ActionButton
|
||||||
}
|
.builder(Component.text("Start", NamedTextColor.GREEN))
|
||||||
}
|
.action(
|
||||||
if (builder.remaining != "" && !builder.remaining.endsWith(" ")) {
|
DialogAction.staticAction(
|
||||||
roleswithoutauto.forEach { role ->
|
ClickEvent.callback {
|
||||||
builder.suggest("${builder.remaining} ${role.key}")
|
Game(plugin, world, players, roles)
|
||||||
}
|
it.closeDialog()
|
||||||
}
|
},
|
||||||
builder.buildFuture()
|
),
|
||||||
}.executes { ctx ->
|
).build(),
|
||||||
val plugin = Bukkit.getPluginManager().getPlugin("tcoww")!!
|
ActionButton
|
||||||
val targetResolver = ctx.getArgument("players", PlayerSelectorArgumentResolver::class.java)
|
.builder(Component.text("Cancel", NamedTextColor.RED))
|
||||||
val targets = targetResolver.resolve(ctx.source)
|
.action(DialogAction.staticAction(ClickEvent.callback { it.closeDialog() }))
|
||||||
|
.build(),
|
||||||
val rolesstr = StringArgumentType.getString(ctx, "roles")
|
),
|
||||||
val rolessplit = rolesstr.split(" ")
|
|
||||||
|
|
||||||
val roles = rolessplit.map { str ->
|
|
||||||
Role.registerRoles[NamespacedKey.fromString(str)]
|
|
||||||
}
|
|
||||||
val correctrole = roles.filterNotNull()
|
|
||||||
|
|
||||||
Game(plugin, ctx.source.location.world, targets, correctrole)
|
|
||||||
Command.SINGLE_SUCCESS
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
).then(
|
}
|
||||||
Commands.literal("stop").executes { ctx ->
|
|
||||||
Game.current?.stopGame(true)
|
val root: LiteralCommandNode<CommandSourceStack> =
|
||||||
Command.SINGLE_SUCCESS
|
Commands
|
||||||
}
|
.literal("game")
|
||||||
)
|
.requires { sender ->
|
||||||
}
|
sender.sender.isOp
|
||||||
|
}.then(
|
||||||
|
Commands
|
||||||
|
.literal("start")
|
||||||
|
.executes { ctx ->
|
||||||
|
val executor = ctx.source.executor ?: ctx.source.sender
|
||||||
|
if (executor is Player) {
|
||||||
|
val players =
|
||||||
|
Bukkit
|
||||||
|
.getOnlinePlayers()
|
||||||
|
.filter { it.gameMode == GameMode.ADVENTURE || it.gameMode == GameMode.SURVIVAL }
|
||||||
|
val menu = GameConfig(players.size)
|
||||||
|
executor.openInventory(menu.inventory)
|
||||||
|
menu.future.thenAccept {
|
||||||
|
val dialog = createDialog(Tcoww, executor.world, players, it)
|
||||||
|
executor.showDialog(dialog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Command.SINGLE_SUCCESS
|
||||||
|
},
|
||||||
|
).then(
|
||||||
|
Commands.literal("stop").executes { ctx ->
|
||||||
|
Game.current?.stopGame(true)
|
||||||
|
Command.SINGLE_SUCCESS
|
||||||
|
},
|
||||||
|
).build()
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,156 +0,0 @@
|
|||||||
package fr.azur.tcoww.commands
|
|
||||||
|
|
||||||
import com.mojang.brigadier.Command
|
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder
|
|
||||||
import fr.azur.tcoww.game.Game
|
|
||||||
import fr.azur.tcoww.roles.FortuneTeller
|
|
||||||
import fr.azur.tcoww.roles.Role
|
|
||||||
import fr.azur.tcoww.roles.Witch
|
|
||||||
import fr.azur.tcoww.utils.Stockage
|
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack
|
|
||||||
import io.papermc.paper.command.brigadier.Commands
|
|
||||||
import io.papermc.paper.command.brigadier.argument.ArgumentTypes
|
|
||||||
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver
|
|
||||||
import net.kyori.adventure.text.Component
|
|
||||||
import net.kyori.adventure.text.event.HoverEvent
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
|
||||||
import org.bukkit.Bukkit
|
|
||||||
import org.bukkit.NamespacedKey
|
|
||||||
import org.bukkit.entity.Player
|
|
||||||
import org.bukkit.persistence.PersistentDataType
|
|
||||||
import org.bukkit.potion.PotionEffect
|
|
||||||
import org.bukkit.potion.PotionEffectType
|
|
||||||
|
|
||||||
class Power {
|
|
||||||
val root: LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("power")
|
|
||||||
.requires { ctx -> ctx.sender as? Player != null && Role.getRole(ctx.sender as Player)?.hasPowerCommand == true }
|
|
||||||
.then(
|
|
||||||
Commands.literal("kill")
|
|
||||||
.requires { ctx ->
|
|
||||||
val player = ctx.executor as? Player ?: return@requires false
|
|
||||||
val role = Role.getRole(player)
|
|
||||||
(role is Witch && player.hasPowerItem(1))
|
|
||||||
}
|
|
||||||
.then(
|
|
||||||
Commands.argument("target", ArgumentTypes.player())
|
|
||||||
.suggests { _, builder ->
|
|
||||||
Game.current?.playersMutable?.forEach { builder.suggest(it.name) }
|
|
||||||
builder.buildFuture()
|
|
||||||
}
|
|
||||||
.executes { ctx ->
|
|
||||||
val target = ctx.getTargetPlayer("target") ?: return@executes 0
|
|
||||||
val player = ctx.source.getPlayer() ?: return@executes 0
|
|
||||||
if (Game.current?.playersMutable?.contains(target) == true) {
|
|
||||||
target.addPotionEffect(PotionEffect(PotionEffectType.WITHER, 600, 4))
|
|
||||||
player.removePowerItem(1)
|
|
||||||
}
|
|
||||||
Command.SINGLE_SUCCESS
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.then(
|
|
||||||
Commands.literal("save")
|
|
||||||
.requires { ctx ->
|
|
||||||
val player = ctx.executor as? Player ?: return@requires false
|
|
||||||
val role = Role.getRole(player)
|
|
||||||
role is Witch && player.hasPowerItem(2)
|
|
||||||
}
|
|
||||||
.then(
|
|
||||||
Commands.argument("target", ArgumentTypes.player())
|
|
||||||
.executes { ctx ->
|
|
||||||
val target = ctx.getTargetPlayer("target") ?: return@executes 0
|
|
||||||
val player = ctx.source.getPlayer() ?: return@executes 0
|
|
||||||
if (Game.current?.playersMutable?.contains(target) == true &&
|
|
||||||
target.persistentDataContainer.get(
|
|
||||||
NamespacedKey("tcoww", "dead"),
|
|
||||||
PersistentDataType.BOOLEAN
|
|
||||||
) == true
|
|
||||||
) {
|
|
||||||
target.persistentDataContainer.set(
|
|
||||||
NamespacedKey("tcoww", "dead"),
|
|
||||||
PersistentDataType.BOOLEAN,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
Stockage.backLocation[target.uniqueId]?.let { target.teleport(it) }
|
|
||||||
target.isInvulnerable = false
|
|
||||||
target.sendMessage(Component.text("Vous avez été résucité.").color(NamedTextColor.AQUA))
|
|
||||||
player.sendMessage(
|
|
||||||
Component.text("Vous avez résuciter ").color(NamedTextColor.AQUA)
|
|
||||||
.append(player.displayName())
|
|
||||||
)
|
|
||||||
player.removePowerItem(2)
|
|
||||||
}
|
|
||||||
Command.SINGLE_SUCCESS
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.then(
|
|
||||||
Commands.literal("view")
|
|
||||||
.requires { ctx ->
|
|
||||||
val player = ctx.executor as? Player ?: return@requires false
|
|
||||||
val role = Role.getRole(player)
|
|
||||||
role is FortuneTeller && player.hasPowerItem(4)
|
|
||||||
}
|
|
||||||
.then(
|
|
||||||
Commands.argument("target", ArgumentTypes.player())
|
|
||||||
.suggests { _, builder ->
|
|
||||||
Game.current?.playersMutable?.forEach { builder.suggest(it.name) }
|
|
||||||
builder.buildFuture()
|
|
||||||
}
|
|
||||||
.executes { ctx ->
|
|
||||||
val target = ctx.getTargetPlayer("target") ?: return@executes 0
|
|
||||||
val player = ctx.source.getPlayer() ?: return@executes 0
|
|
||||||
val plugin = Bukkit.getPluginManager().getPlugin("tcoww") ?: return@executes 0
|
|
||||||
if (Game.current?.playersMutable?.contains(target) == true) {
|
|
||||||
val item = player.getPowerItem(4) ?: return@executes 0
|
|
||||||
|
|
||||||
val timeGestion = Game.current!!.timeGestion
|
|
||||||
val cooldown =
|
|
||||||
((timeGestion.dayDuration + timeGestion.voteDuration + timeGestion.nightDuration + timeGestion.crepuscularDuration - 30) * 2) * 20
|
|
||||||
|
|
||||||
val cloneditem = item.clone()
|
|
||||||
|
|
||||||
player.inventory.remove(item)
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, Runnable {
|
|
||||||
player.inventory.addItem(cloneditem)
|
|
||||||
}, cooldown.toLong())
|
|
||||||
|
|
||||||
val targetrole = Role.getRole(target)
|
|
||||||
|
|
||||||
player.sendMessage(
|
|
||||||
target.displayName().append(Component.text(" est "))
|
|
||||||
.append(
|
|
||||||
(targetrole?.displayName ?: Component.text("Inconnu").hoverEvent(
|
|
||||||
HoverEvent.showText(
|
|
||||||
targetrole?.description ?: Component.empty()
|
|
||||||
)
|
|
||||||
))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Command.SINGLE_SUCCESS
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun CommandSourceStack.getPlayer(): Player? = (this.executor ?: this.sender) as? Player
|
|
||||||
|
|
||||||
private fun Player.hasPowerItem(id: Int): Boolean = this.inventory.any {
|
|
||||||
it?.persistentDataContainer?.get(NamespacedKey("tcoww", "power"), PersistentDataType.INTEGER) == id
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Player.getPowerItem(id: Int) = this.inventory.firstOrNull {
|
|
||||||
it?.persistentDataContainer?.get(NamespacedKey("tcoww", "power"), PersistentDataType.INTEGER) == id
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Player.removePowerItem(id: Int) {
|
|
||||||
val item = getPowerItem(id) ?: return
|
|
||||||
this.inventory.remove(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun com.mojang.brigadier.context.CommandContext<CommandSourceStack>.getTargetPlayer(name: String): Player? {
|
|
||||||
val resolver = this.getArgument(name, PlayerSelectorArgumentResolver::class.java)
|
|
||||||
return resolver.resolve(this.source).firstOrNull()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,21 @@
|
|||||||
package fr.azur.tcoww.commands
|
package fr.azur.tcoww.commands
|
||||||
|
|
||||||
import com.mojang.brigadier.Command
|
import com.mojang.brigadier.Command
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder
|
import com.mojang.brigadier.tree.LiteralCommandNode
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack
|
import io.papermc.paper.command.brigadier.CommandSourceStack
|
||||||
import io.papermc.paper.command.brigadier.Commands
|
import io.papermc.paper.command.brigadier.Commands
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class ReloadCommands {
|
object ReloadCommands {
|
||||||
val root: LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("reloadcommands").executes { ctx ->
|
val root: LiteralCommandNode<CommandSourceStack> =
|
||||||
val sender = ctx.source.sender as? Player
|
Commands
|
||||||
sender?.updateCommands()
|
.literal("reload-commands")
|
||||||
sender?.sendMessage(Component.text("Commands rechargés !").color(NamedTextColor.GOLD))
|
.executes { ctx ->
|
||||||
Command.SINGLE_SUCCESS
|
val sender = ctx.source.sender as? Player
|
||||||
}
|
sender?.updateCommands()
|
||||||
}
|
sender?.sendMessage(Component.text("Commands rechargés !", NamedTextColor.GOLD))
|
||||||
|
Command.SINGLE_SUCCESS
|
||||||
|
}.build()
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
package fr.azur.tcoww.commands
|
|
||||||
|
|
||||||
import com.mojang.brigadier.Command
|
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder
|
|
||||||
import fr.azur.tcoww.game.TimeGestion
|
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack
|
|
||||||
import io.papermc.paper.command.brigadier.Commands
|
|
||||||
import org.bukkit.Bukkit
|
|
||||||
import org.bukkit.plugin.Plugin
|
|
||||||
import org.bukkit.scheduler.BukkitTask
|
|
||||||
|
|
||||||
class TimeGest {
|
|
||||||
var timeGestion: TimeGestion? = null
|
|
||||||
var sheduler: BukkitTask? = null
|
|
||||||
var plugin: Plugin? = null
|
|
||||||
|
|
||||||
private fun kill() {
|
|
||||||
sheduler?.cancel()
|
|
||||||
sheduler = null
|
|
||||||
timeGestion = null
|
|
||||||
}
|
|
||||||
|
|
||||||
val root: LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("timegest")
|
|
||||||
.requires { sender ->
|
|
||||||
sender.sender.isOp
|
|
||||||
}.then(
|
|
||||||
Commands.literal("start").executes { ctx ->
|
|
||||||
if (plugin == null) plugin = Bukkit.getPluginManager().getPlugin("tcoww")!!
|
|
||||||
val executor = ctx.source.executor
|
|
||||||
if (executor == null) throw Error("No executor !")
|
|
||||||
if (timeGestion != null || sheduler != null) kill()
|
|
||||||
timeGestion = TimeGestion(plugin!!, executor.world)
|
|
||||||
sheduler = Bukkit.getScheduler().runTaskTimer(plugin!!, Runnable {
|
|
||||||
timeGestion!!.tick()
|
|
||||||
}, 0L, 1L)
|
|
||||||
Command.SINGLE_SUCCESS
|
|
||||||
}
|
|
||||||
).then(
|
|
||||||
Commands.literal("kill").executes {
|
|
||||||
kill()
|
|
||||||
Command.SINGLE_SUCCESS
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ package fr.azur.tcoww.commands
|
|||||||
import com.mojang.brigadier.Command
|
import com.mojang.brigadier.Command
|
||||||
import com.mojang.brigadier.arguments.IntegerArgumentType
|
import com.mojang.brigadier.arguments.IntegerArgumentType
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType
|
import com.mojang.brigadier.arguments.StringArgumentType
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder
|
import com.mojang.brigadier.tree.LiteralCommandNode
|
||||||
import fr.azur.tcoww.Tcoww
|
import fr.azur.tcoww.Tcoww
|
||||||
import fr.azur.tcoww.items.CustomItems
|
import fr.azur.tcoww.items.CustomItems
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack
|
import io.papermc.paper.command.brigadier.CommandSourceStack
|
||||||
@@ -16,131 +16,139 @@ import org.bukkit.Bukkit
|
|||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class Tools {
|
object Tools {
|
||||||
val root: LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("tools")
|
val root: LiteralCommandNode<CommandSourceStack> =
|
||||||
.requires { sender ->
|
Commands
|
||||||
sender.sender.isOp
|
.literal("tools")
|
||||||
}.then(
|
.requires { sender ->
|
||||||
Commands.literal("location")
|
sender.sender.isOp
|
||||||
.then(
|
}.then(
|
||||||
Commands.literal("bed").executes { ctx ->
|
Commands
|
||||||
val player = ctx.source.executor as Player
|
.literal("location")
|
||||||
player.inventory.addItem(CustomItems.BedLocTool.item)
|
.then(
|
||||||
Command.SINGLE_SUCCESS
|
Commands
|
||||||
}.then(
|
.literal("bed")
|
||||||
Commands.literal("get").executes { ctx ->
|
.executes { ctx ->
|
||||||
ctx.source.sender.sendMessage(sendBed())
|
val player = ctx.source.executor as Player
|
||||||
Command.SINGLE_SUCCESS
|
player.inventory.addItem(CustomItems.BedLocTool.item)
|
||||||
}
|
Command.SINGLE_SUCCESS
|
||||||
).then(
|
}.then(
|
||||||
Commands.literal("remove").then(
|
Commands.literal("get").executes { ctx ->
|
||||||
Commands.argument("index", IntegerArgumentType.integer(0))
|
|
||||||
.executes { ctx ->
|
|
||||||
val plugin = Bukkit.getPluginManager().getPlugin("tcoww") ?: return@executes 0
|
|
||||||
val index = IntegerArgumentType.getInteger(ctx, "index")
|
|
||||||
val list = plugin.config.getMapList("bedLocation")
|
|
||||||
|
|
||||||
plugin.config.set("bedLocation", list.minus(list[index]))
|
|
||||||
plugin.saveConfig()
|
|
||||||
|
|
||||||
ctx.source.sender.sendMessage(sendBed())
|
ctx.source.sender.sendMessage(sendBed())
|
||||||
|
|
||||||
Command.SINGLE_SUCCESS
|
Command.SINGLE_SUCCESS
|
||||||
}
|
},
|
||||||
))
|
).then(
|
||||||
).then(
|
Commands.literal("remove").then(
|
||||||
Commands.literal("spawn").executes { ctx ->
|
Commands
|
||||||
val player = ctx.source.executor as Player
|
.argument("index", IntegerArgumentType.integer(0))
|
||||||
player.inventory.addItem(CustomItems.SpawnLocTool.item)
|
.executes { ctx ->
|
||||||
Command.SINGLE_SUCCESS
|
val plugin = Bukkit.getPluginManager().getPlugin("tcoww") ?: return@executes 0
|
||||||
}
|
val index = IntegerArgumentType.getInteger(ctx, "index")
|
||||||
).then(
|
val list =
|
||||||
Commands.literal("lobby").executes { ctx ->
|
plugin.config
|
||||||
val player = ctx.source.executor as Player
|
.getList("bed-locations")
|
||||||
player.inventory.addItem(CustomItems.LobbyLocTool.item)
|
.orEmpty()
|
||||||
Command.SINGLE_SUCCESS
|
.mapNotNull { it as? Location }
|
||||||
}
|
|
||||||
)
|
plugin.config.set("bed-locations", list.drop(index))
|
||||||
).then(
|
plugin.saveConfig()
|
||||||
Commands.literal("reload").executes {
|
|
||||||
val plugin = Bukkit.getPluginManager().getPlugin("tcoww") as Tcoww
|
ctx.source.sender.sendMessage(sendBed())
|
||||||
plugin.reload()
|
|
||||||
Command.SINGLE_SUCCESS
|
Command.SINGLE_SUCCESS
|
||||||
}
|
},
|
||||||
).then(
|
),
|
||||||
Commands.literal("customitem").then(
|
),
|
||||||
Commands.argument("item", StringArgumentType.greedyString())
|
).then(
|
||||||
.suggests { _, builder ->
|
Commands.literal("spawn").executes { ctx ->
|
||||||
CustomItems.entries.forEach {
|
val player = ctx.source.executor as Player
|
||||||
builder.suggest(it.name)
|
player.inventory.addItem(CustomItems.SpawnLocTool.item)
|
||||||
}
|
Command.SINGLE_SUCCESS
|
||||||
builder.buildFuture()
|
},
|
||||||
}
|
).then(
|
||||||
.executes { ctx ->
|
Commands.literal("lobby").executes { ctx ->
|
||||||
val itemName = StringArgumentType.getString(ctx, "item")
|
val player = ctx.source.executor as Player
|
||||||
val item = CustomItems.valueOf(itemName).item
|
player.inventory.addItem(CustomItems.LobbyLocTool.item)
|
||||||
val exe = ctx.source.executor
|
Command.SINGLE_SUCCESS
|
||||||
if (exe is Player) {
|
},
|
||||||
exe.inventory.addItem(item)
|
),
|
||||||
}
|
).then(
|
||||||
Command.SINGLE_SUCCESS
|
Commands.literal("reload").executes {
|
||||||
}
|
val plugin = Bukkit.getPluginManager().getPlugin("tcoww") as Tcoww
|
||||||
)
|
plugin.reload()
|
||||||
)
|
Command.SINGLE_SUCCESS
|
||||||
|
},
|
||||||
|
).then(
|
||||||
|
Commands.literal("customitem").then(
|
||||||
|
Commands
|
||||||
|
.argument("item", StringArgumentType.greedyString())
|
||||||
|
.suggests { _, builder ->
|
||||||
|
CustomItems.entries.forEach {
|
||||||
|
builder.suggest(it.name)
|
||||||
|
}
|
||||||
|
builder.buildFuture()
|
||||||
|
}.executes { ctx ->
|
||||||
|
val itemName = StringArgumentType.getString(ctx, "item")
|
||||||
|
val item = CustomItems.valueOf(itemName).item
|
||||||
|
val exe = ctx.source.executor
|
||||||
|
if (exe is Player) {
|
||||||
|
exe.inventory.addItem(item)
|
||||||
|
}
|
||||||
|
Command.SINGLE_SUCCESS
|
||||||
|
},
|
||||||
|
),
|
||||||
|
).build()
|
||||||
|
|
||||||
fun sendBed(): Component {
|
fun sendBed(): Component {
|
||||||
val plugin = Bukkit.getPluginManager().getPlugin("tcoww") ?: return Component.empty()
|
val plugin = Bukkit.getPluginManager().getPlugin("tcoww") ?: return Component.empty()
|
||||||
val bedlist = plugin.config.getMapList("bedLocation")
|
val bedList =
|
||||||
val bedLocationComponent = bedlist.map {
|
plugin.config
|
||||||
if (it as? Map<String, Object> != null) {
|
.getList("bed-locations")
|
||||||
val loc = Location.deserialize(it as Map<String, Object>)
|
.orEmpty()
|
||||||
Component.text("[${loc.x}, ${loc.y}, ${loc.z}] ")
|
val bedLocationComponent =
|
||||||
.color(NamedTextColor.LIGHT_PURPLE)
|
bedList.mapIndexed { index, element ->
|
||||||
.append(
|
if (element is Location) {
|
||||||
Component.text("teleport")
|
Component
|
||||||
.clickEvent(
|
.text("[${element.x}, ${element.y}, ${element.z}] ")
|
||||||
ClickEvent.runCommand("/minecraft:tp ${loc.x.toInt()} ${loc.y.toInt()} ${loc.z.toInt()}")
|
|
||||||
)
|
|
||||||
.color(NamedTextColor.LIGHT_PURPLE)
|
|
||||||
.decorate(TextDecoration.UNDERLINED)
|
|
||||||
)
|
|
||||||
.appendSpace()
|
|
||||||
.append(
|
|
||||||
Component.text("remove")
|
|
||||||
.clickEvent(
|
|
||||||
ClickEvent.runCommand(
|
|
||||||
"/tcoww:tools location bed remove ${
|
|
||||||
bedlist.indexOf(
|
|
||||||
it
|
|
||||||
)
|
|
||||||
}"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.color(NamedTextColor.LIGHT_PURPLE)
|
|
||||||
.decorate(TextDecoration.UNDERLINED)
|
|
||||||
)
|
|
||||||
.appendNewline()
|
|
||||||
} else Component.text("[unkown location] ")
|
|
||||||
.color(NamedTextColor.LIGHT_PURPLE)
|
|
||||||
.append(
|
|
||||||
Component.text("remove")
|
|
||||||
.clickEvent(
|
|
||||||
ClickEvent.runCommand(
|
|
||||||
"/tcoww:tools location bed remove ${
|
|
||||||
bedlist.indexOf(
|
|
||||||
it
|
|
||||||
)
|
|
||||||
}"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.color(NamedTextColor.LIGHT_PURPLE)
|
.color(NamedTextColor.LIGHT_PURPLE)
|
||||||
.decorate(TextDecoration.UNDERLINED)
|
.append(
|
||||||
)
|
Component
|
||||||
.appendNewline()
|
.text("teleport")
|
||||||
}
|
.clickEvent(
|
||||||
return Component.text("Current bed locations :")
|
ClickEvent.runCommand("/minecraft:tp ${element.x} ${element.y} ${element.z}"),
|
||||||
|
).color(NamedTextColor.LIGHT_PURPLE)
|
||||||
|
.decorate(TextDecoration.UNDERLINED),
|
||||||
|
).appendSpace()
|
||||||
|
.append(
|
||||||
|
Component
|
||||||
|
.text("remove")
|
||||||
|
.clickEvent(
|
||||||
|
ClickEvent.runCommand(
|
||||||
|
"/tcoww:tools location bed remove $index",
|
||||||
|
),
|
||||||
|
).color(NamedTextColor.LIGHT_PURPLE)
|
||||||
|
.decorate(TextDecoration.UNDERLINED),
|
||||||
|
).appendNewline()
|
||||||
|
} else {
|
||||||
|
Component
|
||||||
|
.text("[unkown location] ")
|
||||||
|
.color(NamedTextColor.LIGHT_PURPLE)
|
||||||
|
.append(
|
||||||
|
Component
|
||||||
|
.text("remove")
|
||||||
|
.clickEvent(
|
||||||
|
ClickEvent.runCommand(
|
||||||
|
"/tcoww:tools location bed remove $index",
|
||||||
|
),
|
||||||
|
).color(NamedTextColor.LIGHT_PURPLE)
|
||||||
|
.decorate(TextDecoration.UNDERLINED),
|
||||||
|
).appendNewline()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Component
|
||||||
|
.text("Current bed locations :")
|
||||||
.color(NamedTextColor.DARK_PURPLE)
|
.color(NamedTextColor.DARK_PURPLE)
|
||||||
.appendNewline()
|
.appendNewline()
|
||||||
.append(bedLocationComponent)
|
.append(bedLocationComponent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,53 @@
|
|||||||
package fr.azur.tcoww.commands
|
package fr.azur.tcoww.commands
|
||||||
|
|
||||||
import com.mojang.brigadier.Command
|
import com.mojang.brigadier.Command
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder
|
import com.mojang.brigadier.tree.LiteralCommandNode
|
||||||
import fr.azur.tcoww.game.Game
|
import fr.azur.tcoww.game.Game
|
||||||
import fr.azur.tcoww.game.Phase
|
import fr.azur.tcoww.game.NightLightCycle
|
||||||
import fr.azur.tcoww.utils.Stockage
|
import fr.azur.tcoww.ui.PlayerSelectMenu
|
||||||
import io.papermc.paper.command.brigadier.CommandSourceStack
|
import io.papermc.paper.command.brigadier.CommandSourceStack
|
||||||
import io.papermc.paper.command.brigadier.Commands
|
import io.papermc.paper.command.brigadier.Commands
|
||||||
import io.papermc.paper.command.brigadier.argument.ArgumentTypes
|
import io.papermc.paper.command.brigadier.argument.ArgumentTypes
|
||||||
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver
|
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
class Vote {
|
object Vote {
|
||||||
val root: LiteralArgumentBuilder<CommandSourceStack> = Commands.literal("vote").then(
|
var vote = mutableMapOf<UUID, UUID>()
|
||||||
Commands.argument("target", ArgumentTypes.player())
|
|
||||||
.requires { ctx ->
|
val root: LiteralCommandNode<CommandSourceStack> =
|
||||||
Game.current?.timeGestion?.phase == Phase.VOTE && Game.current!!.playersMutable.contains(ctx.sender)
|
Commands
|
||||||
}.suggests { ctx, builder ->
|
.literal("vote")
|
||||||
Game.current?.playersMutable?.forEach { player -> builder.suggest(player.name) }
|
.then(
|
||||||
builder.buildFuture()
|
Commands
|
||||||
}.executes { ctx ->
|
.argument("target", ArgumentTypes.player())
|
||||||
val targetResolver = ctx.getArgument("target", PlayerSelectorArgumentResolver::class.java)
|
.requires { ctx ->
|
||||||
val target = targetResolver.resolve(ctx.source).first()
|
Game.current?.timeGestion?.phase == NightLightCycle.Phase.VOTE &&
|
||||||
|
Game.current!!.remainingPlayer.contains(ctx.sender)
|
||||||
|
}.suggests { _, builder ->
|
||||||
|
Game.current?.remainingPlayer?.forEach { player -> builder.suggest(player.name) }
|
||||||
|
builder.buildFuture()
|
||||||
|
}.executes { ctx ->
|
||||||
|
val targetResolver = ctx.getArgument("target", PlayerSelectorArgumentResolver::class.java)
|
||||||
|
val target = targetResolver.resolve(ctx.source).first()
|
||||||
|
val player = (ctx.source.executor ?: ctx.source.sender as Player) as Player
|
||||||
|
if (Game.current?.remainingPlayer?.contains(target) ?: false) {
|
||||||
|
vote[player.uniqueId] = target.uniqueId
|
||||||
|
}
|
||||||
|
Command.SINGLE_SUCCESS
|
||||||
|
},
|
||||||
|
).executes { ctx ->
|
||||||
|
val current = Game.current ?: return@executes Command.SINGLE_SUCCESS
|
||||||
val player = (ctx.source.executor ?: ctx.source.sender as Player) as Player
|
val player = (ctx.source.executor ?: ctx.source.sender as Player) as Player
|
||||||
if (Game.current?.playersMutable?.contains(target) ?: false) {
|
|
||||||
Stockage.vote[player.uniqueId] = target.uniqueId
|
val menu = PlayerSelectMenu(current.remainingPlayer)
|
||||||
|
player.openInventory(menu.inventory)
|
||||||
|
|
||||||
|
menu.future.whenComplete { selectedPlayer, _ ->
|
||||||
|
val target = selectedPlayer ?: return@whenComplete
|
||||||
|
vote[player.uniqueId] = target.uniqueId
|
||||||
}
|
}
|
||||||
|
|
||||||
Command.SINGLE_SUCCESS
|
Command.SINGLE_SUCCESS
|
||||||
}
|
}.build()
|
||||||
)
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,421 +0,0 @@
|
|||||||
package fr.azur.tcoww.events
|
|
||||||
|
|
||||||
import fr.azur.tcoww.game.Game
|
|
||||||
import fr.azur.tcoww.game.Phase
|
|
||||||
import fr.azur.tcoww.items.CustomItems
|
|
||||||
import fr.azur.tcoww.roles.Child
|
|
||||||
import fr.azur.tcoww.roles.Role
|
|
||||||
import fr.azur.tcoww.roles.Witch
|
|
||||||
import fr.azur.tcoww.utils.BedGestion
|
|
||||||
import fr.azur.tcoww.utils.Skin
|
|
||||||
import fr.azur.tcoww.utils.Stockage
|
|
||||||
import net.kyori.adventure.text.Component
|
|
||||||
import net.kyori.adventure.text.event.ClickEvent
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
|
||||||
import net.kyori.adventure.text.format.TextDecoration
|
|
||||||
import net.kyori.adventure.title.Title
|
|
||||||
import org.bukkit.*
|
|
||||||
import org.bukkit.attribute.Attribute
|
|
||||||
import org.bukkit.attribute.AttributeModifier
|
|
||||||
import org.bukkit.entity.EntityType
|
|
||||||
import org.bukkit.entity.ItemDisplay
|
|
||||||
import org.bukkit.entity.Player
|
|
||||||
import org.bukkit.event.EventHandler
|
|
||||||
import org.bukkit.event.EventPriority
|
|
||||||
import org.bukkit.event.Listener
|
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent
|
|
||||||
import org.bukkit.event.entity.PlayerDeathEvent
|
|
||||||
import org.bukkit.event.inventory.InventoryMoveItemEvent
|
|
||||||
import org.bukkit.event.player.*
|
|
||||||
import org.bukkit.inventory.ItemStack
|
|
||||||
import org.bukkit.inventory.meta.SkullMeta
|
|
||||||
import org.bukkit.persistence.PersistentDataType
|
|
||||||
import org.bukkit.plugin.Plugin
|
|
||||||
import org.bukkit.potion.PotionEffect
|
|
||||||
import org.bukkit.potion.PotionEffectType
|
|
||||||
import java.time.Duration
|
|
||||||
|
|
||||||
class GameEvent(val plugin: Plugin, val skinUtils: Skin) : Listener {
|
|
||||||
@EventHandler
|
|
||||||
fun phaseChange(event: TimePhaseChangeEvent) {
|
|
||||||
Game.current?.playersMutable?.forEach { it.updateCommands() }
|
|
||||||
when (event.newPhase) {
|
|
||||||
Phase.DAY -> {
|
|
||||||
event.world.players.forEach { player ->
|
|
||||||
player.sendMessage(Component.text("Le jour se lève.").color(NamedTextColor.GOLD))
|
|
||||||
player.clearActivePotionEffects()
|
|
||||||
player.persistentDataContainer.set(
|
|
||||||
NamespacedKey("tcoww", "insomie"),
|
|
||||||
PersistentDataType.BOOLEAN,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
if (player.role?.lg == true) {
|
|
||||||
player.inventory.forEach {
|
|
||||||
if (it != null && it.persistentDataContainer.get(
|
|
||||||
NamespacedKey("tcoww", "power"),
|
|
||||||
PersistentDataType.INTEGER
|
|
||||||
) == 3
|
|
||||||
) {
|
|
||||||
player.inventory.remove(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player.isTransformed()) {
|
|
||||||
player.tfHuman()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Phase.VOTE -> {
|
|
||||||
event.world.players.forEach { player ->
|
|
||||||
player.sendMessage(
|
|
||||||
Component.text("Le jour se couche, ce soir un vote est organisé.")
|
|
||||||
.color(NamedTextColor.DARK_AQUA)
|
|
||||||
.appendNewline()
|
|
||||||
.append(
|
|
||||||
Component.text("Faite /vote <pseudo> pour voter.")
|
|
||||||
.color(NamedTextColor.AQUA)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Phase.NIGHT -> {
|
|
||||||
if (Stockage.vote.isNotEmpty()) {
|
|
||||||
val voteMap = Stockage.vote.values.groupingBy { it }.eachCount()
|
|
||||||
val mostVoted = voteMap.maxByOrNull { it.value }?.key
|
|
||||||
mostVoted?.let { uuid ->
|
|
||||||
Bukkit.getPlayer(uuid)?.let { votedPlayer ->
|
|
||||||
votedPlayer.fireTicks = 1200
|
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, Runnable {
|
|
||||||
votedPlayer.health = 0.0
|
|
||||||
}, 60)
|
|
||||||
Game.current?.playersMutable?.forEach {
|
|
||||||
it.sendMessage(
|
|
||||||
Component.text("${votedPlayer.name} a reçu le plus de vote.")
|
|
||||||
.color(NamedTextColor.RED)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Stockage.vote.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
Game.current?.wwcankill = true
|
|
||||||
event.world.players.forEach { player ->
|
|
||||||
player.sendMessage(
|
|
||||||
Component.text("La lune se léve et les loups sont de sortie. Vous devriez dormir.")
|
|
||||||
.color(NamedTextColor.DARK_PURPLE)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (player.role?.lg ?: false) {
|
|
||||||
player.sendMessage(
|
|
||||||
Component.text("Vous pouvez vous transformer.").color(NamedTextColor.DARK_PURPLE)
|
|
||||||
)
|
|
||||||
player.inventory.addItem(CustomItems.WereWolfTransformItem.item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, Runnable {
|
|
||||||
val openBed = plugin.config.getMapList("bedLocation").mapNotNull {
|
|
||||||
if (it as? Map<String, Object> != null) Location.deserialize(it as Map<String, Object>) else null
|
|
||||||
}.filter { !BedGestion.isOcupied(it.block) }.toMutableList()
|
|
||||||
Game.current?.playersMutable?.forEach { player ->
|
|
||||||
if (!player.isSleeping && !player.persistentDataContainer.getOrDefault(
|
|
||||||
NamespacedKey("tcoww", "dead"),
|
|
||||||
PersistentDataType.BOOLEAN,
|
|
||||||
false
|
|
||||||
) && !player.isTransformed()
|
|
||||||
) {
|
|
||||||
val loc = openBed.removeFirst()
|
|
||||||
player.sleep(loc, true)
|
|
||||||
|
|
||||||
val role = player.role
|
|
||||||
if (role is Child || role?.lg == true) {
|
|
||||||
player.sendMessage(
|
|
||||||
Component.text(
|
|
||||||
"Tout le monde est couché. Vous pouvez vous lever.",
|
|
||||||
NamedTextColor.AQUA
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, plugin.config.getLong("playerSleep"))
|
|
||||||
}
|
|
||||||
|
|
||||||
Phase.CREPUSCULAR -> {
|
|
||||||
val current = Game.current ?: return
|
|
||||||
val deadPlayers = current.playersMutable.filter {
|
|
||||||
it.persistentDataContainer.get(NamespacedKey("tcoww", "dead"), PersistentDataType.BOOLEAN) == true
|
|
||||||
}
|
|
||||||
|
|
||||||
deadPlayers.forEach { player ->
|
|
||||||
player.gameMode = GameMode.SPECTATOR
|
|
||||||
Stockage.backLocation[player.uniqueId]?.let { player.teleport(it) }
|
|
||||||
player.kill(current)
|
|
||||||
}
|
|
||||||
|
|
||||||
current.playersMutable.removeAll(deadPlayers)
|
|
||||||
if (current.gameEnded()) {
|
|
||||||
current.playersMutable.forEach {
|
|
||||||
if (it.isTransformed()) it.tfHuman()
|
|
||||||
}
|
|
||||||
current.stopGame()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun powerItemDrop(event: PlayerDropItemEvent) {
|
|
||||||
val item = event.itemDrop.itemStack
|
|
||||||
if (event.player.gameMode != GameMode.CREATIVE &&
|
|
||||||
item.itemMeta.persistentDataContainer.has(NamespacedKey("tcoww", "power"), PersistentDataType.INTEGER)
|
|
||||||
) {
|
|
||||||
event.isCancelled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun powerItemTransfer(event: InventoryMoveItemEvent) {
|
|
||||||
val item = event.item
|
|
||||||
if (event.source != event.destination &&
|
|
||||||
item.itemMeta.persistentDataContainer.has(NamespacedKey("tcoww", "power"), PersistentDataType.INTEGER)
|
|
||||||
) {
|
|
||||||
event.isCancelled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun sleepLeaveEvent(event: PlayerBedLeaveEvent) {
|
|
||||||
val role = event.player.role
|
|
||||||
if (Game.current?.timeGestion?.phase == Phase.NIGHT &&
|
|
||||||
role !is Child && role?.lg != true &&
|
|
||||||
!event.player.persistentDataContainer.getOrDefault(
|
|
||||||
NamespacedKey("tcoww", "insomie"),
|
|
||||||
PersistentDataType.BOOLEAN,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
event.isCancelled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun clickEvent(event: PlayerInteractEvent) {
|
|
||||||
val item = event.item ?: return
|
|
||||||
if (item.persistentDataContainer.get(NamespacedKey("tcoww", "power"), PersistentDataType.INTEGER) == 3) {
|
|
||||||
val player = event.player
|
|
||||||
|
|
||||||
player.inventory.remove(item)
|
|
||||||
|
|
||||||
if (player.isTransformed()) {
|
|
||||||
player.tfHuman()
|
|
||||||
} else {
|
|
||||||
player.tfWerewolf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun onDeath(event: PlayerDeathEvent) {
|
|
||||||
val current = Game.current ?: return
|
|
||||||
val player = event.player
|
|
||||||
if (!current.playersMutable.contains(player)) return
|
|
||||||
|
|
||||||
event.isCancelled = true
|
|
||||||
|
|
||||||
if (current.timeGestion.phase == Phase.NIGHT) {
|
|
||||||
Stockage.backLocation[player.uniqueId] = player.location
|
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, Runnable {
|
|
||||||
player.teleport(plugin.config.getLocation("lobbyLocation")!!)
|
|
||||||
player.clearActivePotionEffects()
|
|
||||||
player.fireTicks = 0
|
|
||||||
}, 1)
|
|
||||||
player.isInvulnerable = true
|
|
||||||
player.persistentDataContainer.set(NamespacedKey("tcoww", "dead"), PersistentDataType.BOOLEAN, true)
|
|
||||||
player.sendMessage(
|
|
||||||
Component.text("Vous étes mort... Mais vous pouvez être encore résucité.").color(
|
|
||||||
NamedTextColor.RED
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
current.playersMutable.forEach { p ->
|
|
||||||
if (p.role is Witch && p.inventory.any {
|
|
||||||
it != null && it.persistentDataContainer.get(
|
|
||||||
NamespacedKey("tcoww", "power"),
|
|
||||||
PersistentDataType.INTEGER
|
|
||||||
) == 2
|
|
||||||
}) {
|
|
||||||
p.sendMessage(
|
|
||||||
Component.text("Cette nuit, ${player.name} est mort dans d'atroces souffrances. Vous avez le pouvoir de le/la sauver.\n")
|
|
||||||
.color(NamedTextColor.DARK_PURPLE)
|
|
||||||
.append(
|
|
||||||
Component.text("Cliquez ici pour le/la ressusciter.")
|
|
||||||
.color(NamedTextColor.DARK_PURPLE)
|
|
||||||
.decorate(TextDecoration.UNDERLINED)
|
|
||||||
.clickEvent(ClickEvent.suggestCommand("/power save ${player.name}"))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
player.kill(current)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun onHit(event: EntityDamageByEntityEvent) {
|
|
||||||
val current = Game.current ?: return
|
|
||||||
if (current.timeGestion.phase != Phase.NIGHT) return
|
|
||||||
|
|
||||||
val damager = event.damager
|
|
||||||
val target = event.entity
|
|
||||||
if (damager is Player && target is Player &&
|
|
||||||
current.playersMutable.contains(damager) &&
|
|
||||||
current.playersMutable.contains(target) &&
|
|
||||||
damager.role?.lg == true &&
|
|
||||||
damager.isTransformed() &&
|
|
||||||
target.role?.lg != true &&
|
|
||||||
current.wwcankill
|
|
||||||
) {
|
|
||||||
current.wwcankill = false
|
|
||||||
target.health = 0.0
|
|
||||||
target.persistentDataContainer.set(NamespacedKey("tcoww", "insomie"), PersistentDataType.BOOLEAN, true)
|
|
||||||
if (target.isSleeping) target.wakeup(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(
|
|
||||||
priority = EventPriority.MONITOR,
|
|
||||||
ignoreCancelled = true
|
|
||||||
)
|
|
||||||
fun startSleep(event: PlayerBedEnterEvent) {
|
|
||||||
event.player.addPotionEffect(
|
|
||||||
PotionEffect(
|
|
||||||
PotionEffectType.REGENERATION,
|
|
||||||
PotionEffect.INFINITE_DURATION,
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(
|
|
||||||
priority = EventPriority.MONITOR,
|
|
||||||
ignoreCancelled = true
|
|
||||||
)
|
|
||||||
fun endSleep(event: PlayerBedLeaveEvent) {
|
|
||||||
event.player.removePotionEffect(PotionEffectType.REGENERATION)
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
fun disconnect(event: PlayerQuitEvent) {
|
|
||||||
val current = Game.current ?: return
|
|
||||||
val player = event.player
|
|
||||||
if (!current.playersMutable.contains(player)) return
|
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, Runnable {
|
|
||||||
if (!player.isConnected) {
|
|
||||||
player.kill(current)
|
|
||||||
}
|
|
||||||
}, 2_400)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Player.kill(current: Game) {
|
|
||||||
if (isTransformed()) tfHuman()
|
|
||||||
val item = ItemStack.of(Material.PLAYER_HEAD)
|
|
||||||
val skullmeta = item.itemMeta as SkullMeta
|
|
||||||
skullmeta.owningPlayer = player
|
|
||||||
item.itemMeta = skullmeta
|
|
||||||
|
|
||||||
val loc = this.location.add(0.0, 1.5, 0.0)
|
|
||||||
val entity = this.world.spawnEntity(loc, EntityType.ITEM_DISPLAY) as ItemDisplay
|
|
||||||
entity.setItemStack(item)
|
|
||||||
Bukkit.getScheduler().runTaskLater(
|
|
||||||
plugin,
|
|
||||||
Runnable {
|
|
||||||
entity.remove()
|
|
||||||
},
|
|
||||||
2400L
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
this.gameMode = GameMode.SPECTATOR
|
|
||||||
this.isInvulnerable = false
|
|
||||||
current.playersMutable.remove(player)
|
|
||||||
|
|
||||||
this.showTitle(
|
|
||||||
Title.title(
|
|
||||||
Component.text("Vous êtes mort.").color(NamedTextColor.DARK_RED),
|
|
||||||
Component.empty(),
|
|
||||||
Title.Times.times(Duration.ZERO, Duration.ofSeconds(2), Duration.ofMillis(500))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (current.gameEnded()) current.stopGame()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Player.tfWerewolf() {
|
|
||||||
if (isTransformed()) return
|
|
||||||
|
|
||||||
skinUtils.applyWerewolfFur(this)
|
|
||||||
persistentDataContainer.set(
|
|
||||||
NamespacedKey("tcoww", "wwtranform"),
|
|
||||||
PersistentDataType.BOOLEAN,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
val speedatr = getAttribute(Attribute.MOVEMENT_SPEED)!!
|
|
||||||
val scaleatr = getAttribute(Attribute.SCALE)!!
|
|
||||||
|
|
||||||
speedatr.addModifier(
|
|
||||||
AttributeModifier(
|
|
||||||
NamespacedKey("tcoww", "wwtranform"),
|
|
||||||
0.05,
|
|
||||||
AttributeModifier.Operation.ADD_NUMBER
|
|
||||||
)
|
|
||||||
)
|
|
||||||
scaleatr.addModifier(
|
|
||||||
AttributeModifier(
|
|
||||||
NamespacedKey("tcoww", "wwtranform"),
|
|
||||||
0.1,
|
|
||||||
AttributeModifier.Operation.ADD_NUMBER
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Player.tfHuman() {
|
|
||||||
if (!isTransformed()) return
|
|
||||||
|
|
||||||
skinUtils.unApplySkin(this)
|
|
||||||
persistentDataContainer.set(
|
|
||||||
NamespacedKey("tcoww", "wwtranform"),
|
|
||||||
PersistentDataType.BOOLEAN,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
val speedatr = getAttribute(Attribute.MOVEMENT_SPEED)!!
|
|
||||||
val scaleatr = getAttribute(Attribute.SCALE)!!
|
|
||||||
speedatr.removeModifier(
|
|
||||||
NamespacedKey("tcoww", "wwtranform")
|
|
||||||
)
|
|
||||||
scaleatr.removeModifier(
|
|
||||||
NamespacedKey("tcoww", "wwtranform")
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Player.isTransformed(): Boolean {
|
|
||||||
return persistentDataContainer.getOrDefault(
|
|
||||||
NamespacedKey("tcoww", "wwtranform"),
|
|
||||||
PersistentDataType.BOOLEAN,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val Player.role
|
|
||||||
get() = Role.getRole(this)
|
|
||||||
}
|
|
||||||
247
src/main/kotlin/fr/azur/tcoww/events/GameEvents.kt
Normal file
247
src/main/kotlin/fr/azur/tcoww/events/GameEvents.kt
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
package fr.azur.tcoww.events
|
||||||
|
|
||||||
|
import fr.azur.tcoww.Tcoww
|
||||||
|
import fr.azur.tcoww.events.PowerEvents.backLocation
|
||||||
|
import fr.azur.tcoww.game.Game
|
||||||
|
import fr.azur.tcoww.game.NightLightCycle
|
||||||
|
import fr.azur.tcoww.roles.Child
|
||||||
|
import fr.azur.tcoww.roles.Role
|
||||||
|
import fr.azur.tcoww.roles.Role.Companion.werewolfRole
|
||||||
|
import fr.azur.tcoww.roles.Witch
|
||||||
|
import fr.azur.tcoww.utils.DataKeys.Insomnia
|
||||||
|
import fr.azur.tcoww.utils.DataKeys.PlayerDead
|
||||||
|
import fr.azur.tcoww.utils.DataKeys.PowerItems
|
||||||
|
import fr.azur.tcoww.utils.Players
|
||||||
|
import fr.azur.tcoww.utils.Players.isTransformed
|
||||||
|
import fr.azur.tcoww.utils.Players.kill
|
||||||
|
import fr.azur.tcoww.utils.VoiceChatPlugin
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import net.kyori.adventure.text.format.TextDecoration
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.GameMode
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.bukkit.entity.Mannequin
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.EventPriority
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent
|
||||||
|
import org.bukkit.event.player.PlayerBedEnterEvent
|
||||||
|
import org.bukkit.event.player.PlayerBedLeaveEvent
|
||||||
|
import org.bukkit.event.player.PlayerInteractEntityEvent
|
||||||
|
import org.bukkit.inventory.meta.Damageable
|
||||||
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
import org.bukkit.potion.PotionEffect
|
||||||
|
import org.bukkit.potion.PotionEffectType
|
||||||
|
|
||||||
|
object GameEvents : Listener {
|
||||||
|
@EventHandler
|
||||||
|
fun onDeath(event: PlayerDeathEvent) {
|
||||||
|
val current = Game.current ?: return
|
||||||
|
val player = event.player
|
||||||
|
if (!current.remainingPlayer.contains(player)) return
|
||||||
|
|
||||||
|
event.isCancelled = true
|
||||||
|
|
||||||
|
if (current.timeGestion.phase == NightLightCycle.Phase.NIGHT) {
|
||||||
|
backLocation[player.uniqueId] = player.location
|
||||||
|
val lobby = Tcoww.config.getLocation("lobby-location")
|
||||||
|
Bukkit.getScheduler().runTaskLater(
|
||||||
|
Tcoww,
|
||||||
|
Runnable {
|
||||||
|
if (lobby != null) {
|
||||||
|
player.teleport(lobby)
|
||||||
|
} else {
|
||||||
|
player.gameMode = GameMode.SPECTATOR
|
||||||
|
}
|
||||||
|
player.clearActivePotionEffects()
|
||||||
|
player.fireTicks = 0
|
||||||
|
},
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
player.isInvulnerable = true
|
||||||
|
player.persistentDataContainer.set(PlayerDead, PersistentDataType.BOOLEAN, true)
|
||||||
|
player.sendMessage(
|
||||||
|
Component.text(
|
||||||
|
"Vous étes mort... Mais vous pouvez être encore résucité.",
|
||||||
|
NamedTextColor.RED,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
current.remainingPlayer.forEach { p ->
|
||||||
|
if (p.werewolfRole is Witch &&
|
||||||
|
p.inventory.any {
|
||||||
|
it != null &&
|
||||||
|
it.persistentDataContainer.get(
|
||||||
|
PowerItems,
|
||||||
|
PersistentDataType.INTEGER,
|
||||||
|
) == 2 &&
|
||||||
|
(it.itemMeta as Damageable).damage != 1
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
p.sendMessage(
|
||||||
|
Component
|
||||||
|
.text(
|
||||||
|
"Cette nuit, ${player.name} est mort dans d'atroces souffrances. Vous avez le pouvoir de le/la sauver.\n",
|
||||||
|
NamedTextColor.DARK_PURPLE,
|
||||||
|
).append(
|
||||||
|
Component
|
||||||
|
.text("Cliquez ici pour le/la ressusciter.", NamedTextColor.DARK_PURPLE)
|
||||||
|
.decorate(TextDecoration.UNDERLINED)
|
||||||
|
.clickEvent(
|
||||||
|
ClickEvent.callback {
|
||||||
|
val item =
|
||||||
|
p.inventory.find {
|
||||||
|
it != null &&
|
||||||
|
it.persistentDataContainer.get(
|
||||||
|
PowerItems,
|
||||||
|
PersistentDataType.INTEGER,
|
||||||
|
) == 2 &&
|
||||||
|
(it.itemMeta as Damageable).damage != 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.persistentDataContainer.get(
|
||||||
|
PlayerDead,
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
) == true
|
||||||
|
) {
|
||||||
|
return@callback
|
||||||
|
}
|
||||||
|
if (item == null) return@callback
|
||||||
|
|
||||||
|
(item.itemMeta as Damageable).damage = 1
|
||||||
|
|
||||||
|
player.persistentDataContainer.set(
|
||||||
|
NamespacedKey("tcoww", "dead"),
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
backLocation[player.uniqueId]?.let { player.teleport(it) }
|
||||||
|
player.isInvulnerable = false
|
||||||
|
player.sendMessage(
|
||||||
|
Component.text("Vous avez été résucité.", NamedTextColor.AQUA),
|
||||||
|
)
|
||||||
|
player.sendMessage(
|
||||||
|
Component
|
||||||
|
.text("Vous avez résuciter ")
|
||||||
|
.color(NamedTextColor.AQUA)
|
||||||
|
.append(player.displayName()),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
player.kill()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onHit(event: EntityDamageByEntityEvent) {
|
||||||
|
val current = Game.current ?: return
|
||||||
|
if (current.timeGestion.phase != NightLightCycle.Phase.NIGHT) return
|
||||||
|
|
||||||
|
val damager = event.damager
|
||||||
|
val target = event.entity
|
||||||
|
if (damager is Player &&
|
||||||
|
target is Player &&
|
||||||
|
current.remainingPlayer.contains(damager) &&
|
||||||
|
current.remainingPlayer.contains(target) &&
|
||||||
|
damager.werewolfRole.team == Role.Team.LG &&
|
||||||
|
damager.isTransformed() &&
|
||||||
|
target.werewolfRole.team != Role.Team.LG
|
||||||
|
) {
|
||||||
|
target.health = 0.0
|
||||||
|
target.persistentDataContainer.set(Insomnia, PersistentDataType.BOOLEAN, true)
|
||||||
|
if (target.isSleeping) target.wakeup(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun sleepLeaveEvent(event: PlayerBedLeaveEvent) {
|
||||||
|
val role = event.player.werewolfRole
|
||||||
|
if (Game.current?.timeGestion?.phase == NightLightCycle.Phase.NIGHT &&
|
||||||
|
role !is Child &&
|
||||||
|
role.team != Role.Team.LG &&
|
||||||
|
!event.player.persistentDataContainer.getOrDefault(
|
||||||
|
Insomnia,
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
event.isCancelled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(
|
||||||
|
priority = EventPriority.MONITOR,
|
||||||
|
ignoreCancelled = true,
|
||||||
|
)
|
||||||
|
fun startSleep(event: PlayerBedEnterEvent) {
|
||||||
|
if (event.player.werewolfRole.team == Role.Team.LG) {
|
||||||
|
VoiceChatPlugin.addWerewolf(event.player)
|
||||||
|
} else {
|
||||||
|
VoiceChatPlugin.createSoloGroup(event.player)
|
||||||
|
}
|
||||||
|
event.player.addPotionEffect(
|
||||||
|
PotionEffect(
|
||||||
|
PotionEffectType.REGENERATION,
|
||||||
|
PotionEffect.INFINITE_DURATION,
|
||||||
|
1,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
event.player.addPotionEffect(
|
||||||
|
PotionEffect(
|
||||||
|
PotionEffectType.BLINDNESS,
|
||||||
|
PotionEffect.INFINITE_DURATION,
|
||||||
|
1,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(
|
||||||
|
priority = EventPriority.MONITOR,
|
||||||
|
)
|
||||||
|
fun endSleep(event: PlayerBedLeaveEvent) {
|
||||||
|
event.player.removePotionEffect(PotionEffectType.REGENERATION)
|
||||||
|
event.player.removePotionEffect(PotionEffectType.BLINDNESS)
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun clickOnCorpse(event: PlayerInteractEntityEvent) {
|
||||||
|
val corpse = event.rightClicked
|
||||||
|
if (corpse is Mannequin &&
|
||||||
|
corpse.persistentDataContainer.getOrDefault(Players.corpseKey, PersistentDataType.BOOLEAN, false)
|
||||||
|
) {
|
||||||
|
val deadPlayer = Bukkit.getPlayer(corpse.profile.uuid()!!)!!
|
||||||
|
val playerRole =
|
||||||
|
Role.registerRoles.getValue(
|
||||||
|
NamespacedKey.fromString(
|
||||||
|
corpse.persistentDataContainer.get(
|
||||||
|
Players.corpseRoleKey,
|
||||||
|
PersistentDataType.STRING,
|
||||||
|
)!!,
|
||||||
|
)!!,
|
||||||
|
)
|
||||||
|
event.player.sendMessage {
|
||||||
|
Component
|
||||||
|
.text("Ceci est le cadavre de ", NamedTextColor.DARK_RED)
|
||||||
|
.append(deadPlayer.displayName())
|
||||||
|
.append(Component.text(".", NamedTextColor.DARK_RED))
|
||||||
|
.appendNewline()
|
||||||
|
.append(Component.text("Il était ", NamedTextColor.DARK_RED))
|
||||||
|
.append(playerRole.displayName)
|
||||||
|
.append(Component.text(".", NamedTextColor.DARK_RED))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
178
src/main/kotlin/fr/azur/tcoww/events/PhaseEvents.kt
Normal file
178
src/main/kotlin/fr/azur/tcoww/events/PhaseEvents.kt
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
package fr.azur.tcoww.events
|
||||||
|
|
||||||
|
import fr.azur.tcoww.Tcoww
|
||||||
|
import fr.azur.tcoww.commands.Vote
|
||||||
|
import fr.azur.tcoww.game.Game
|
||||||
|
import fr.azur.tcoww.game.NightLightCycle
|
||||||
|
import fr.azur.tcoww.roles.Child
|
||||||
|
import fr.azur.tcoww.roles.Role
|
||||||
|
import fr.azur.tcoww.roles.Role.Companion.werewolfRole
|
||||||
|
import fr.azur.tcoww.utils.BedGestion.isOccupied
|
||||||
|
import fr.azur.tcoww.utils.DataKeys.Insomnia
|
||||||
|
import fr.azur.tcoww.utils.DataKeys.PlayerDead
|
||||||
|
import fr.azur.tcoww.utils.DataKeys.PowerItems
|
||||||
|
import fr.azur.tcoww.utils.Players.isTransformed
|
||||||
|
import fr.azur.tcoww.utils.Players.kill
|
||||||
|
import fr.azur.tcoww.utils.Players.tfHuman
|
||||||
|
import fr.azur.tcoww.utils.VoiceChatPlugin
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.GameMode
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
|
object PhaseEvents : Listener {
|
||||||
|
@EventHandler
|
||||||
|
fun phaseChange(event: NightLightCycle.NightLightCyclePhaseChangeEvent) {
|
||||||
|
val current = Game.current ?: return
|
||||||
|
current.remainingPlayer.forEach { it.updateCommands() }
|
||||||
|
when (event.newPhase) {
|
||||||
|
NightLightCycle.Phase.DAY -> {
|
||||||
|
event.world.players.forEach { player ->
|
||||||
|
VoiceChatPlugin.degroupPlayer(player)
|
||||||
|
player.sendMessage(Component.text("Le jour se lève.", NamedTextColor.GOLD))
|
||||||
|
player.clearActivePotionEffects()
|
||||||
|
player.persistentDataContainer.set(
|
||||||
|
Insomnia,
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
if (player.werewolfRole.team == Role.Team.LG) {
|
||||||
|
player.inventory.forEach {
|
||||||
|
if (it != null &&
|
||||||
|
it.persistentDataContainer.get(
|
||||||
|
PowerItems,
|
||||||
|
PersistentDataType.INTEGER,
|
||||||
|
) == 3
|
||||||
|
) {
|
||||||
|
player.setCooldown(it, ((event.duration.day + event.duration.vote) * 20))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.isTransformed()) {
|
||||||
|
player.tfHuman()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NightLightCycle.Phase.VOTE -> {
|
||||||
|
event.world.players.forEach { player ->
|
||||||
|
player.sendMessage(
|
||||||
|
Component
|
||||||
|
.text("Le jour se couche, ce soir un vote est organisé.")
|
||||||
|
.color(NamedTextColor.DARK_AQUA)
|
||||||
|
.appendNewline()
|
||||||
|
.append(
|
||||||
|
Component
|
||||||
|
.text("Faite /vote <pseudo> pour voter.")
|
||||||
|
.color(NamedTextColor.AQUA),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NightLightCycle.Phase.NIGHT -> {
|
||||||
|
if (Vote.vote.isNotEmpty()) {
|
||||||
|
val voteMap =
|
||||||
|
Vote.vote.values
|
||||||
|
.groupingBy { it }
|
||||||
|
.eachCount()
|
||||||
|
val mostVoted = voteMap.maxByOrNull { it.value }?.key
|
||||||
|
mostVoted?.let { uuid ->
|
||||||
|
Bukkit.getPlayer(uuid)?.let { votedPlayer ->
|
||||||
|
votedPlayer.fireTicks = 1200
|
||||||
|
Bukkit.getScheduler().runTaskLater(
|
||||||
|
Tcoww,
|
||||||
|
Runnable {
|
||||||
|
votedPlayer.health = 0.0
|
||||||
|
},
|
||||||
|
60,
|
||||||
|
)
|
||||||
|
current.remainingPlayer.forEach {
|
||||||
|
it.sendMessage(
|
||||||
|
Component
|
||||||
|
.text("${votedPlayer.name} a reçu le plus de vote.")
|
||||||
|
.color(NamedTextColor.RED),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Vote.vote.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
event.world.players.forEach { player ->
|
||||||
|
player.sendMessage(
|
||||||
|
Component
|
||||||
|
.text("La lune se léve et les loups sont de sortie. Vous devriez dormir.")
|
||||||
|
.color(NamedTextColor.DARK_PURPLE),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (player.werewolfRole.team == Role.Team.LG) {
|
||||||
|
player.sendMessage(
|
||||||
|
Component.text("Vous pouvez vous transformer.", NamedTextColor.DARK_PURPLE),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskLater(
|
||||||
|
Tcoww,
|
||||||
|
Runnable {
|
||||||
|
val openBed =
|
||||||
|
current.beds
|
||||||
|
.filter { !it.block.isOccupied() }
|
||||||
|
.toMutableList()
|
||||||
|
current.remainingPlayer.forEach { player ->
|
||||||
|
if (!player.isSleeping &&
|
||||||
|
!player.persistentDataContainer.getOrDefault(
|
||||||
|
PlayerDead,
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
) &&
|
||||||
|
!player.isTransformed()
|
||||||
|
) {
|
||||||
|
val loc = openBed.removeFirst()
|
||||||
|
player.sleep(loc, true)
|
||||||
|
|
||||||
|
val role = player.werewolfRole
|
||||||
|
if (role is Child || role.team == Role.Team.LG) {
|
||||||
|
player.sendMessage(
|
||||||
|
Component.text(
|
||||||
|
"Tout le monde est couché. Vous pouvez vous lever.",
|
||||||
|
NamedTextColor.AQUA,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Tcoww.config.getLong("player-sleep"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
NightLightCycle.Phase.CREPUSCULAR -> {
|
||||||
|
val current = Game.current ?: return
|
||||||
|
val deadPlayers =
|
||||||
|
current.remainingPlayer.filter {
|
||||||
|
it.persistentDataContainer.get(PlayerDead, PersistentDataType.BOOLEAN) == true
|
||||||
|
}
|
||||||
|
|
||||||
|
deadPlayers.forEach { player ->
|
||||||
|
player.gameMode = GameMode.SPECTATOR
|
||||||
|
PowerEvents.backLocation[player.uniqueId]?.let { player.teleport(it) }
|
||||||
|
player.kill()
|
||||||
|
}
|
||||||
|
|
||||||
|
current.remainingPlayer.removeAll(deadPlayers)
|
||||||
|
// if (current.gameEnded()) {
|
||||||
|
// current.remainingPlayer.forEach {
|
||||||
|
// if (it.isTransformed()) it.tfHuman()
|
||||||
|
// }
|
||||||
|
// current.stopGame()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
157
src/main/kotlin/fr/azur/tcoww/events/PowerEvents.kt
Normal file
157
src/main/kotlin/fr/azur/tcoww/events/PowerEvents.kt
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
package fr.azur.tcoww.events
|
||||||
|
|
||||||
|
import fr.azur.tcoww.game.Game
|
||||||
|
import fr.azur.tcoww.roles.Role
|
||||||
|
import fr.azur.tcoww.ui.PlayerSelectMenu
|
||||||
|
import fr.azur.tcoww.utils.DataKeys
|
||||||
|
import fr.azur.tcoww.utils.Players.isTransformed
|
||||||
|
import fr.azur.tcoww.utils.Players.tfHuman
|
||||||
|
import fr.azur.tcoww.utils.Players.tfWerewolf
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.event.HoverEvent
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.GameMode
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.event.inventory.InventoryMoveItemEvent
|
||||||
|
import org.bukkit.event.player.PlayerDropItemEvent
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent
|
||||||
|
import org.bukkit.inventory.meta.Damageable
|
||||||
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
import org.bukkit.potion.PotionEffect
|
||||||
|
import org.bukkit.potion.PotionEffectType
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
object PowerEvents : Listener {
|
||||||
|
var backLocation = mutableMapOf<UUID, Location>()
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun powerItemDrop(event: PlayerDropItemEvent) {
|
||||||
|
val item = event.itemDrop.itemStack
|
||||||
|
if (event.player.gameMode != GameMode.CREATIVE &&
|
||||||
|
item.itemMeta.persistentDataContainer.has(DataKeys.PowerItems, PersistentDataType.INTEGER)
|
||||||
|
) {
|
||||||
|
event.isCancelled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun powerItemTransfer(event: InventoryMoveItemEvent) {
|
||||||
|
val item = event.item
|
||||||
|
if (event.source != event.destination &&
|
||||||
|
item.itemMeta.persistentDataContainer.has(DataKeys.PowerItems, PersistentDataType.INTEGER)
|
||||||
|
) {
|
||||||
|
event.isCancelled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun clickEvent(event: PlayerInteractEvent) {
|
||||||
|
val item = event.item ?: return
|
||||||
|
val player = event.player
|
||||||
|
if (player.hasCooldown(item)) return
|
||||||
|
when (item.persistentDataContainer.get(NamespacedKey("tcoww", "power"), PersistentDataType.INTEGER)) {
|
||||||
|
1 -> {
|
||||||
|
if ((item.itemMeta as Damageable).damage == 1) return
|
||||||
|
val current = Game.current ?: return
|
||||||
|
|
||||||
|
val menu = PlayerSelectMenu(current.remainingPlayer)
|
||||||
|
player.openInventory(menu.inventory)
|
||||||
|
|
||||||
|
menu.future.whenComplete { selectedPlayer, _ ->
|
||||||
|
val target = selectedPlayer ?: return@whenComplete
|
||||||
|
(item.itemMeta as Damageable).damage = 1
|
||||||
|
target.addPotionEffect(PotionEffect(PotionEffectType.WITHER, 600, 4))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
2 -> {
|
||||||
|
if ((item.itemMeta as Damageable).damage == 1) return
|
||||||
|
val current = Game.current ?: return
|
||||||
|
|
||||||
|
val menu =
|
||||||
|
PlayerSelectMenu(
|
||||||
|
current.remainingPlayer.filter {
|
||||||
|
it.persistentDataContainer.get(
|
||||||
|
NamespacedKey("tcoww", "dead"),
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
) == true
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
player.openInventory(menu.inventory)
|
||||||
|
|
||||||
|
menu.future.whenComplete { selectedPlayer, _ ->
|
||||||
|
val target = selectedPlayer ?: return@whenComplete
|
||||||
|
(item.itemMeta as Damageable).damage = 1
|
||||||
|
target.persistentDataContainer.set(
|
||||||
|
NamespacedKey("tcoww", "dead"),
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
backLocation[target.uniqueId]?.let { target.teleport(it) }
|
||||||
|
target.isInvulnerable = false
|
||||||
|
target.sendMessage(Component.text("Vous avez été résucité.", NamedTextColor.AQUA))
|
||||||
|
player.sendMessage(
|
||||||
|
Component
|
||||||
|
.text("Vous avez résuciter ")
|
||||||
|
.color(NamedTextColor.AQUA)
|
||||||
|
.append(player.displayName()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
3 -> {
|
||||||
|
player.setCooldown(item, 600)
|
||||||
|
|
||||||
|
if (player.isTransformed()) {
|
||||||
|
player.tfHuman()
|
||||||
|
} else {
|
||||||
|
player.tfWerewolf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
4 -> {
|
||||||
|
val current = Game.current ?: return
|
||||||
|
val timeGestion = current.timeGestion
|
||||||
|
|
||||||
|
val menu = PlayerSelectMenu(current.remainingPlayer)
|
||||||
|
player.openInventory(menu.inventory)
|
||||||
|
|
||||||
|
menu.future.whenComplete { selectedPlayer, _ ->
|
||||||
|
val target = selectedPlayer ?: return@whenComplete
|
||||||
|
|
||||||
|
val cooldown =
|
||||||
|
(
|
||||||
|
(
|
||||||
|
timeGestion.duration.day + timeGestion.duration.vote + timeGestion.duration.night +
|
||||||
|
timeGestion.duration.crepuscular -
|
||||||
|
30
|
||||||
|
) *
|
||||||
|
2
|
||||||
|
) *
|
||||||
|
20
|
||||||
|
|
||||||
|
player.setCooldown(item, cooldown)
|
||||||
|
|
||||||
|
val targetRole = Role.getRole(target)
|
||||||
|
|
||||||
|
player.sendMessage(
|
||||||
|
target
|
||||||
|
.displayName()
|
||||||
|
.append(Component.text(" est "))
|
||||||
|
.append(
|
||||||
|
targetRole?.displayName ?: Component.text("Inconnu").hoverEvent(
|
||||||
|
HoverEvent.showText(
|
||||||
|
targetRole?.lineDescription ?: Component.empty(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package fr.azur.tcoww.events
|
|
||||||
|
|
||||||
import fr.azur.tcoww.game.Phase
|
|
||||||
import org.bukkit.World
|
|
||||||
import org.bukkit.event.Event
|
|
||||||
import org.bukkit.event.HandlerList
|
|
||||||
|
|
||||||
class TimePhaseChangeEvent(
|
|
||||||
val world: World,
|
|
||||||
val newPhase: Phase
|
|
||||||
) : Event() {
|
|
||||||
override fun getHandlers(): HandlerList {
|
|
||||||
return handlerList
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@JvmStatic
|
|
||||||
val handlerList: HandlerList = HandlerList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +1,56 @@
|
|||||||
package fr.azur.tcoww.events
|
package fr.azur.tcoww.events
|
||||||
|
|
||||||
import fr.azur.tcoww.utils.BedGestion
|
import fr.azur.tcoww.Tcoww
|
||||||
|
import fr.azur.tcoww.utils.BedGestion.getHeadBed
|
||||||
|
import fr.azur.tcoww.utils.BedGestion.isBed
|
||||||
|
import fr.azur.tcoww.utils.DataKeys
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.Location
|
||||||
import org.bukkit.event.EventHandler
|
import org.bukkit.event.EventHandler
|
||||||
import org.bukkit.event.Listener
|
import org.bukkit.event.Listener
|
||||||
import org.bukkit.event.player.PlayerInteractEvent
|
import org.bukkit.event.player.PlayerInteractEvent
|
||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
import org.bukkit.plugin.java.JavaPlugin
|
|
||||||
|
|
||||||
class ToolsEvents(val plugin: JavaPlugin) : Listener {
|
object ToolsEvents : Listener {
|
||||||
@EventHandler
|
@EventHandler
|
||||||
fun clickEvent(event: PlayerInteractEvent) {
|
fun clickEvent(event: PlayerInteractEvent) {
|
||||||
val tool = event.player.inventory.itemInMainHand
|
val tool = event.player.inventory.itemInMainHand
|
||||||
|
|
||||||
if (!tool.persistentDataContainer.has(NamespacedKey("tcoww", "tools"))) return
|
if (!tool.persistentDataContainer.has(DataKeys.ToolsItems) || event.player.hasCooldown(tool)) return
|
||||||
|
|
||||||
when (tool.persistentDataContainer.get(NamespacedKey("tcoww", "tools"), PersistentDataType.INTEGER)) {
|
event.player.setCooldown(tool, 20)
|
||||||
|
|
||||||
|
when (tool.persistentDataContainer.get(DataKeys.ToolsItems, PersistentDataType.INTEGER)) {
|
||||||
1 -> {
|
1 -> {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
val interactloc = event.interactionPoint
|
val interactLoc = event.interactionPoint
|
||||||
if (interactloc != null) {
|
if (interactLoc != null) {
|
||||||
if (BedGestion.isBed(interactloc.block)) {
|
if (interactLoc.block.isBed()) {
|
||||||
val list = plugin.config.getMapList("bedLocation")
|
val list =
|
||||||
|
Tcoww.config
|
||||||
|
.getList("bed-locations")
|
||||||
|
.orEmpty()
|
||||||
|
.mapNotNull { it as? Location }
|
||||||
|
.toMutableList()
|
||||||
|
|
||||||
val block = BedGestion.getHeadBed(interactloc.block)
|
val block = interactLoc.block.getHeadBed()
|
||||||
|
|
||||||
if (!list.contains(block.location.serialize())) {
|
if (!list.contains(block.location)) {
|
||||||
list.add(block.location.serialize())
|
list.add(block.location)
|
||||||
plugin.config.set("bedLocation", list)
|
Tcoww.config.set("bed-locations", list)
|
||||||
plugin.saveConfig()
|
Tcoww.saveConfig()
|
||||||
event.player.sendMessage(
|
event.player.sendMessage(
|
||||||
Component.text("Bed location add.").color(NamedTextColor.LIGHT_PURPLE)
|
Component.text("Bed location add.", NamedTextColor.LIGHT_PURPLE),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
event.player.sendMessage(
|
event.player.sendMessage(
|
||||||
Component.text("Bed location already exists.").color(NamedTextColor.DARK_RED)
|
Component.text("Bed location already exists.", NamedTextColor.DARK_RED),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
event.player.sendMessage(
|
event.player.sendMessage(
|
||||||
Component.text("It's not a bed...").color(NamedTextColor.DARK_RED)
|
Component.text("It's not a bed...", NamedTextColor.DARK_RED),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,34 +58,29 @@ class ToolsEvents(val plugin: JavaPlugin) : Listener {
|
|||||||
|
|
||||||
2 -> {
|
2 -> {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
val interactloc = event.interactionPoint
|
val interactLoc = event.interactionPoint
|
||||||
if (interactloc != null) {
|
if (interactLoc != null) {
|
||||||
interactloc.x = interactloc.blockX.toDouble()
|
interactLoc.x = interactLoc.blockX.toDouble()
|
||||||
interactloc.y = interactloc.blockY.toDouble() + 1
|
interactLoc.y = interactLoc.blockY.toDouble() + 1
|
||||||
interactloc.z = interactloc.blockZ.toDouble()
|
interactLoc.z = interactLoc.blockZ.toDouble()
|
||||||
plugin.config.set("spawnLocation", interactloc)
|
Tcoww.config.set("spawn-location", interactLoc)
|
||||||
plugin.saveConfig()
|
Tcoww.saveConfig()
|
||||||
event.player.sendMessage(Component.text("Spawn location set.").color(NamedTextColor.LIGHT_PURPLE))
|
event.player.sendMessage(Component.text("Spawn location set.", NamedTextColor.LIGHT_PURPLE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
3 -> {
|
3 -> {
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
val interactloc = event.interactionPoint
|
val interactLoc = event.interactionPoint
|
||||||
if (interactloc != null) {
|
if (interactLoc != null) {
|
||||||
interactloc.x = interactloc.blockX.toDouble()
|
interactLoc.x = interactLoc.blockX.toDouble()
|
||||||
interactloc.y = interactloc.blockY.toDouble() + 1
|
interactLoc.y = interactLoc.blockY.toDouble() + 1
|
||||||
interactloc.z = interactloc.blockZ.toDouble()
|
interactLoc.z = interactLoc.blockZ.toDouble()
|
||||||
plugin.config.set("lobbyLocation", interactloc)
|
Tcoww.config.set("lobby-location", interactLoc)
|
||||||
plugin.saveConfig()
|
Tcoww.saveConfig()
|
||||||
event.player.sendMessage(Component.text("Lobby location set.").color(NamedTextColor.LIGHT_PURPLE))
|
event.player.sendMessage(Component.text("Lobby location set.", NamedTextColor.LIGHT_PURPLE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// @EventHandler
|
|
||||||
// fun reloadAfterWorld(worldInitEvent: WorldInitEvent) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|||||||
27
src/main/kotlin/fr/azur/tcoww/events/UIEvents.kt
Normal file
27
src/main/kotlin/fr/azur/tcoww/events/UIEvents.kt
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package fr.azur.tcoww.events
|
||||||
|
|
||||||
|
import fr.azur.tcoww.ui.CustomUI
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||||
|
|
||||||
|
object UIEvents : Listener {
|
||||||
|
@EventHandler
|
||||||
|
fun onInventoryClick(event: InventoryClickEvent) {
|
||||||
|
val inventory = event.inventory
|
||||||
|
val holder = inventory.getHolder(false)
|
||||||
|
if (holder is CustomUI) {
|
||||||
|
holder.onClick(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onInventoryClick(event: InventoryCloseEvent) {
|
||||||
|
val inventory = event.inventory
|
||||||
|
val holder = inventory.getHolder(false)
|
||||||
|
if (holder is CustomUI) {
|
||||||
|
holder.onClose(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,35 +1,42 @@
|
|||||||
package fr.azur.tcoww.game
|
package fr.azur.tcoww.game
|
||||||
|
|
||||||
|
import fr.azur.tcoww.Tcoww
|
||||||
import fr.azur.tcoww.roles.Role
|
import fr.azur.tcoww.roles.Role
|
||||||
import fr.azur.tcoww.roles.Villager
|
import fr.azur.tcoww.roles.Role.Companion.werewolfRole
|
||||||
import fr.azur.tcoww.roles.Werewolf
|
import fr.azur.tcoww.utils.Players.tfHuman
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.GameMode
|
import org.bukkit.GameMode
|
||||||
|
import org.bukkit.Location
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.World
|
import org.bukkit.World
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.persistence.PersistentDataType
|
|
||||||
import org.bukkit.plugin.Plugin
|
import org.bukkit.plugin.Plugin
|
||||||
import org.bukkit.potion.PotionEffect
|
import org.bukkit.potion.PotionEffect
|
||||||
import org.bukkit.potion.PotionEffectType
|
import org.bukkit.potion.PotionEffectType
|
||||||
import org.bukkit.scheduler.BukkitTask
|
|
||||||
import kotlin.math.ceil
|
|
||||||
|
|
||||||
class Game(var plugin: Plugin, val world: World, val players: Iterable<Player>, var roles: Iterable<Role>) {
|
class Game(
|
||||||
val werewolfPercentage: Float = plugin.config.getInt("wwcount").toFloat()
|
var plugin: Plugin,
|
||||||
val timeGestion: TimeGestion
|
val world: World,
|
||||||
val playersMutable = players.toMutableList()
|
val players: Iterable<Player>,
|
||||||
val timeGestShedule: BukkitTask
|
var roles: Map<NamespacedKey, Int>,
|
||||||
var wwcankill = false
|
) {
|
||||||
|
val timeGestion: NightLightCycle
|
||||||
|
val remainingPlayer = players.toMutableList()
|
||||||
|
val beds =
|
||||||
|
Tcoww.config
|
||||||
|
.getList("bed-locations")
|
||||||
|
.orEmpty()
|
||||||
|
.mapNotNull { it as? Location }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
players.forEach { player ->
|
players.forEach { player ->
|
||||||
player.persistentDataContainer.set(NamespacedKey("tcoww", "dead"), PersistentDataType.BOOLEAN, false)
|
player.tfHuman()
|
||||||
player.persistentDataContainer.set(NamespacedKey("tcoww", "wwtranform"), PersistentDataType.BOOLEAN, false)
|
val spawnLoc = plugin.config.getLocation("spawn-location")
|
||||||
player.teleport(plugin.config.getLocation("spawnLocation")!!)
|
if (spawnLoc != null) player.teleport(spawnLoc)
|
||||||
player.inventory.clear()
|
player.inventory.clear()
|
||||||
|
player.gameMode = GameMode.ADVENTURE
|
||||||
player.health = 20.0
|
player.health = 20.0
|
||||||
player.addPotionEffect(
|
player.addPotionEffect(
|
||||||
PotionEffect(
|
PotionEffect(
|
||||||
@@ -37,47 +44,27 @@ class Game(var plugin: Plugin, val world: World, val players: Iterable<Player>,
|
|||||||
PotionEffect.INFINITE_DURATION,
|
PotionEffect.INFINITE_DURATION,
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
false
|
false,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
assignRoles()
|
assignRoles()
|
||||||
|
|
||||||
timeGestion = TimeGestion(plugin, world)
|
timeGestion = NightLightCycle(plugin, world)
|
||||||
|
|
||||||
timeGestShedule = Bukkit.getScheduler().runTaskTimer(plugin, Runnable {
|
|
||||||
timeGestion.tick()
|
|
||||||
}, 0L, 1L)
|
|
||||||
|
|
||||||
current = this
|
current = this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getWerewolfInt(): Int {
|
|
||||||
val playerCount = players.count()
|
|
||||||
return ceil(playerCount * (werewolfPercentage / 100f)).toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun assignRoles() {
|
private fun assignRoles() {
|
||||||
val playerList = players.shuffled().toMutableList()
|
val playersShuffled = players.shuffled()
|
||||||
|
var playerIndex = 0
|
||||||
val werewolfCount = getWerewolfInt()
|
roles.forEach {
|
||||||
val specialRolesCount = roles.count()
|
val role = Role.registerRoles.getValue(it.key)
|
||||||
|
for (i in 0..<it.value) {
|
||||||
if (werewolfCount + specialRolesCount > playerList.size) {
|
playersShuffled[playerIndex].werewolfRole = role
|
||||||
throw IllegalArgumentException("Not enough players for the given number of werewolves and special roles.")
|
playerIndex++
|
||||||
}
|
}
|
||||||
|
|
||||||
repeat(werewolfCount) { i ->
|
|
||||||
Role.setRole(playerList[i], Werewolf())
|
|
||||||
}
|
|
||||||
|
|
||||||
roles.forEachIndexed { idx, role ->
|
|
||||||
Role.setRole(playerList[werewolfCount + idx], role)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i in werewolfCount + specialRolesCount until playerList.size) {
|
|
||||||
Role.setRole(playerList[i], Villager())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,56 +72,54 @@ class Game(var plugin: Plugin, val world: World, val players: Iterable<Player>,
|
|||||||
var current: Game? = null
|
var current: Game? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun gameEnded(): Boolean {
|
fun checkGameEnd(): Boolean {
|
||||||
var hasWerewolf = false
|
val team = players.map { player -> player.werewolfRole.team }.toSet()
|
||||||
var hasVillager = false
|
return team.count() <= 1
|
||||||
|
|
||||||
for (player in playersMutable) {
|
|
||||||
val isWerewolf = Role.getRole(player)?.lg ?: false
|
|
||||||
if (isWerewolf) hasWerewolf = true else hasVillager = true
|
|
||||||
if (hasWerewolf && hasVillager) return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopGame(withoutResult: Boolean = false) {
|
fun stopGame(withoutResult: Boolean = false) {
|
||||||
current ?: return
|
current ?: return
|
||||||
current = null
|
current = null
|
||||||
timeGestShedule.cancel()
|
timeGestion.stop()
|
||||||
world.time = 18000
|
world.time = 18000
|
||||||
players.forEach { player ->
|
players.forEach { player ->
|
||||||
player.gameMode = GameMode.SPECTATOR
|
player.gameMode = GameMode.SPECTATOR
|
||||||
player.sendMessage(
|
player.sendMessage(
|
||||||
Component.text("La partie est terminée !", NamedTextColor.DARK_GREEN)
|
Component
|
||||||
|
.text("La partie est terminée !", NamedTextColor.DARK_GREEN)
|
||||||
.appendNewline()
|
.appendNewline()
|
||||||
.append {
|
.apply {
|
||||||
if (withoutResult)
|
if (!withoutResult) return@apply
|
||||||
Component.empty()
|
remainingPlayer.forEachIndexed { index, player ->
|
||||||
else {
|
append(player.displayName())
|
||||||
val villageHasWolf = playersMutable.any {
|
|
||||||
Role.getRole(it)?.lg ?: false
|
if (index != remainingPlayer.lastIndex) {
|
||||||
}
|
append(
|
||||||
if (villageHasWolf) {
|
Component.text(
|
||||||
Component.text(
|
when (index) {
|
||||||
"Les loups-garous ont finalement dévoré le village.",
|
remainingPlayer.lastIndex - 1 -> " et "
|
||||||
NamedTextColor.DARK_RED
|
else -> ", "
|
||||||
)
|
},
|
||||||
} else {
|
NamedTextColor.DARK_GREEN,
|
||||||
Component.text(
|
),
|
||||||
"Les villageois ont finalement sauvé le village.",
|
|
||||||
NamedTextColor.DARK_BLUE
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
append(Component.text(" ont gagné !", NamedTextColor.DARK_GREEN))
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, Runnable {
|
val lobbyLoc = plugin.config.getLocation("lobby-location")
|
||||||
players.forEach { player ->
|
Bukkit.getScheduler().runTaskLater(
|
||||||
player.teleport(plugin.config.getLocation("lobbyLocation")!!)
|
plugin,
|
||||||
player.gameMode = GameMode.ADVENTURE
|
Runnable {
|
||||||
}
|
players.forEach { player ->
|
||||||
}, 200)
|
if (lobbyLoc != null) player.teleport(lobbyLoc)
|
||||||
|
player.gameMode = GameMode.ADVENTURE
|
||||||
|
}
|
||||||
|
},
|
||||||
|
200,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
127
src/main/kotlin/fr/azur/tcoww/game/NightLightCycle.kt
Normal file
127
src/main/kotlin/fr/azur/tcoww/game/NightLightCycle.kt
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
package fr.azur.tcoww.game
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.GameRule
|
||||||
|
import org.bukkit.World
|
||||||
|
import org.bukkit.event.Event
|
||||||
|
import org.bukkit.event.HandlerList
|
||||||
|
import org.bukkit.plugin.Plugin
|
||||||
|
import org.bukkit.scheduler.BukkitTask
|
||||||
|
|
||||||
|
class NightLightCycle(
|
||||||
|
plugin: Plugin,
|
||||||
|
val world: World,
|
||||||
|
) {
|
||||||
|
enum class Phase {
|
||||||
|
DAY,
|
||||||
|
VOTE,
|
||||||
|
NIGHT,
|
||||||
|
CREPUSCULAR,
|
||||||
|
}
|
||||||
|
|
||||||
|
class NightLightCyclePhaseChangeEvent(
|
||||||
|
val world: World,
|
||||||
|
val newPhase: Phase,
|
||||||
|
val duration: Duration,
|
||||||
|
) : Event() {
|
||||||
|
override fun getHandlers(): HandlerList = handlerList
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
val handlerList: HandlerList = HandlerList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Duration(
|
||||||
|
val day: Int,
|
||||||
|
val vote: Int,
|
||||||
|
val night: Int,
|
||||||
|
val crepuscular: Int,
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun fromPlugin(plugin: Plugin): Duration {
|
||||||
|
val dayDuration = plugin.config.getInt("duration.day")
|
||||||
|
val voteDuration = plugin.config.getInt("duration.vote")
|
||||||
|
val nightDuration = plugin.config.getInt("duration.night")
|
||||||
|
val crepuscularDuration = plugin.config.getInt("duration.crepuscular")
|
||||||
|
return Duration(dayDuration, voteDuration, nightDuration, crepuscularDuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var phase: Phase = Phase.DAY
|
||||||
|
val phases = Phase.entries
|
||||||
|
val process: BukkitTask
|
||||||
|
|
||||||
|
val duration = Duration.fromPlugin(plugin)
|
||||||
|
|
||||||
|
var targetInstant: Long
|
||||||
|
var tickOrigin: Int = 0
|
||||||
|
var realDifference: Int
|
||||||
|
var tickDifference: Int
|
||||||
|
|
||||||
|
var dayCount: Int = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false)
|
||||||
|
realDifference = duration.day * 1000
|
||||||
|
targetInstant = System.currentTimeMillis() + realDifference.toLong()
|
||||||
|
tickDifference = 12_000
|
||||||
|
Bukkit.getPluginManager().callEvent(NightLightCyclePhaseChangeEvent(world, phase, duration))
|
||||||
|
|
||||||
|
process =
|
||||||
|
Bukkit.getScheduler().runTaskTimer(
|
||||||
|
plugin,
|
||||||
|
Runnable {
|
||||||
|
this.tick()
|
||||||
|
},
|
||||||
|
0L,
|
||||||
|
1L,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun changePhase(newPhase: Phase) {
|
||||||
|
when (newPhase) {
|
||||||
|
Phase.DAY -> {
|
||||||
|
tickDifference = 12_000
|
||||||
|
tickOrigin = 0
|
||||||
|
realDifference = duration.day * 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
Phase.VOTE -> {
|
||||||
|
tickDifference = 1_000
|
||||||
|
tickOrigin = 12_000
|
||||||
|
realDifference = duration.vote * 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
Phase.NIGHT -> {
|
||||||
|
tickDifference = 11_000
|
||||||
|
tickOrigin = 13_000
|
||||||
|
realDifference = duration.night * 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
Phase.CREPUSCULAR -> {
|
||||||
|
tickDifference = 1_000
|
||||||
|
tickOrigin = 23_000
|
||||||
|
realDifference = duration.crepuscular * 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
targetInstant = System.currentTimeMillis() + realDifference
|
||||||
|
phase = newPhase
|
||||||
|
Bukkit.getPluginManager().callEvent(NightLightCyclePhaseChangeEvent(world, newPhase, duration))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tick() {
|
||||||
|
if (System.currentTimeMillis() >= targetInstant) {
|
||||||
|
val phase = phases[(phases.indexOf(phase) + 1) % phases.count()]
|
||||||
|
if (phase == Phase.DAY) {
|
||||||
|
dayCount += 1
|
||||||
|
}
|
||||||
|
changePhase(phase)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop() {
|
||||||
|
process.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package fr.azur.tcoww.game
|
|
||||||
|
|
||||||
enum class Phase {
|
|
||||||
DAY,
|
|
||||||
VOTE,
|
|
||||||
NIGHT,
|
|
||||||
CREPUSCULAR
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package fr.azur.tcoww.game
|
|
||||||
|
|
||||||
import fr.azur.tcoww.events.TimePhaseChangeEvent
|
|
||||||
import org.bukkit.Bukkit
|
|
||||||
import org.bukkit.World
|
|
||||||
import org.bukkit.GameRule
|
|
||||||
import org.bukkit.plugin.Plugin
|
|
||||||
import java.util.Calendar
|
|
||||||
|
|
||||||
class TimeGestion(plugin: Plugin, val world: World) {
|
|
||||||
var calendar: Calendar = Calendar.getInstance()
|
|
||||||
var targetCalendar: Calendar = calendar.clone() as Calendar
|
|
||||||
var difference: Long
|
|
||||||
var differencetick: Int
|
|
||||||
|
|
||||||
val dayDuration: Int = plugin.config.getInt("duration.day")
|
|
||||||
val voteDuration: Int = plugin.config.getInt("duration.vote")
|
|
||||||
val nightDuration: Int = plugin.config.getInt("duration.night")
|
|
||||||
val crepuscularDuration: Int = plugin.config.getInt("duration.crepuscular")
|
|
||||||
|
|
||||||
var phase: Phase = Phase.DAY
|
|
||||||
var tickcorrecter = 0
|
|
||||||
|
|
||||||
init {
|
|
||||||
world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false)
|
|
||||||
targetCalendar.add(Calendar.SECOND, dayDuration)
|
|
||||||
difference = targetCalendar.timeInMillis - calendar.timeInMillis
|
|
||||||
differencetick = 12500
|
|
||||||
Bukkit.getPluginManager().callEvent(TimePhaseChangeEvent(world,phase))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun changePhase() {
|
|
||||||
calendar = Calendar.getInstance()
|
|
||||||
targetCalendar = calendar.clone() as Calendar
|
|
||||||
|
|
||||||
when (phase) {
|
|
||||||
// vote
|
|
||||||
Phase.DAY -> {
|
|
||||||
phase = Phase.VOTE
|
|
||||||
tickcorrecter = 12_500
|
|
||||||
differencetick = 1_500
|
|
||||||
targetCalendar.add(Calendar.SECOND, voteDuration)
|
|
||||||
}
|
|
||||||
// night
|
|
||||||
Phase.VOTE -> {
|
|
||||||
phase = Phase.NIGHT
|
|
||||||
tickcorrecter = 14_000
|
|
||||||
differencetick = 8_500
|
|
||||||
targetCalendar.add(Calendar.SECOND, nightDuration)
|
|
||||||
}
|
|
||||||
// crepuscular
|
|
||||||
Phase.NIGHT -> {
|
|
||||||
phase = Phase.CREPUSCULAR
|
|
||||||
tickcorrecter = 22_500
|
|
||||||
differencetick = 1_500
|
|
||||||
targetCalendar.add(Calendar.SECOND, crepuscularDuration)
|
|
||||||
}
|
|
||||||
// day
|
|
||||||
Phase.CREPUSCULAR -> {
|
|
||||||
phase = Phase.DAY
|
|
||||||
tickcorrecter = 0
|
|
||||||
differencetick = 12_500
|
|
||||||
targetCalendar.add(Calendar.SECOND, dayDuration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Bukkit.getPluginManager().callEvent(TimePhaseChangeEvent(world,phase))
|
|
||||||
|
|
||||||
difference = targetCalendar.timeInMillis - calendar.timeInMillis
|
|
||||||
}
|
|
||||||
|
|
||||||
fun tick() {
|
|
||||||
if (System.currentTimeMillis() >= targetCalendar.timeInMillis) {
|
|
||||||
changePhase()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (difference == 0L) return
|
|
||||||
|
|
||||||
val result = tickcorrecter + ((differencetick.toDouble() * (System.currentTimeMillis() - calendar.timeInMillis)) / difference).toInt()
|
|
||||||
world.time = result.coerceIn(0, 23999).toLong()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,12 +2,12 @@ package fr.azur.tcoww.items
|
|||||||
|
|
||||||
import fr.azur.tcoww.game.Game
|
import fr.azur.tcoww.game.Game
|
||||||
import fr.azur.tcoww.roles.Role
|
import fr.azur.tcoww.roles.Role
|
||||||
|
import fr.azur.tcoww.utils.DataKeys
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
import net.kyori.adventure.text.format.TextDecoration
|
import net.kyori.adventure.text.format.TextDecoration
|
||||||
import org.bukkit.Color
|
import org.bukkit.Color
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
|
||||||
import org.bukkit.enchantments.Enchantment
|
import org.bukkit.enchantments.Enchantment
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.inventory.ItemRarity
|
import org.bukkit.inventory.ItemRarity
|
||||||
@@ -19,181 +19,205 @@ import org.bukkit.persistence.PersistentDataType
|
|||||||
import org.bukkit.potion.PotionEffect
|
import org.bukkit.potion.PotionEffect
|
||||||
import org.bukkit.potion.PotionEffectType
|
import org.bukkit.potion.PotionEffectType
|
||||||
|
|
||||||
enum class CustomItems(val cache: Boolean, val supplier: () -> ItemStack) {
|
enum class CustomItems(
|
||||||
|
val cache: Boolean,
|
||||||
|
val supplier: () -> ItemStack,
|
||||||
|
) {
|
||||||
WereWolfTransformItem(true, {
|
WereWolfTransformItem(true, {
|
||||||
ItemStack.of(Material.BONE).apply {
|
ItemStack.of(Material.BONE).apply {
|
||||||
itemMeta = itemMeta.apply {
|
itemMeta =
|
||||||
customName(Component.text("Os de transformation").color(NamedTextColor.DARK_RED))
|
itemMeta.apply {
|
||||||
persistentDataContainer.set(
|
customName(Component.text("Os de transformation", NamedTextColor.DARK_RED))
|
||||||
NamespacedKey("tcoww", "power"),
|
persistentDataContainer.set(
|
||||||
PersistentDataType.INTEGER,
|
DataKeys.PowerItems,
|
||||||
3
|
PersistentDataType.INTEGER,
|
||||||
)
|
3,
|
||||||
lore(
|
|
||||||
listOf(
|
|
||||||
Component.text("Clique pour basculer en forme loup-garou.")
|
|
||||||
.color(NamedTextColor.GOLD)
|
|
||||||
)
|
)
|
||||||
)
|
lore(
|
||||||
}
|
listOf(
|
||||||
|
Component
|
||||||
|
.text("Clique pour basculer en forme loup-garou.")
|
||||||
|
.color(NamedTextColor.GOLD),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
GunBullet(true, {
|
GunBullet(true, {
|
||||||
ItemStack(Material.TIPPED_ARROW).apply {
|
ItemStack(Material.TIPPED_ARROW).apply {
|
||||||
itemMeta = (itemMeta as PotionMeta).apply {
|
itemMeta =
|
||||||
color = Color.ORANGE
|
(itemMeta as PotionMeta).apply {
|
||||||
displayName(Component.text("Balle de fusil.", NamedTextColor.YELLOW))
|
color = Color.ORANGE
|
||||||
basePotionType = basePotionType.apply {
|
displayName(Component.text("Balle de fusil.", NamedTextColor.YELLOW))
|
||||||
addCustomEffect(PotionEffect(PotionEffectType.INSTANT_DAMAGE, 20, 99), true)
|
basePotionType =
|
||||||
|
basePotionType.apply {
|
||||||
|
addCustomEffect(PotionEffect(PotionEffectType.INSTANT_DAMAGE, 20, 99), true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
BlasTechDL44(true, {
|
BlasTechDL44(true, {
|
||||||
ItemStack.of(Material.CROSSBOW).apply {
|
ItemStack.of(Material.CROSSBOW).apply {
|
||||||
itemMeta = (itemMeta as CrossbowMeta).apply {
|
itemMeta =
|
||||||
addChargedProjectile(GunBullet.item)
|
(itemMeta as DamageableCrossbow).apply {
|
||||||
displayName(Component.text("BlasTech DL-44", NamedTextColor.GOLD))
|
addChargedProjectile(GunBullet.item)
|
||||||
addEnchant(Enchantment.INFINITY, 1, true)
|
displayName(Component.text("BlasTech DL-44", NamedTextColor.GOLD))
|
||||||
}
|
addEnchant(Enchantment.INFINITY, 1, true)
|
||||||
itemMeta = (itemMeta as Damageable).apply {
|
setMaxDamage(1)
|
||||||
setMaxDamage(1)
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
CrystalBall(true, {
|
CrystalBall(true, {
|
||||||
ItemStack.of(Material.GLASS).apply {
|
ItemStack.of(Material.GLASS).apply {
|
||||||
itemMeta = itemMeta.apply {
|
itemMeta =
|
||||||
customName(
|
itemMeta.apply {
|
||||||
Component.text("Boule de cristal").color(NamedTextColor.AQUA)
|
customName(
|
||||||
)
|
Component.text("Boule de cristal", NamedTextColor.AQUA),
|
||||||
persistentDataContainer.set(
|
)
|
||||||
NamespacedKey("tcoww", "power"),
|
persistentDataContainer.set(
|
||||||
PersistentDataType.INTEGER,
|
DataKeys.PowerItems,
|
||||||
4
|
PersistentDataType.INTEGER,
|
||||||
)
|
4,
|
||||||
lore(listOf(Component.text("/power view <pseudo> pour l'utiliser.").color(NamedTextColor.GOLD)))
|
)
|
||||||
}
|
setMaxStackSize(1)
|
||||||
|
lore(listOf(Component.text("Click droit pour utiliser.", NamedTextColor.GOLD)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}),
|
||||||
),
|
|
||||||
DeathPotion(true, {
|
DeathPotion(true, {
|
||||||
ItemStack.of(Material.POTION).apply {
|
ItemStack.of(Material.POTION).apply {
|
||||||
itemMeta = (itemMeta as PotionMeta).apply {
|
itemMeta =
|
||||||
customName(
|
(itemMeta as DamageablePotion).apply {
|
||||||
Component.text("Potion de poison").color(NamedTextColor.DARK_PURPLE)
|
setMaxStackSize(1)
|
||||||
)
|
setMaxDamage(1)
|
||||||
persistentDataContainer.set(
|
customName(
|
||||||
NamespacedKey("tcoww", "power"),
|
Component.text("Potion de poison", NamedTextColor.DARK_PURPLE),
|
||||||
PersistentDataType.INTEGER,
|
|
||||||
1
|
|
||||||
)
|
|
||||||
color = Color.BLACK
|
|
||||||
lore(
|
|
||||||
listOf(
|
|
||||||
Component.text("/power kill <pseudo> pour l'utiliser.").color(NamedTextColor.GOLD)
|
|
||||||
)
|
)
|
||||||
)
|
persistentDataContainer.set(
|
||||||
}
|
DataKeys.PowerItems,
|
||||||
|
PersistentDataType.INTEGER,
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
color = Color.BLACK
|
||||||
|
lore(
|
||||||
|
listOf(
|
||||||
|
Component.text("Click droit pour utiliser.", NamedTextColor.GOLD),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
HealPotion(true, {
|
HealPotion(true, {
|
||||||
ItemStack.of(Material.POTION).apply {
|
ItemStack.of(Material.POTION).apply {
|
||||||
itemMeta = (itemMeta as PotionMeta).apply {
|
itemMeta =
|
||||||
customName(
|
(itemMeta as DamageablePotion).apply {
|
||||||
Component.text("Potion de vie").color(NamedTextColor.DARK_PURPLE)
|
setMaxStackSize(1)
|
||||||
)
|
setMaxDamage(1)
|
||||||
persistentDataContainer.set(
|
customName(
|
||||||
NamespacedKey("tcoww", "power"),
|
Component.text("Potion de vie", NamedTextColor.DARK_PURPLE),
|
||||||
PersistentDataType.INTEGER,
|
)
|
||||||
2
|
persistentDataContainer.set(
|
||||||
)
|
DataKeys.PowerItems,
|
||||||
color = Color.RED
|
PersistentDataType.INTEGER,
|
||||||
lore(listOf(Component.text("/power save <pseudo> pour l'utiliser.").color(NamedTextColor.GOLD)))
|
2,
|
||||||
}
|
)
|
||||||
|
color = Color.RED
|
||||||
|
lore(listOf(Component.text("Click droit pour utiliser.", NamedTextColor.GOLD)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
SpawnLocTool(true, {
|
SpawnLocTool(true, {
|
||||||
ItemStack.of(Material.SUGAR_CANE).apply {
|
ItemStack.of(Material.SUGAR_CANE).apply {
|
||||||
itemMeta = itemMeta.apply {
|
itemMeta =
|
||||||
setRarity(ItemRarity.EPIC)
|
itemMeta.apply {
|
||||||
persistentDataContainer.set(
|
setRarity(ItemRarity.EPIC)
|
||||||
NamespacedKey("tcoww", "tools"),
|
persistentDataContainer.set(
|
||||||
PersistentDataType.INTEGER,
|
DataKeys.ToolsItems,
|
||||||
2
|
PersistentDataType.INTEGER,
|
||||||
)
|
2,
|
||||||
lore(listOf(Component.text("Spawn location tool").color(NamedTextColor.GOLD)))
|
)
|
||||||
}
|
lore(listOf(Component.text("Spawn location tool", NamedTextColor.GOLD)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
BedLocTool(true, {
|
BedLocTool(true, {
|
||||||
ItemStack.of(Material.WOODEN_HOE).apply {
|
ItemStack.of(Material.WOODEN_HOE).apply {
|
||||||
itemMeta = itemMeta.apply {
|
itemMeta =
|
||||||
setRarity(ItemRarity.EPIC)
|
itemMeta.apply {
|
||||||
persistentDataContainer.set(
|
setRarity(ItemRarity.EPIC)
|
||||||
NamespacedKey("tcoww", "tools"),
|
persistentDataContainer.set(
|
||||||
PersistentDataType.INTEGER,
|
DataKeys.ToolsItems,
|
||||||
1
|
PersistentDataType.INTEGER,
|
||||||
)
|
1,
|
||||||
lore(listOf(Component.text("bed location tool").color(NamedTextColor.GOLD)))
|
)
|
||||||
}
|
lore(listOf(Component.text("bed location tool", NamedTextColor.GOLD)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
LobbyLocTool(true, {
|
LobbyLocTool(true, {
|
||||||
ItemStack.of(Material.POPPED_CHORUS_FRUIT).apply {
|
ItemStack.of(Material.POPPED_CHORUS_FRUIT).apply {
|
||||||
itemMeta = itemMeta.apply {
|
itemMeta =
|
||||||
setRarity(ItemRarity.EPIC)
|
itemMeta.apply {
|
||||||
persistentDataContainer.set(
|
setRarity(ItemRarity.EPIC)
|
||||||
NamespacedKey("tcoww", "tools"),
|
persistentDataContainer.set(
|
||||||
PersistentDataType.INTEGER,
|
DataKeys.ToolsItems,
|
||||||
3
|
PersistentDataType.INTEGER,
|
||||||
)
|
3,
|
||||||
lore(listOf(Component.text("Lobby location tool").color(NamedTextColor.GOLD)))
|
)
|
||||||
}
|
lore(listOf(Component.text("Lobby location tool", NamedTextColor.GOLD)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
ListHint(false, {
|
ListHint(false, {
|
||||||
val finalLore = buildList {
|
val finalLore =
|
||||||
add(
|
buildList {
|
||||||
Component.text("C'est une liste de nom.", NamedTextColor.RED)
|
add(
|
||||||
)
|
Component.text("C'est une liste de nom.", NamedTextColor.RED),
|
||||||
add(
|
)
|
||||||
Component.text("Il y a écrit que un de ces 3 citoyens", NamedTextColor.DARK_RED)
|
add(
|
||||||
)
|
Component.text("Il y a écrit que un de ces 3 citoyens", NamedTextColor.DARK_RED),
|
||||||
add(
|
)
|
||||||
Component.text("est un loup-garou.", NamedTextColor.DARK_RED)
|
add(
|
||||||
)
|
Component.text("est un loup-garou.", NamedTextColor.DARK_RED),
|
||||||
|
)
|
||||||
|
|
||||||
val players = Game.current?.playersMutable?.shuffled().orEmpty()
|
val players =
|
||||||
|
Game.current
|
||||||
|
?.remainingPlayer
|
||||||
|
?.shuffled()
|
||||||
|
.orEmpty()
|
||||||
|
|
||||||
val (villagers, werewolves) = players.partition {
|
val (villagers, werewolves) =
|
||||||
Role.getRole(it)?.lg == false
|
players.partition {
|
||||||
|
Role.getRole(it)?.team != Role.Team.LG
|
||||||
|
}
|
||||||
|
|
||||||
|
val lg = werewolves.firstOrNull()
|
||||||
|
val names = mutableListOf<Player>()
|
||||||
|
|
||||||
|
if (lg != null) names.add(lg)
|
||||||
|
names.addAll(villagers.take(2))
|
||||||
|
|
||||||
|
val colors = NamedColors.namedColors.shuffled().toMutableList()
|
||||||
|
|
||||||
|
names.shuffled().forEach {
|
||||||
|
val color = colors.removeFirst()
|
||||||
|
add(Component.text("- ").append(it.displayName()).color(color))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty()) {
|
||||||
|
add(Component.text("nothing", NamedTextColor.DARK_RED, TextDecoration.OBFUSCATED))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val lg = werewolves.firstOrNull()
|
|
||||||
val names = mutableListOf<Player>()
|
|
||||||
|
|
||||||
if (lg != null) names.add(lg)
|
|
||||||
names.addAll(villagers.take(2))
|
|
||||||
|
|
||||||
val colors = NamedColors.namedColors.shuffled().toMutableList()
|
|
||||||
|
|
||||||
names.shuffled().forEach {
|
|
||||||
val color = colors.removeFirst()
|
|
||||||
add(Component.text("- ").append(it.displayName()).color(color))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEmpty()) {
|
|
||||||
add(Component.text("nothing", NamedTextColor.DARK_RED, TextDecoration.OBFUSCATED))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ItemStack(Material.PAPER).apply {
|
ItemStack(Material.PAPER).apply {
|
||||||
itemMeta = itemMeta.apply {
|
itemMeta =
|
||||||
displayName(Component.text("Liste de nom", NamedTextColor.GOLD))
|
itemMeta.apply {
|
||||||
lore(finalLore)
|
displayName(Component.text("Liste de nom", NamedTextColor.GOLD))
|
||||||
}
|
lore(finalLore)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
;
|
||||||
|
|
||||||
private var cachedItem: ItemStack? = null
|
private var cachedItem: ItemStack? = null
|
||||||
|
|
||||||
@@ -206,21 +230,31 @@ enum class CustomItems(val cache: Boolean, val supplier: () -> ItemStack) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data object NamedColors {
|
interface DamageableCrossbow :
|
||||||
val namedColors = listOf(
|
Damageable,
|
||||||
NamedTextColor.DARK_RED,
|
CrossbowMeta
|
||||||
NamedTextColor.RED,
|
|
||||||
NamedTextColor.GOLD,
|
|
||||||
NamedTextColor.YELLOW,
|
|
||||||
NamedTextColor.DARK_GREEN,
|
|
||||||
NamedTextColor.GREEN,
|
|
||||||
NamedTextColor.AQUA,
|
|
||||||
NamedTextColor.DARK_AQUA,
|
|
||||||
NamedTextColor.DARK_BLUE,
|
|
||||||
NamedTextColor.BLUE,
|
|
||||||
NamedTextColor.LIGHT_PURPLE,
|
|
||||||
NamedTextColor.DARK_PURPLE
|
|
||||||
)
|
|
||||||
|
|
||||||
|
interface DamageablePotion :
|
||||||
|
Damageable,
|
||||||
|
PotionMeta {
|
||||||
|
override fun clone(): DamageablePotion
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
data object NamedColors {
|
||||||
|
val namedColors =
|
||||||
|
listOf(
|
||||||
|
NamedTextColor.DARK_RED,
|
||||||
|
NamedTextColor.RED,
|
||||||
|
NamedTextColor.GOLD,
|
||||||
|
NamedTextColor.YELLOW,
|
||||||
|
NamedTextColor.DARK_GREEN,
|
||||||
|
NamedTextColor.GREEN,
|
||||||
|
NamedTextColor.AQUA,
|
||||||
|
NamedTextColor.DARK_AQUA,
|
||||||
|
NamedTextColor.DARK_BLUE,
|
||||||
|
NamedTextColor.BLUE,
|
||||||
|
NamedTextColor.LIGHT_PURPLE,
|
||||||
|
NamedTextColor.DARK_PURPLE,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,21 +2,22 @@ package fr.azur.tcoww.roles
|
|||||||
|
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.entity.Player
|
|
||||||
|
|
||||||
class Child : Role {
|
object Child : Role {
|
||||||
override fun handle(player: Player) {}
|
override val id = NamespacedKey("tcoww", "child")
|
||||||
|
override val team = Role.Team.Villager
|
||||||
override fun onDeath(player: Player) {}
|
override val displayName = Component.text("Petite Fille", NamedTextColor.LIGHT_PURPLE)
|
||||||
|
override val icon = Material.MAGENTA_WOOL
|
||||||
override var lg = false
|
override val order: Int = 2
|
||||||
override var id = NamespacedKey("tcoww", "child")
|
|
||||||
override val displayName = Component.text("Petite Fille")
|
|
||||||
override val hasPowerCommand = false
|
override val hasPowerCommand = false
|
||||||
override val description =
|
override val description =
|
||||||
Component.text("Extrêmement discrette et au coeur du risque.", NamedTextColor.BLUE).appendNewline()
|
listOf(
|
||||||
.append(
|
Component.text("Extrêmement discrette et au coeur du risque.", NamedTextColor.BLUE),
|
||||||
Component.text("Vous n'êtes pas obliger de dormir la nuit, vous pouvez donc observer les loups le soir.", NamedTextColor.BLUE)
|
Component.text(
|
||||||
)
|
"Vous n'êtes pas obliger de dormir la nuit, vous pouvez donc observer les loups le soir.",
|
||||||
}
|
NamedTextColor.BLUE,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,23 +3,27 @@ package fr.azur.tcoww.roles
|
|||||||
import fr.azur.tcoww.items.CustomItems
|
import fr.azur.tcoww.items.CustomItems
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class FortuneTeller : Role {
|
object FortuneTeller : Role {
|
||||||
override fun handle(player: Player) {
|
override fun handle(player: Player) {
|
||||||
player.inventory.addItem(CustomItems.CrystalBall.item)
|
player.inventory.addItem(CustomItems.CrystalBall.item)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDeath(player: Player) {}
|
override val team = Role.Team.Villager
|
||||||
|
|
||||||
override var lg = false
|
|
||||||
override var id = NamespacedKey("tcoww", "fortune_teller")
|
override var id = NamespacedKey("tcoww", "fortune_teller")
|
||||||
override val displayName = Component.text("Voyante")
|
override val icon = Material.GLASS
|
||||||
|
override val order: Int = 3
|
||||||
|
override val displayName = Component.text("Voyante", NamedTextColor.AQUA)
|
||||||
override val hasPowerCommand = true
|
override val hasPowerCommand = true
|
||||||
override val description =
|
override val description =
|
||||||
Component.text("Vous voyez des choses mais quoi ?.", NamedTextColor.BLUE).appendNewline()
|
listOf(
|
||||||
.append(
|
Component.text("Vous voyez des choses mais quoi ?.", NamedTextColor.BLUE),
|
||||||
Component.text("Tout les 2 jours vous pouvez regarder le role d'un joueur.", NamedTextColor.BLUE)
|
Component
|
||||||
)
|
.text("Tout les 2 jours vous pouvez regarder le role d'un joueur grâce à votre ", NamedTextColor.BLUE)
|
||||||
}
|
.append(CustomItems.CrystalBall.item.displayName())
|
||||||
|
.append(Component.text(".", NamedTextColor.BLUE)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,32 +3,32 @@ package fr.azur.tcoww.roles
|
|||||||
import fr.azur.tcoww.items.CustomItems
|
import fr.azur.tcoww.items.CustomItems
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class Hunter : Role {
|
object Hunter : Role {
|
||||||
override fun handle(player: Player) {
|
override fun handle(player: Player) {
|
||||||
player.inventory.addItem(CustomItems.BlasTechDL44.item)
|
player.inventory.addItem(CustomItems.BlasTechDL44.item)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDeath(player: Player) {
|
override val team = Role.Team.Villager
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override var lg = false
|
|
||||||
override var id = NamespacedKey("tcoww", "hunter")
|
override var id = NamespacedKey("tcoww", "hunter")
|
||||||
override val displayName = Component.text("Chaseur")
|
override val displayName = Component.text("Chaseur", NamedTextColor.GOLD)
|
||||||
|
override val icon = Material.ARROW
|
||||||
|
override val order: Int = 5
|
||||||
override val hasPowerCommand = false
|
override val hasPowerCommand = false
|
||||||
override val description =
|
override val description =
|
||||||
Component.text(
|
listOf(
|
||||||
"Vous êtes la personne, la plus redouter des animaux (et en particulier des loups).",
|
Component.text(
|
||||||
NamedTextColor.BLUE
|
"Vous êtes la personne, la plus redouter des animaux (et en particulier des loups).",
|
||||||
).appendNewline()
|
NamedTextColor.BLUE,
|
||||||
.append(
|
),
|
||||||
Component.text("Vous possedez un ", NamedTextColor.BLUE)
|
Component
|
||||||
.append(CustomItems.BlasTechDL44.item.displayName())
|
.text("Vous possedez un ", NamedTextColor.BLUE)
|
||||||
.append(
|
.append(CustomItems.BlasTechDL44.item.displayName())
|
||||||
Component.text(" qui permet de one shot n'importe quoi... (Usage Unique.)", NamedTextColor.BLUE)
|
.append(
|
||||||
)
|
Component.text(" qui permet de one shot n'importe quoi... (Usage Unique)", NamedTextColor.BLUE),
|
||||||
)
|
),
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,48 +2,87 @@ package fr.azur.tcoww.roles
|
|||||||
|
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.persistence.PersistentDataType
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
|
||||||
interface Role {
|
interface Role {
|
||||||
fun handle(player: Player)
|
enum class Team {
|
||||||
fun onDeath(player: Player)
|
LG {
|
||||||
val lg: Boolean
|
override val displayName = Component.text("loups-garous").color(NamedTextColor.DARK_RED)
|
||||||
|
},
|
||||||
|
Villager {
|
||||||
|
override val displayName: Component = Component.text("villageois", NamedTextColor.GREEN)
|
||||||
|
},
|
||||||
|
Solo {
|
||||||
|
override val displayName: Component = Component.text("solo", NamedTextColor.YELLOW)
|
||||||
|
}, ;
|
||||||
|
|
||||||
|
abstract val displayName: Component
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handle(player: Player) {}
|
||||||
|
|
||||||
|
fun onDeath(player: Player) {}
|
||||||
|
|
||||||
|
fun onVote(player: Player) {}
|
||||||
|
|
||||||
val id: NamespacedKey
|
val id: NamespacedKey
|
||||||
|
val icon: Material
|
||||||
|
val order: Int
|
||||||
|
val team: Team
|
||||||
val displayName: Component
|
val displayName: Component
|
||||||
val hasPowerCommand: Boolean
|
val hasPowerCommand: Boolean
|
||||||
val description: Component
|
val description: List<Component>
|
||||||
|
val lineDescription: Component
|
||||||
|
get() {
|
||||||
|
return Component.empty().apply {
|
||||||
|
description.forEach {
|
||||||
|
append(it)
|
||||||
|
appendNewline()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var registerRoles = hashMapOf<NamespacedKey, Role>()
|
var registerRoles = hashMapOf<NamespacedKey, Role>()
|
||||||
private val rolekey = NamespacedKey("tcoww", "role")
|
private val roleKey = NamespacedKey("tcoww", "role")
|
||||||
fun setRole(player: Player, role: Role) {
|
|
||||||
player.persistentDataContainer.set(
|
fun setRole(
|
||||||
rolekey,
|
player: Player,
|
||||||
PersistentDataType.STRING,
|
role: Role,
|
||||||
role.id.toString()
|
) {
|
||||||
|
player.sendMessage(
|
||||||
|
Component.text("Votre role est ", NamedTextColor.DARK_AQUA).append(role.displayName),
|
||||||
)
|
)
|
||||||
player.sendMessage(
|
player.sendMessage(
|
||||||
Component.text("Votre role est ").append(role.displayName).color(NamedTextColor.DARK_AQUA)
|
role.lineDescription.append {
|
||||||
|
if (role.team == Team.Solo) {
|
||||||
|
Component.text("Vous gagnez Seul.", NamedTextColor.AQUA)
|
||||||
|
} else {
|
||||||
|
Component
|
||||||
|
.text("Vous gagnez avec les ", NamedTextColor.AQUA)
|
||||||
|
.append(role.team.displayName)
|
||||||
|
.append(Component.text(".", NamedTextColor.AQUA))
|
||||||
|
}
|
||||||
|
},
|
||||||
)
|
)
|
||||||
player.sendMessage(role.description.appendNewline().append {
|
|
||||||
if (role.lg)
|
player.persistentDataContainer.set(roleKey, PersistentDataType.STRING, role.id.toString())
|
||||||
Component.text("Vous gagnez avec les loups-garous.", NamedTextColor.AQUA)
|
|
||||||
else
|
|
||||||
Component.text("Vous gagnez avec les villageois.", NamedTextColor.AQUA)
|
|
||||||
})
|
|
||||||
role.handle(player)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRole(player: Player): Role? {
|
fun getRole(player: Player): Role? {
|
||||||
val rolestr = player.persistentDataContainer.get(rolekey, PersistentDataType.STRING)
|
val roleKey = player.persistentDataContainer.get(roleKey, PersistentDataType.STRING) ?: return null
|
||||||
if (rolestr == null) return null
|
return registerRoles[NamespacedKey.fromString(roleKey)]
|
||||||
return registerRoles[NamespacedKey.fromString(rolestr)]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var Player.werewolfRole: Role
|
||||||
|
get() = getRole(this)!!
|
||||||
|
set(role) = setRole(this, role)
|
||||||
|
|
||||||
fun registerRole(role: Role) {
|
fun registerRole(role: Role) {
|
||||||
registerRoles.put(role.id, role)
|
registerRoles[role.id] = role
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,19 @@ package fr.azur.tcoww.roles
|
|||||||
|
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.entity.Player
|
|
||||||
|
|
||||||
class Villager : Role {
|
object Villager : Role {
|
||||||
override fun handle(player: Player) {
|
override val team = Role.Team.Villager
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDeath(player: Player) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override var lg: Boolean = false
|
|
||||||
override var id = NamespacedKey("tcoww", "villager")
|
override var id = NamespacedKey("tcoww", "villager")
|
||||||
override val displayName = Component.text("Villageois")
|
override val displayName = Component.text("Villageois", NamedTextColor.GRAY)
|
||||||
|
override val icon = Material.DIRT
|
||||||
|
override val order: Int = 0
|
||||||
override val hasPowerCommand = false
|
override val hasPowerCommand = false
|
||||||
override val description =
|
override val description =
|
||||||
Component.text("En tant que villageois, vous n'avez aucun pouvoir.", NamedTextColor.BLUE).appendNewline()
|
listOf(
|
||||||
.append(
|
Component.text("En tant que villageois, vous n'avez aucun pouvoir.", NamedTextColor.BLUE),
|
||||||
Component.text("Profiter en pour risquer pour trouver des indices ! ^^", NamedTextColor.BLUE)
|
Component.text("Profiter en pour risquer pour trouver des indices ! ^^", NamedTextColor.BLUE),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,32 @@
|
|||||||
package fr.azur.tcoww.roles
|
package fr.azur.tcoww.roles
|
||||||
|
|
||||||
|
import fr.azur.tcoww.Tcoww
|
||||||
|
import fr.azur.tcoww.items.CustomItems
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class Werewolf : Role {
|
object Werewolf : Role {
|
||||||
override fun handle(player: Player) {}
|
override val team = Role.Team.LG
|
||||||
|
|
||||||
override fun onDeath(player: Player) {}
|
|
||||||
|
|
||||||
override var lg = true
|
|
||||||
override var id = NamespacedKey("tcoww", "werewolf")
|
override var id = NamespacedKey("tcoww", "werewolf")
|
||||||
override val displayName = Component.text("Loup-Garou")
|
override val displayName = Component.text("Loup-Garou", NamedTextColor.DARK_GRAY)
|
||||||
|
override val icon = Material.BONE
|
||||||
|
override val order: Int = 1
|
||||||
override val hasPowerCommand = false
|
override val hasPowerCommand = false
|
||||||
override val description =
|
override val description =
|
||||||
Component.text("Pour la faire courte, vous avez faim, très faim.", NamedTextColor.BLUE).appendNewline()
|
listOf(
|
||||||
.append(
|
Component.text("Pour la faire courte, vous avez faim, très faim.", NamedTextColor.BLUE),
|
||||||
Component.text(
|
Component.text(
|
||||||
"Votre but est de tuer les villageois. Sans vous faire atraper et voter. Toute les nuits, vous pouvez vous tranformer en loup pour manger un villageois.",
|
"Votre but est de tuer les villageois. Sans vous faire atraper et voter. Toute les nuits, vous pouvez vous tranformer en loup pour manger un villageois.",
|
||||||
NamedTextColor.BLUE
|
NamedTextColor.BLUE,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
override fun handle(player: Player) {
|
||||||
|
val tfItem = CustomItems.WereWolfTransformItem.item
|
||||||
|
player.inventory.addItem(tfItem)
|
||||||
|
player.setCooldown(tfItem, ((Tcoww.config.getInt("duration.day") + Tcoww.config.getInt("duration.day")) * 20))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,27 +3,28 @@ package fr.azur.tcoww.roles
|
|||||||
import fr.azur.tcoww.items.CustomItems
|
import fr.azur.tcoww.items.CustomItems
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.Material
|
||||||
import org.bukkit.NamespacedKey
|
import org.bukkit.NamespacedKey
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class Witch : Role {
|
object Witch : Role {
|
||||||
override fun handle(player: Player) {
|
override fun handle(player: Player) {
|
||||||
player.inventory.addItem(CustomItems.DeathPotion.item)
|
player.inventory.addItem(CustomItems.DeathPotion.item)
|
||||||
player.inventory.addItem(CustomItems.HealPotion.item)
|
player.inventory.addItem(CustomItems.HealPotion.item)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDeath(player: Player) {}
|
override val team = Role.Team.Villager
|
||||||
|
|
||||||
override var lg = false
|
|
||||||
override var id = NamespacedKey("tcoww", "witch")
|
override var id = NamespacedKey("tcoww", "witch")
|
||||||
override val displayName = Component.text("Sorcière")
|
override val displayName = Component.text("Sorcière")
|
||||||
|
override val icon = Material.GLASS_BOTTLE
|
||||||
|
override val order: Int = 4
|
||||||
override val hasPowerCommand = true
|
override val hasPowerCommand = true
|
||||||
override val description =
|
override val description =
|
||||||
Component.text("Une potion = Une solution.", NamedTextColor.BLUE).appendNewline()
|
listOf(
|
||||||
.append(
|
Component.text("Une potion = Une solution.", NamedTextColor.BLUE),
|
||||||
Component.text(
|
Component.text(
|
||||||
"Vous possédez deux potions : une pour tuer et une pour ressusciter quelqu'un.",
|
"Vous possédez deux potions : une pour tuer et une pour ressusciter quelqu'un.",
|
||||||
NamedTextColor.BLUE
|
NamedTextColor.BLUE,
|
||||||
)
|
),
|
||||||
).appendNewline()
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/main/kotlin/fr/azur/tcoww/ui/CustomUI.kt
Normal file
11
src/main/kotlin/fr/azur/tcoww/ui/CustomUI.kt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package fr.azur.tcoww.ui
|
||||||
|
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||||
|
import org.bukkit.inventory.InventoryHolder
|
||||||
|
|
||||||
|
interface CustomUI : InventoryHolder {
|
||||||
|
fun onClick(event: InventoryClickEvent) {}
|
||||||
|
|
||||||
|
fun onClose(event: InventoryCloseEvent) {}
|
||||||
|
}
|
||||||
121
src/main/kotlin/fr/azur/tcoww/ui/GameConfig.kt
Normal file
121
src/main/kotlin/fr/azur/tcoww/ui/GameConfig.kt
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
package fr.azur.tcoww.ui
|
||||||
|
|
||||||
|
import fr.azur.tcoww.Tcoww
|
||||||
|
import fr.azur.tcoww.roles.Role
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||||
|
import org.bukkit.inventory.Inventory
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.inventory.meta.Damageable
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
import kotlin.math.ceil
|
||||||
|
|
||||||
|
class GameConfig(
|
||||||
|
playerCount: Int,
|
||||||
|
) : CustomUI {
|
||||||
|
// [index, [role key, amount]]
|
||||||
|
val rolesConfig = hashMapOf<Int, Pair<NamespacedKey, Int>>()
|
||||||
|
val size = (Role.registerRoles.count() / 9 + 1) * 9
|
||||||
|
val future = CompletableFuture<Map<NamespacedKey, Int>>()
|
||||||
|
|
||||||
|
private val inventory =
|
||||||
|
Tcoww.server.createInventory(this, size, Component.text("Game Config.", NamedTextColor.GREEN)).apply {
|
||||||
|
Role.registerRoles.values.sortedBy { it.order }.onEachIndexed { index, role ->
|
||||||
|
setItem(index, createItem(index, role))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val werewolfCount = ceil((playerCount * (Tcoww.config.getInt("werewolf-default-percentage") / 100f))).toInt()
|
||||||
|
editItem(0, playerCount - werewolfCount)
|
||||||
|
editItem(1, werewolfCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createItem(
|
||||||
|
index: Int,
|
||||||
|
role: Role,
|
||||||
|
): ItemStack {
|
||||||
|
rolesConfig[index] = Pair(role.id, 0)
|
||||||
|
|
||||||
|
return ItemStack.of(role.icon).apply {
|
||||||
|
itemMeta =
|
||||||
|
(itemMeta as Damageable).apply {
|
||||||
|
lore(
|
||||||
|
role.description,
|
||||||
|
)
|
||||||
|
itemName(
|
||||||
|
role.displayName,
|
||||||
|
)
|
||||||
|
setMaxStackSize(1)
|
||||||
|
setMaxDamage(1)
|
||||||
|
damage = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun editItem(
|
||||||
|
index: Int,
|
||||||
|
newAmount: Int,
|
||||||
|
) {
|
||||||
|
if (newAmount !in 0..99) throw IllegalArgumentException("Amount must be in 0 and 99 !")
|
||||||
|
rolesConfig[index] = Pair(rolesConfig[index]!!.first, newAmount)
|
||||||
|
val item = inventory.getItem(index) ?: return
|
||||||
|
item.itemMeta =
|
||||||
|
(item.itemMeta as Damageable).apply {
|
||||||
|
if (newAmount == 0) {
|
||||||
|
setMaxStackSize(1)
|
||||||
|
setMaxDamage(1)
|
||||||
|
damage = 1
|
||||||
|
} else {
|
||||||
|
damage = 0
|
||||||
|
setMaxStackSize(99)
|
||||||
|
item.amount = newAmount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInventory(): Inventory = inventory
|
||||||
|
|
||||||
|
override fun onClick(event: InventoryClickEvent) {
|
||||||
|
event.isCancelled = true
|
||||||
|
val index = event.slot
|
||||||
|
if (index !in 0..<Role.registerRoles.size || event.clickedInventory != inventory) return
|
||||||
|
if (event.isLeftClick) {
|
||||||
|
for (i in 0..<Role.registerRoles.size) {
|
||||||
|
if (i == index) continue
|
||||||
|
val count = rolesConfig[i]!!.second
|
||||||
|
if (count != 0) {
|
||||||
|
val targetCount = rolesConfig[index]!!.second
|
||||||
|
editItem(i, count - 1)
|
||||||
|
editItem(index, targetCount + 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (event.isRightClick) {
|
||||||
|
for (i in 0..<Role.registerRoles.size) {
|
||||||
|
if (i == index) continue
|
||||||
|
val count = rolesConfig[i]!!.second
|
||||||
|
if (count != 0) {
|
||||||
|
val targetCount = rolesConfig[index]!!.second
|
||||||
|
if (targetCount == 0) break
|
||||||
|
editItem(i, count + 1)
|
||||||
|
editItem(index, targetCount - 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClose(event: InventoryCloseEvent) {
|
||||||
|
future.complete(
|
||||||
|
buildMap {
|
||||||
|
rolesConfig.forEach {
|
||||||
|
if (it.value.second != 0) put(it.value.first, it.value.second)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/main/kotlin/fr/azur/tcoww/ui/PlayerSelectMenu.kt
Normal file
46
src/main/kotlin/fr/azur/tcoww/ui/PlayerSelectMenu.kt
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package fr.azur.tcoww.ui
|
||||||
|
|
||||||
|
import fr.azur.tcoww.Tcoww
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||||
|
import org.bukkit.inventory.Inventory
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
|
class PlayerSelectMenu(
|
||||||
|
val players: Iterable<Player>,
|
||||||
|
) : CustomUI {
|
||||||
|
val size = (players.count() / 9 + 1) * 9
|
||||||
|
val future = CompletableFuture<Player?>()
|
||||||
|
|
||||||
|
private val inventory =
|
||||||
|
Tcoww.server.createInventory(this, size, Component.text("Select a player.", NamedTextColor.GREEN)).apply {
|
||||||
|
players.forEachIndexed { index, player ->
|
||||||
|
val item =
|
||||||
|
ItemStack.of(Material.PLAYER_HEAD).apply {
|
||||||
|
itemMeta =
|
||||||
|
(itemMeta as SkullMeta).apply {
|
||||||
|
playerProfile = player.playerProfile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setItem(index, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInventory(): Inventory = inventory
|
||||||
|
|
||||||
|
override fun onClick(event: InventoryClickEvent) {
|
||||||
|
val index = event.slot
|
||||||
|
if (index !in 0..<players.count() || event.clickedInventory != inventory) return
|
||||||
|
future.complete(players.elementAt(index))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClose(event: InventoryCloseEvent) {
|
||||||
|
future.complete(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,21 +4,19 @@ import org.bukkit.block.Block
|
|||||||
import org.bukkit.block.data.type.Bed
|
import org.bukkit.block.data.type.Bed
|
||||||
|
|
||||||
object BedGestion {
|
object BedGestion {
|
||||||
fun isBed(block: Block): Boolean {
|
fun Block.isBed() = blockData is Bed
|
||||||
return block.blockData is Bed
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getHeadBed(block: Block): Block {
|
fun Block.getHeadBed(): Block {
|
||||||
val bedData = block.blockData as Bed
|
val bedData = blockData as Bed
|
||||||
return if (bedData.part == Bed.Part.FOOT) {
|
return if (bedData.part == Bed.Part.FOOT) {
|
||||||
block.getRelative(bedData.facing)
|
getRelative(bedData.facing)
|
||||||
} else {
|
} else {
|
||||||
block
|
this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isOcupied(block: Block): Boolean {
|
fun Block.isOccupied(): Boolean {
|
||||||
val bedData = block.blockData as Bed
|
val bedData = blockData as Bed
|
||||||
return bedData.isOccupied
|
return bedData.isOccupied
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/main/kotlin/fr/azur/tcoww/utils/DataKeys.kt
Normal file
11
src/main/kotlin/fr/azur/tcoww/utils/DataKeys.kt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package fr.azur.tcoww.utils
|
||||||
|
|
||||||
|
import fr.azur.tcoww.Tcoww
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
|
||||||
|
data object DataKeys {
|
||||||
|
val PlayerDead = NamespacedKey(Tcoww, "dead")
|
||||||
|
val PowerItems = NamespacedKey(Tcoww, "power")
|
||||||
|
val Insomnia = NamespacedKey(Tcoww, "insomnia")
|
||||||
|
val ToolsItems = NamespacedKey(Tcoww, "tools")
|
||||||
|
}
|
||||||
118
src/main/kotlin/fr/azur/tcoww/utils/Players.kt
Normal file
118
src/main/kotlin/fr/azur/tcoww/utils/Players.kt
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
package fr.azur.tcoww.utils
|
||||||
|
|
||||||
|
import fr.azur.tcoww.game.Game
|
||||||
|
import fr.azur.tcoww.roles.Role.Companion.werewolfRole
|
||||||
|
import fr.azur.tcoww.utils.skins.Manager
|
||||||
|
import io.papermc.paper.datacomponent.item.ResolvableProfile
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
|
import net.kyori.adventure.title.Title
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.GameMode
|
||||||
|
import org.bukkit.NamespacedKey
|
||||||
|
import org.bukkit.attribute.Attribute
|
||||||
|
import org.bukkit.attribute.AttributeModifier
|
||||||
|
import org.bukkit.entity.Mannequin
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.entity.Pose
|
||||||
|
import org.bukkit.persistence.PersistentDataType
|
||||||
|
import java.time.Duration
|
||||||
|
|
||||||
|
object Players {
|
||||||
|
private val transformKey = NamespacedKey("tcoww", "werewolf_transform")
|
||||||
|
val corpseKey = NamespacedKey("tcoww", "corpse")
|
||||||
|
val corpseRoleKey = NamespacedKey("tcoww", "corpse_role")
|
||||||
|
private val noCollisionTeam =
|
||||||
|
Bukkit
|
||||||
|
.getServer()
|
||||||
|
.scoreboardManager.mainScoreboard
|
||||||
|
.getTeam("NoCollide")
|
||||||
|
|
||||||
|
fun Player.tfWerewolf() {
|
||||||
|
if (isTransformed()) return
|
||||||
|
|
||||||
|
Manager.applyWerewolfFur(this)
|
||||||
|
|
||||||
|
persistentDataContainer.set(
|
||||||
|
transformKey,
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
|
||||||
|
val speedAtr = getAttribute(Attribute.MOVEMENT_SPEED)!!
|
||||||
|
val scaleAtr = getAttribute(Attribute.SCALE)!!
|
||||||
|
|
||||||
|
speedAtr.addModifier(
|
||||||
|
AttributeModifier(
|
||||||
|
transformKey,
|
||||||
|
0.02,
|
||||||
|
AttributeModifier.Operation.ADD_NUMBER,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
scaleAtr.addModifier(
|
||||||
|
AttributeModifier(
|
||||||
|
transformKey,
|
||||||
|
0.1,
|
||||||
|
AttributeModifier.Operation.ADD_NUMBER,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Player.tfHuman() {
|
||||||
|
if (!isTransformed()) return
|
||||||
|
|
||||||
|
Manager.unapplySkin(this)
|
||||||
|
|
||||||
|
persistentDataContainer.set(
|
||||||
|
transformKey,
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
|
||||||
|
val speedAtr = getAttribute(Attribute.MOVEMENT_SPEED)!!
|
||||||
|
val scaleAtr = getAttribute(Attribute.SCALE)!!
|
||||||
|
speedAtr.removeModifier(transformKey)
|
||||||
|
scaleAtr.removeModifier(transformKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Player.isTransformed(): Boolean =
|
||||||
|
persistentDataContainer.getOrDefault(
|
||||||
|
transformKey,
|
||||||
|
PersistentDataType.BOOLEAN,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Player.kill() {
|
||||||
|
if (isTransformed()) tfHuman()
|
||||||
|
|
||||||
|
val current = Game.current ?: return
|
||||||
|
|
||||||
|
val corpse = createCorpse(this)
|
||||||
|
corpse.spawnAt(this.location)
|
||||||
|
|
||||||
|
this.gameMode = GameMode.SPECTATOR
|
||||||
|
this.isInvulnerable = false
|
||||||
|
current.remainingPlayer.remove(this)
|
||||||
|
|
||||||
|
this.showTitle(
|
||||||
|
Title.title(
|
||||||
|
Component.text("Vous êtes mort.", NamedTextColor.DARK_RED),
|
||||||
|
Component.empty(),
|
||||||
|
Title.Times.times(Duration.ZERO, Duration.ofSeconds(2), Duration.ofMillis(500)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (current.checkGameEnd()) current.stopGame()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createCorpse(player: Player): Mannequin =
|
||||||
|
player.world.createEntity(player.location, Mannequin::class.java).apply {
|
||||||
|
profile = ResolvableProfile.resolvableProfile(player.playerProfile)
|
||||||
|
noCollisionTeam?.addEntity(this)
|
||||||
|
isInvulnerable = true
|
||||||
|
pose = Pose.SLEEPING
|
||||||
|
persistentDataContainer.set(corpseKey, PersistentDataType.BOOLEAN, true)
|
||||||
|
val role = player.werewolfRole
|
||||||
|
persistentDataContainer.set(corpseRoleKey, PersistentDataType.STRING, role.id.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package fr.azur.tcoww.utils
|
|
||||||
|
|
||||||
import net.skinsrestorer.api.SkinsRestorer
|
|
||||||
import net.skinsrestorer.api.property.SkinProperty
|
|
||||||
import org.bukkit.entity.Player
|
|
||||||
import org.bukkit.plugin.Plugin
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.jvm.optionals.getOrNull
|
|
||||||
import kotlin.random.Random
|
|
||||||
|
|
||||||
class Skin(private val plugin: Plugin, private val skinsRestorer: SkinsRestorer) {
|
|
||||||
|
|
||||||
var maxSkinId: Int = 0
|
|
||||||
private set
|
|
||||||
|
|
||||||
init {
|
|
||||||
reloadSkin()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun reloadSkin() {
|
|
||||||
val skinsValue = plugin.config.getStringList("wwskinsvalue")
|
|
||||||
val skinsSignature = plugin.config.getStringList("wwskinssignature")
|
|
||||||
Stockage.wwPlayerFur.clear()
|
|
||||||
|
|
||||||
maxSkinId = 0
|
|
||||||
skinsValue.zip(skinsSignature).forEachIndexed { index, (value, signature) ->
|
|
||||||
skinsRestorer.skinStorage.setCustomSkinData("tcoww_$index", SkinProperty.of(value, signature))
|
|
||||||
maxSkinId = index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun applyWerewolfFur(player: Player) {
|
|
||||||
val skin = skinsRestorer.playerStorage.getSkinIdOfPlayer(player.uniqueId)
|
|
||||||
Stockage.oldPlayerSkin[player.uniqueId] = skin.getOrNull()
|
|
||||||
|
|
||||||
val result = skinsRestorer.skinStorage.findOrCreateSkinData("tcoww_${getWerewolfFur(player.uniqueId)}")
|
|
||||||
|
|
||||||
if (!result.isEmpty) {
|
|
||||||
skinsRestorer.playerStorage.setSkinIdOfPlayer(player.uniqueId, result.get().identifier)
|
|
||||||
skinsRestorer.getSkinApplier(Player::class.java).applySkin(player)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun unApplySkin(player: Player) {
|
|
||||||
val skin = Stockage.oldPlayerSkin[player.uniqueId]
|
|
||||||
if (skin == null) {
|
|
||||||
skinsRestorer.playerStorage.removeSkinIdOfPlayer(player.uniqueId)
|
|
||||||
} else {
|
|
||||||
skinsRestorer.playerStorage.setSkinIdOfPlayer(player.uniqueId,skin)
|
|
||||||
}
|
|
||||||
skinsRestorer.getSkinApplier(Player::class.java).applySkin(player)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getWerewolfFur(playerUUID: UUID): Int {
|
|
||||||
return Stockage.wwPlayerFur[playerUUID]
|
|
||||||
?: randomFur(playerUUID)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun randomFur(playerUUID: UUID): Int {
|
|
||||||
val id = if (maxSkinId == 0) 0 else Random(playerUUID.mostSignificantBits xor playerUUID.leastSignificantBits).nextInt(maxSkinId)
|
|
||||||
Stockage.wwPlayerFur[playerUUID] = id
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package fr.azur.tcoww.utils
|
|
||||||
|
|
||||||
import net.skinsrestorer.api.property.SkinIdentifier
|
|
||||||
import org.bukkit.Location
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
object Stockage {
|
|
||||||
var backLocation = mutableMapOf<UUID, Location>()
|
|
||||||
var vote = mutableMapOf<UUID, UUID>()
|
|
||||||
var oldPlayerSkin = mutableMapOf<UUID, SkinIdentifier?>()
|
|
||||||
var wwPlayerFur = mutableMapOf<UUID, Int>()
|
|
||||||
}
|
|
||||||
58
src/main/kotlin/fr/azur/tcoww/utils/VoiceChatPlugin.kt
Normal file
58
src/main/kotlin/fr/azur/tcoww/utils/VoiceChatPlugin.kt
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package fr.azur.tcoww.utils
|
||||||
|
|
||||||
|
import de.maxhenkel.voicechat.api.Group
|
||||||
|
import de.maxhenkel.voicechat.api.VoicechatPlugin
|
||||||
|
import de.maxhenkel.voicechat.api.VoicechatServerApi
|
||||||
|
import de.maxhenkel.voicechat.api.events.EventRegistration
|
||||||
|
import de.maxhenkel.voicechat.api.events.VoicechatServerStartedEvent
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import java.util.UUID
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
object VoiceChatPlugin : VoicechatPlugin {
|
||||||
|
lateinit var api: VoicechatServerApi
|
||||||
|
lateinit var werewolfGroup: Group
|
||||||
|
|
||||||
|
override fun getPluginId(): String = "tcoww"
|
||||||
|
|
||||||
|
override fun registerEvents(registration: EventRegistration) {
|
||||||
|
registration.registerEvent(VoicechatServerStartedEvent::class.java, this::onServerStarted)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onServerStarted(event: VoicechatServerStartedEvent) {
|
||||||
|
api = event.voicechat
|
||||||
|
werewolfGroup =
|
||||||
|
api
|
||||||
|
.groupBuilder()
|
||||||
|
.setPersistent(true)
|
||||||
|
.setName("werewolf")
|
||||||
|
.setPassword(Random.nextInt().toString())
|
||||||
|
.setType(Group.Type.NORMAL)
|
||||||
|
.setHidden(true)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addWerewolf(player: Player) {
|
||||||
|
val connection = api.getConnectionOf(player.uniqueId) ?: return
|
||||||
|
connection.group = werewolfGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createSoloGroup(player: Player) {
|
||||||
|
val connection = api.getConnectionOf(player.uniqueId) ?: return
|
||||||
|
val soloGroup =
|
||||||
|
api
|
||||||
|
.groupBuilder()
|
||||||
|
.setName(UUID.randomUUID().toString())
|
||||||
|
.setHidden(true)
|
||||||
|
.setPassword(Random.nextInt().toString())
|
||||||
|
.setType(Group.Type.ISOLATED)
|
||||||
|
.setPersistent(false)
|
||||||
|
.build()
|
||||||
|
connection.group = soloGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
fun degroupPlayer(player: Player) {
|
||||||
|
val connection = api.getConnectionOf(player.uniqueId) ?: return
|
||||||
|
connection.group = null
|
||||||
|
}
|
||||||
|
}
|
||||||
77
src/main/kotlin/fr/azur/tcoww/utils/skins/Manager.kt
Normal file
77
src/main/kotlin/fr/azur/tcoww/utils/skins/Manager.kt
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package fr.azur.tcoww.utils.skins
|
||||||
|
|
||||||
|
import fr.azur.tcoww.Tcoww
|
||||||
|
import net.skinsrestorer.api.SkinsRestorer
|
||||||
|
import net.skinsrestorer.api.SkinsRestorerProvider
|
||||||
|
import net.skinsrestorer.api.property.SkinIdentifier
|
||||||
|
import net.skinsrestorer.api.property.SkinProperty
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import java.util.UUID
|
||||||
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
object Manager {
|
||||||
|
var maxSkinId: Int = 0
|
||||||
|
private lateinit var skinsRestorer: SkinsRestorer
|
||||||
|
var oldPlayerSkin = mutableMapOf<UUID, SkinIdentifier?>()
|
||||||
|
var wwPlayerFur = mutableMapOf<UUID, Int>()
|
||||||
|
|
||||||
|
fun handle() {
|
||||||
|
skinsRestorer = SkinsRestorerProvider.get()
|
||||||
|
reloadSkin()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reloadSkin() {
|
||||||
|
val skinsValue =
|
||||||
|
Tcoww.config
|
||||||
|
.getList("werewolf-skins")
|
||||||
|
.orEmpty()
|
||||||
|
.mapNotNull { it as? WerewolfSkin }
|
||||||
|
|
||||||
|
wwPlayerFur.clear()
|
||||||
|
|
||||||
|
maxSkinId = skinsValue.size
|
||||||
|
skinsValue.forEachIndexed { index, skin ->
|
||||||
|
skinsRestorer.skinStorage.setCustomSkinData("tcoww$index", SkinProperty.of(skin.value, skin.signature))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun applyWerewolfFur(player: Player) {
|
||||||
|
val skin = skinsRestorer.playerStorage.getSkinIdOfPlayer(player.uniqueId)
|
||||||
|
oldPlayerSkin[player.uniqueId] = skin.getOrNull()
|
||||||
|
|
||||||
|
val result = skinsRestorer.skinStorage.findOrCreateSkinData("tcoww_${getWerewolfFur(player.uniqueId)}")
|
||||||
|
|
||||||
|
if (!result.isEmpty) {
|
||||||
|
skinsRestorer.playerStorage.setSkinIdOfPlayer(player.uniqueId, result.get().identifier)
|
||||||
|
skinsRestorer.getSkinApplier(Player::class.java).applySkin(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unapplySkin(player: Player) {
|
||||||
|
val skin = oldPlayerSkin[player.uniqueId]
|
||||||
|
if (skin == null) {
|
||||||
|
skinsRestorer.playerStorage.removeSkinIdOfPlayer(player.uniqueId)
|
||||||
|
} else {
|
||||||
|
skinsRestorer.playerStorage.setSkinIdOfPlayer(player.uniqueId, skin)
|
||||||
|
}
|
||||||
|
skinsRestorer.getSkinApplier(Player::class.java).applySkin(player)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getWerewolfFur(playerUUID: UUID): Int =
|
||||||
|
wwPlayerFur[playerUUID]
|
||||||
|
?: randomFur(playerUUID)
|
||||||
|
|
||||||
|
private fun randomFur(playerUUID: UUID): Int {
|
||||||
|
val id =
|
||||||
|
if (maxSkinId == 0) {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
Random(playerUUID.mostSignificantBits xor playerUUID.leastSignificantBits).nextInt(
|
||||||
|
maxSkinId,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
wwPlayerFur[playerUUID] = id
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/main/kotlin/fr/azur/tcoww/utils/skins/WerewolfSkin.kt
Normal file
22
src/main/kotlin/fr/azur/tcoww/utils/skins/WerewolfSkin.kt
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package fr.azur.tcoww.utils.skins
|
||||||
|
|
||||||
|
import org.bukkit.configuration.serialization.ConfigurationSerializable
|
||||||
|
|
||||||
|
data class WerewolfSkin(
|
||||||
|
val value: String,
|
||||||
|
val signature: String,
|
||||||
|
) : ConfigurationSerializable {
|
||||||
|
constructor(args: MutableMap<String, Object>) : this(
|
||||||
|
args["value"] as String,
|
||||||
|
args["signature"] as String,
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun serialize(): Map<String, String> {
|
||||||
|
val data: MutableMap<String, String> = HashMap()
|
||||||
|
|
||||||
|
data["value"] = value
|
||||||
|
data["signature"] = signature
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package fr.azur.tcoww.voicechat
|
|
||||||
|
|
||||||
import de.maxhenkel.voicechat.api.VoicechatPlugin
|
|
||||||
import de.maxhenkel.voicechat.api.events.EventRegistration
|
|
||||||
|
|
||||||
class VoiceChatPlugin: VoicechatPlugin {
|
|
||||||
override fun getPluginId(): String {
|
|
||||||
return "tcow"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun registerEvents(registration: EventRegistration) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +1,35 @@
|
|||||||
spawnLocation:
|
# Bukkit Location
|
||||||
==: org.bukkit.Location
|
spawn-location: null
|
||||||
world: world
|
|
||||||
x: 0.0
|
# Bukkit Location
|
||||||
y: 0.0
|
lobby-location: null
|
||||||
z: 0.0
|
|
||||||
pitch: 0.0
|
# List of Bukkit Location
|
||||||
yaw: 0.0
|
bed-locations: null
|
||||||
lobbyLocation:
|
|
||||||
==: org.bukkit.Location
|
|
||||||
world: world
|
|
||||||
x: 0.0
|
|
||||||
y: 0.0
|
|
||||||
z: 0.0
|
|
||||||
pitch: 0.0
|
|
||||||
yaw: 0.0
|
|
||||||
duration: # In seconds
|
duration: # In seconds
|
||||||
day: 600
|
day: 600
|
||||||
vote: 120
|
vote: 120
|
||||||
night: 300
|
night: 300
|
||||||
crepuscular: 20
|
crepuscular: 20
|
||||||
wwcount: 10
|
|
||||||
|
werewolf-default-percentage: 20
|
||||||
|
|
||||||
# The skin value
|
# The skin value
|
||||||
wwskinsvalue: [
|
|
||||||
"ewogICJ0aW1lc3RhbXAiIDogMTYxNzQ2NzI1ODQxMCwKICAicHJvZmlsZUlkIiA6ICJjMGYzYjI3YTUwMDE0YzVhYjIxZDc5ZGRlMTAxZGZlMiIsCiAgInByb2ZpbGVOYW1lIiA6ICJDVUNGTDEzIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2Y5NmM4OWUwZWYwZmVlZjZkODc4ZDUzYzQ4OWIyMzliNDdlNmViODQyZDJmM2MzZTlhZDdkMjliZmYxYTM0OWUiCiAgICB9CiAgfQp9",
|
|
||||||
"ewogICJ0aW1lc3RhbXAiIDogMTYxNTYxMTkwOTY4MCwKICAicHJvZmlsZUlkIiA6ICIwMGM2Yjk0YTY5YmU0MzY3OTkwOTQxNjFjMjAxOWI3ZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJLQUVWRVJZIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2I0MGRjNTcxZGUwZGQ4ZmQ5NzBjNzNmOTE2NGJjMTQ0Njk1MWFlNDhkNWFiZTQyMzI5MGVlYjFhODc4NDU1ZmUiCiAgICB9CiAgfQp9",
|
|
||||||
"ewogICJ0aW1lc3RhbXAiIDogMTc0Nzk4MDc5ODQyMywKICAicHJvZmlsZUlkIiA6ICI2NWI5NTU1YWQyMGU0NWM5YjFkNmU3MjQwNjU0NTBkNCIsCiAgInByb2ZpbGVOYW1lIiA6ICJKYXZhUHJvZmlsZU5hbWVYIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzJlZTlmNjcxYzFmNjY4Y2IwYWUwNGE5YzhiZWM0OTVlYTVmNzNmNTNmYmY3ZjM5MmNkYjdlMTc1ZmVjZDFjYmUiCiAgICB9CiAgfQp9",
|
|
||||||
"ewogICJ0aW1lc3RhbXAiIDogMTY0Mjc4ODk3NDg1NSwKICAicHJvZmlsZUlkIiA6ICIzYzE0YmVkNDFiOGE0MDIzOGM3MDgzMTA1NzEwMTZmYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJOb2Jpa28iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYWZlNzIzMDdjZTEyNmI1Y2I0ZDQ0ZGFlZTcwZDI1ZmQwNDMwOGJjN2M0MzI4OWM3ZDk3MDY4NDY5NWI2MGJhIgogICAgfQogIH0KfQ=="
|
|
||||||
]
|
|
||||||
# The skin signature (see mineskin.org)
|
# The skin signature (see mineskin.org)
|
||||||
wwskinssignature: [
|
werewolf-skins:
|
||||||
"uWIu/2R3zImj87H7x//O/04eJ1SwsHvLSxaj1YQuI1vBndUVHhN42Ja7AOJoAieVO8yN1qn/rJj1oK5z5koQ2fZwjNCc0mKTrakCMWGqjaAImDw8RWriUQ3ClPCw6NtCmB1qVUp60kUEpGha/btUSsAEUnVZ0ghM4SXTcS2izbDe/dRfbi5EDr2Uue3sz6+med3hjecZzrKJUX19wP1WwPifEOH2X/smzzGOdqlQtylMZQh3nNeho/GBwbDVXsXsR6LcDgoInDnw63cDV7n4dTs6giGmcx0knhDWH24Z/vrgNSqzbNY9hIgVBNWUqs/1o7/xrbK1HilYBPAiVO0F6+vJOpzdFrpEZVr0M++u+X2Zkt1sfshKZqt0O07KbH8h4xj3J+6iDF5RHHFGmZy0awFGZGIi8wqlffwQfZ+l7nPU1hpMD5DkArxBWJWgnquyCNpQ44OlmTpPRa/gopRpuMwJ1r6vDPhgIavJX6cKQ2lKTYKG2/HB+ZEl/IUtuXxKO7bFe4KOvjJpMwBjOmzqbn2sk3GqbSg8NfNMFA4FjRBvHXOaMsDCqz0MJxLFKvIfYRVWG8XAU6BU82RoS3qGFSOhI6N/DvD7dx1V40q52iWv2j4/S41P5zrtMqQm7wofocptz6sS7GLE1u9rPCBLRIck0wzi3OF7MV2p4wlw6lw=",
|
- ==: fr.azur.tcoww.utils.skins.WerewolfSkin
|
||||||
"kVGwx98YPc6tIZ306TiGI5eoK4v7oEjIvCaOPS03jq4LjBWV12NBTWW67u+HrI2/2m3r8pvAyx1Ddpw4YWyaDbaG0FvLuurWbETqtwvyvVx7R3BZHgw2EnVOYk4+WPmA8xUgzoIbZF/Ch4bSqP7UlZy7/fz4AQwFK/qLMzApOAeV4Kzn4p6+MK2uOkfSjGgwxqAO/+TZj6u01mk1NKNh4ors9RGDG3DBHZKSxTG/PzY5ErKABRXkB/RBMA5IvU5Rzn5cH+Sfkus/7LtYp5u+5i+HcpN/klyBBw4D5di3WzFOAIX78ZiyKzKzWpSN0z6Cb2DZdo1ufeZH9mw8nv+A8VfpGXwphwde+oGBP4l4OffE7YvbnWyVHmlG0L36iI2/FkWQl91GIT15YBHrjeQ9pmvbzCQUMyAHi2jZePTTcT1rDnSzBk7fc9IwfcBRNyqbveTNu9zikfx0W6GnXAbV4qOTIIVEHlpxQ9KW017sqmgiF5l/3ZVwqbEQzglNehYHA55vRfKY0HKbGB54k1oTnM3X7mNXIu6fk8dVgCvT8lVdDm3LWcE6aWF8Yp6QrXNvTNW1yxSRAhigsHrvbajp2Odg18lMTng0oh/4JiYOQAgb6tFdRtQ4nrSVHRBOEvY09IRFzVTTd7n2JaYZ6QcCMOiKOX25fv22rbjSeAZ/Whk=",
|
value: "ewogICJ0aW1lc3RhbXAiIDogMTYxNzQ2NzI1ODQxMCwKICAicHJvZmlsZUlkIiA6ICJjMGYzYjI3YTUwMDE0YzVhYjIxZDc5ZGRlMTAxZGZlMiIsCiAgInByb2ZpbGVOYW1lIiA6ICJDVUNGTDEzIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2Y5NmM4OWUwZWYwZmVlZjZkODc4ZDUzYzQ4OWIyMzliNDdlNmViODQyZDJmM2MzZTlhZDdkMjliZmYxYTM0OWUiCiAgICB9CiAgfQp9"
|
||||||
"wGc2rNbc7+nziEDMKFoBIltHZwx5PQfsfMGyRTfTUdtVi3O4iu0idcpTsTVJ80njIFZvmLpzlwjPu6ULrXJwgQQyGCNdp60jQMl9vGjzgJzs6uqhSCke3EvjOCuAGkv2ScRY5hDGQOnIruxwmgYgDeXHnujt+zTBvW+imxLVaZhXoKVPyqlvm6njWp0XECyAi8DFKbzIdDVp+NsRzIGjKeVoMgWd4xlNazUZGgTsXNCD/+aZOJ1LxA51I8Wgsm888MUXnaGhNI3U4jJNKHAPZMS4++JEuwWzlptJdZIa1jOfwMD6HvIPKEmC5+eDCRFvPIEh84VqErtNTPEUAz7wZAJvO+j+x5A/9VnQmKJhEBxBjlw1Ky+mQcLJnRX/x9jc4EvEd9gWGIUj46y3IF8jWn71eXvinSJ4Op4LQEiv5BfuyMTfY2xwFTlGWjdYF6Xnac+Gz6+E1gjCBSuqKWd56QFDcrqCcvbG50ERhenCUEhUgI33rXNxS/hwz2iClVM26GFJlUtZkZ7/021FjEQNLEYivI1ZkHe9ip8sxx2QVKd5k7Ui/hXkP4xSal3okL4Ar/cThMh0aoWzziYsoAahtoxFWEags7lNOffMoLGmPbgGVRUGHogNu2CES0SNs4AhHVUVERo8OTJHx46XJxXqvLzeEn6zXFD63XXQR8AyXTQ=",
|
signature: "uWIu/2R3zImj87H7x//O/04eJ1SwsHvLSxaj1YQuI1vBndUVHhN42Ja7AOJoAieVO8yN1qn/rJj1oK5z5koQ2fZwjNCc0mKTrakCMWGqjaAImDw8RWriUQ3ClPCw6NtCmB1qVUp60kUEpGha/btUSsAEUnVZ0ghM4SXTcS2izbDe/dRfbi5EDr2Uue3sz6+med3hjecZzrKJUX19wP1WwPifEOH2X/smzzGOdqlQtylMZQh3nNeho/GBwbDVXsXsR6LcDgoInDnw63cDV7n4dTs6giGmcx0knhDWH24Z/vrgNSqzbNY9hIgVBNWUqs/1o7/xrbK1HilYBPAiVO0F6+vJOpzdFrpEZVr0M++u+X2Zkt1sfshKZqt0O07KbH8h4xj3J+6iDF5RHHFGmZy0awFGZGIi8wqlffwQfZ+l7nPU1hpMD5DkArxBWJWgnquyCNpQ44OlmTpPRa/gopRpuMwJ1r6vDPhgIavJX6cKQ2lKTYKG2/HB+ZEl/IUtuXxKO7bFe4KOvjJpMwBjOmzqbn2sk3GqbSg8NfNMFA4FjRBvHXOaMsDCqz0MJxLFKvIfYRVWG8XAU6BU82RoS3qGFSOhI6N/DvD7dx1V40q52iWv2j4/S41P5zrtMqQm7wofocptz6sS7GLE1u9rPCBLRIck0wzi3OF7MV2p4wlw6lw="
|
||||||
"hJ/FhIMQY9G/BqOvGJ0nhuJk/7Y/q/unCpeC7LxGvcYjXzsY/kcInwUzgfjRqNI0oI5ggOAdxIiaGvBRqWCshjxcx6iRyJZBMKwFchM1baHntRl22yxvBA16gpMxbWTihQ0Jtz9m/Dj8clYgyEkMOKFEOya5YiyyqjK+YOl5xWiM1pGAomFixqr7VBLk/NE7e+qYXuFjDl3IZ1OP+tgdgyjkqUZE3OBGQfXP6wvTFjgk/maCPUmzffnbw/yH4JZIa3N/vhK+jzowcV+ymZK/9+10ge8hIZ5LZPdU90xLWd2zPYFjju/vr9TFWUG4YkV8l1vSsG7P8MYjMKFh/YQoTyyjJUZw9YGfnRENZrdegttUxefJywpBgp0xVt5vyAMM9XjTEtwK/A5gef0fD52lKWpwD6xamPBnhb8yRPUnncapGBrQvFhB8uQnkS8BKqtiJyz8XJHg8quzUXjYd+Ywn5p+lzP5zsDXQDYOfcm4FZGYp3oFwJZz1s4YOjP8Abjd+4v0sQIcP+Kj8lBzrADQSvTIJaQZO/emnpkZYoW/ggSJLa+BrRUXK5gNHdZzUI/EDOJggrGn3ezSLd96DyDlosG+lGM/EpuiB504YNzQfrm1scVbk9R4YHNhy+sau04DJcRY0p52qeaVDswMkfjUA6JBvBFT9SqQeB7q9qRwLrk="
|
- ==: fr.azur.tcoww.utils.skins.WerewolfSkin
|
||||||
]
|
value: "ewogICJ0aW1lc3RhbXAiIDogMTYxNTYxMTkwOTY4MCwKICAicHJvZmlsZUlkIiA6ICIwMGM2Yjk0YTY5YmU0MzY3OTkwOTQxNjFjMjAxOWI3ZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJLQUVWRVJZIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2I0MGRjNTcxZGUwZGQ4ZmQ5NzBjNzNmOTE2NGJjMTQ0Njk1MWFlNDhkNWFiZTQyMzI5MGVlYjFhODc4NDU1ZmUiCiAgICB9CiAgfQp9"
|
||||||
|
signature: "kVGwx98YPc6tIZ306TiGI5eoK4v7oEjIvCaOPS03jq4LjBWV12NBTWW67u+HrI2/2m3r8pvAyx1Ddpw4YWyaDbaG0FvLuurWbETqtwvyvVx7R3BZHgw2EnVOYk4+WPmA8xUgzoIbZF/Ch4bSqP7UlZy7/fz4AQwFK/qLMzApOAeV4Kzn4p6+MK2uOkfSjGgwxqAO/+TZj6u01mk1NKNh4ors9RGDG3DBHZKSxTG/PzY5ErKABRXkB/RBMA5IvU5Rzn5cH+Sfkus/7LtYp5u+5i+HcpN/klyBBw4D5di3WzFOAIX78ZiyKzKzWpSN0z6Cb2DZdo1ufeZH9mw8nv+A8VfpGXwphwde+oGBP4l4OffE7YvbnWyVHmlG0L36iI2/FkWQl91GIT15YBHrjeQ9pmvbzCQUMyAHi2jZePTTcT1rDnSzBk7fc9IwfcBRNyqbveTNu9zikfx0W6GnXAbV4qOTIIVEHlpxQ9KW017sqmgiF5l/3ZVwqbEQzglNehYHA55vRfKY0HKbGB54k1oTnM3X7mNXIu6fk8dVgCvT8lVdDm3LWcE6aWF8Yp6QrXNvTNW1yxSRAhigsHrvbajp2Odg18lMTng0oh/4JiYOQAgb6tFdRtQ4nrSVHRBOEvY09IRFzVTTd7n2JaYZ6QcCMOiKOX25fv22rbjSeAZ/Whk="
|
||||||
|
- ==: fr.azur.tcoww.utils.skins.WerewolfSkin
|
||||||
|
value: "ewogICJ0aW1lc3RhbXAiIDogMTc0Nzk4MDc5ODQyMywKICAicHJvZmlsZUlkIiA6ICI2NWI5NTU1YWQyMGU0NWM5YjFkNmU3MjQwNjU0NTBkNCIsCiAgInByb2ZpbGVOYW1lIiA6ICJKYXZhUHJvZmlsZU5hbWVYIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzJlZTlmNjcxYzFmNjY4Y2IwYWUwNGE5YzhiZWM0OTVlYTVmNzNmNTNmYmY3ZjM5MmNkYjdlMTc1ZmVjZDFjYmUiCiAgICB9CiAgfQp9"
|
||||||
|
signature: "wGc2rNbc7+nziEDMKFoBIltHZwx5PQfsfMGyRTfTUdtVi3O4iu0idcpTsTVJ80njIFZvmLpzlwjPu6ULrXJwgQQyGCNdp60jQMl9vGjzgJzs6uqhSCke3EvjOCuAGkv2ScRY5hDGQOnIruxwmgYgDeXHnujt+zTBvW+imxLVaZhXoKVPyqlvm6njWp0XECyAi8DFKbzIdDVp+NsRzIGjKeVoMgWd4xlNazUZGgTsXNCD/+aZOJ1LxA51I8Wgsm888MUXnaGhNI3U4jJNKHAPZMS4++JEuwWzlptJdZIa1jOfwMD6HvIPKEmC5+eDCRFvPIEh84VqErtNTPEUAz7wZAJvO+j+x5A/9VnQmKJhEBxBjlw1Ky+mQcLJnRX/x9jc4EvEd9gWGIUj46y3IF8jWn71eXvinSJ4Op4LQEiv5BfuyMTfY2xwFTlGWjdYF6Xnac+Gz6+E1gjCBSuqKWd56QFDcrqCcvbG50ERhenCUEhUgI33rXNxS/hwz2iClVM26GFJlUtZkZ7/021FjEQNLEYivI1ZkHe9ip8sxx2QVKd5k7Ui/hXkP4xSal3okL4Ar/cThMh0aoWzziYsoAahtoxFWEags7lNOffMoLGmPbgGVRUGHogNu2CES0SNs4AhHVUVERo8OTJHx46XJxXqvLzeEn6zXFD63XXQR8AyXTQ="
|
||||||
|
- ==: fr.azur.tcoww.utils.skins.WerewolfSkin
|
||||||
|
value: "ewogICJ0aW1lc3RhbXAiIDogMTY0Mjc4ODk3NDg1NSwKICAicHJvZmlsZUlkIiA6ICIzYzE0YmVkNDFiOGE0MDIzOGM3MDgzMTA1NzEwMTZmYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJOb2Jpa28iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYWZlNzIzMDdjZTEyNmI1Y2I0ZDQ0ZGFlZTcwZDI1ZmQwNDMwOGJjN2M0MzI4OWM3ZDk3MDY4NDY5NWI2MGJhIgogICAgfQogIH0KfQ=="
|
||||||
|
signature: "hJ/FhIMQY9G/BqOvGJ0nhuJk/7Y/q/unCpeC7LxGvcYjXzsY/kcInwUzgfjRqNI0oI5ggOAdxIiaGvBRqWCshjxcx6iRyJZBMKwFchM1baHntRl22yxvBA16gpMxbWTihQ0Jtz9m/Dj8clYgyEkMOKFEOya5YiyyqjK+YOl5xWiM1pGAomFixqr7VBLk/NE7e+qYXuFjDl3IZ1OP+tgdgyjkqUZE3OBGQfXP6wvTFjgk/maCPUmzffnbw/yH4JZIa3N/vhK+jzowcV+ymZK/9+10ge8hIZ5LZPdU90xLWd2zPYFjju/vr9TFWUG4YkV8l1vSsG7P8MYjMKFh/YQoTyyjJUZw9YGfnRENZrdegttUxefJywpBgp0xVt5vyAMM9XjTEtwK/A5gef0fD52lKWpwD6xamPBnhb8yRPUnncapGBrQvFhB8uQnkS8BKqtiJyz8XJHg8quzUXjYd+Ywn5p+lzP5zsDXQDYOfcm4FZGYp3oFwJZz1s4YOjP8Abjd+4v0sQIcP+Kj8lBzrADQSvTIJaQZO/emnpkZYoW/ggSJLa+BrRUXK5gNHdZzUI/EDOJggrGn3ezSLd96DyDlosG+lGM/EpuiB504YNzQfrm1scVbk9R4YHNhy+sau04DJcRY0p52qeaVDswMkfjUA6JBvBFT9SqQeB7q9qRwLrk="
|
||||||
|
|
||||||
# The time in second before teleport no sleeping player
|
# The time in second before teleport no sleeping player
|
||||||
playerSleep: 20
|
player-sleep: 30
|
||||||
@@ -9,8 +9,9 @@ dependencies:
|
|||||||
server:
|
server:
|
||||||
SkinsRestorer:
|
SkinsRestorer:
|
||||||
load: BEFORE
|
load: BEFORE
|
||||||
required: true
|
required: false
|
||||||
join-classpath: true
|
join-classpath: true
|
||||||
voicechat:
|
voicechat:
|
||||||
load: BEFORE
|
load: BEFORE
|
||||||
required: true
|
required: false
|
||||||
|
join-classpath: true
|
||||||
Reference in New Issue
Block a user