🦋 Debugging for the 1.2.
All checks were successful
Auto Build / Build (push) Successful in 2m40s

This commit is contained in:
2025-12-06 16:40:12 +01:00
parent d6103b078b
commit 97b73b0c55
17 changed files with 182 additions and 101 deletions

View File

@@ -2,6 +2,7 @@ package fr.azur.tcoww
import de.maxhenkel.voicechat.api.BukkitVoicechatService import de.maxhenkel.voicechat.api.BukkitVoicechatService
import fr.azur.tcoww.events.GameEvents import fr.azur.tcoww.events.GameEvents
import fr.azur.tcoww.events.PhaseEvents
import fr.azur.tcoww.events.PowerEvents import fr.azur.tcoww.events.PowerEvents
import fr.azur.tcoww.events.ToolsEvents import fr.azur.tcoww.events.ToolsEvents
import fr.azur.tcoww.events.UIEvents import fr.azur.tcoww.events.UIEvents
@@ -36,6 +37,7 @@ class Tcoww : JavaPlugin() {
registerEvents(GameEvents, this@Tcoww) registerEvents(GameEvents, this@Tcoww)
registerEvents(PowerEvents, this@Tcoww) registerEvents(PowerEvents, this@Tcoww)
registerEvents(ToolsEvents, this@Tcoww) registerEvents(ToolsEvents, this@Tcoww)
registerEvents(PhaseEvents, this@Tcoww)
} }
val service = server.servicesManager.load(BukkitVoicechatService::class.java) val service = server.servicesManager.load(BukkitVoicechatService::class.java)
@@ -44,7 +46,7 @@ class Tcoww : JavaPlugin() {
registerRoles() registerRoles()
val mainScoreboard = server.scoreboardManager.mainScoreboard val mainScoreboard = server.scoreboardManager.mainScoreboard
if (mainScoreboard.getTeam("NoCollide") == null) { if (mainScoreboard.getTeam("NoCollision") == null) {
val team = server.scoreboardManager.mainScoreboard.registerNewTeam("NoCollision") val team = server.scoreboardManager.mainScoreboard.registerNewTeam("NoCollision")
team.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER) team.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER)
} }
@@ -55,6 +57,7 @@ class Tcoww : JavaPlugin() {
fun reload() { fun reload() {
this.reloadConfig() this.reloadConfig()
Manager.reloadSkin()
} }
private fun registerRoles() { private fun registerRoles() {

View File

@@ -7,6 +7,7 @@ import fr.azur.tcoww.game.NightLightCycle
import fr.azur.tcoww.roles.Child import fr.azur.tcoww.roles.Child
import fr.azur.tcoww.roles.Role import fr.azur.tcoww.roles.Role
import fr.azur.tcoww.roles.Role.Companion.werewolfRole import fr.azur.tcoww.roles.Role.Companion.werewolfRole
import fr.azur.tcoww.roles.Werewolf
import fr.azur.tcoww.roles.Witch import fr.azur.tcoww.roles.Witch
import fr.azur.tcoww.utils.DataKeys.Insomnia import fr.azur.tcoww.utils.DataKeys.Insomnia
import fr.azur.tcoww.utils.DataKeys.PlayerDead import fr.azur.tcoww.utils.DataKeys.PlayerDead
@@ -28,6 +29,7 @@ import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority import org.bukkit.event.EventPriority
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.entity.EntityDamageByEntityEvent import org.bukkit.event.entity.EntityDamageByEntityEvent
import org.bukkit.event.entity.EntityRegainHealthEvent
import org.bukkit.event.entity.PlayerDeathEvent import org.bukkit.event.entity.PlayerDeathEvent
import org.bukkit.event.player.PlayerBedEnterEvent import org.bukkit.event.player.PlayerBedEnterEvent
import org.bukkit.event.player.PlayerBedLeaveEvent import org.bukkit.event.player.PlayerBedLeaveEvent
@@ -101,18 +103,17 @@ object GameEvents : Listener {
PersistentDataType.INTEGER, PersistentDataType.INTEGER,
) == 2 && ) == 2 &&
(it.itemMeta as Damageable).damage != 1 (it.itemMeta as Damageable).damage != 1
} } ?: return@callback
if (player.persistentDataContainer.get( if (player.persistentDataContainer.get(
PlayerDead, PlayerDead,
PersistentDataType.BOOLEAN, PersistentDataType.BOOLEAN,
) == true ) == false
) { ) {
return@callback return@callback
} }
if (item == null) return@callback
(item.itemMeta as Damageable).damage = 1 player.inventory.remove(item)
player.persistentDataContainer.set( player.persistentDataContainer.set(
NamespacedKey("tcoww", "dead"), NamespacedKey("tcoww", "dead"),
@@ -144,7 +145,7 @@ object GameEvents : Listener {
@EventHandler @EventHandler
fun onHit(event: EntityDamageByEntityEvent) { fun onHit(event: EntityDamageByEntityEvent) {
val current = Game.current ?: return val current = Game.current ?: return
if (current.timeGestion.phase != NightLightCycle.Phase.NIGHT) return if (current.timeGestion.phase != NightLightCycle.Phase.NIGHT || Werewolf.remainingKill < 1) return
val damager = event.damager val damager = event.damager
val target = event.entity val target = event.entity
@@ -159,6 +160,7 @@ object GameEvents : Listener {
target.health = 0.0 target.health = 0.0
target.persistentDataContainer.set(Insomnia, PersistentDataType.BOOLEAN, true) target.persistentDataContainer.set(Insomnia, PersistentDataType.BOOLEAN, true)
if (target.isSleeping) target.wakeup(false) if (target.isSleeping) target.wakeup(false)
Werewolf.remainingKill--
} }
} }
@@ -244,4 +246,13 @@ object GameEvents : Listener {
} }
} }
} }
@EventHandler
fun disablePotionRegen(event: EntityRegainHealthEvent) {
val player = event.entity as? Player ?: return
if (player.hasPotionEffect(PotionEffectType.WITHER)) {
event.isCancelled = true
}
}
} }

View File

@@ -7,10 +7,12 @@ import fr.azur.tcoww.game.NightLightCycle
import fr.azur.tcoww.roles.Child import fr.azur.tcoww.roles.Child
import fr.azur.tcoww.roles.Role import fr.azur.tcoww.roles.Role
import fr.azur.tcoww.roles.Role.Companion.werewolfRole import fr.azur.tcoww.roles.Role.Companion.werewolfRole
import fr.azur.tcoww.roles.Werewolf
import fr.azur.tcoww.utils.BedGestion.isOccupied import fr.azur.tcoww.utils.BedGestion.isOccupied
import fr.azur.tcoww.utils.DataKeys.Insomnia import fr.azur.tcoww.utils.DataKeys.Insomnia
import fr.azur.tcoww.utils.DataKeys.PlayerDead import fr.azur.tcoww.utils.DataKeys.PlayerDead
import fr.azur.tcoww.utils.DataKeys.PowerItems import fr.azur.tcoww.utils.DataKeys.PowerItems
import fr.azur.tcoww.utils.Players.corpseKey
import fr.azur.tcoww.utils.Players.isTransformed import fr.azur.tcoww.utils.Players.isTransformed
import fr.azur.tcoww.utils.Players.kill import fr.azur.tcoww.utils.Players.kill
import fr.azur.tcoww.utils.Players.tfHuman import fr.azur.tcoww.utils.Players.tfHuman
@@ -59,23 +61,39 @@ object PhaseEvents : Listener {
} }
NightLightCycle.Phase.VOTE -> { NightLightCycle.Phase.VOTE -> {
event.world.entities
.filter {
it.persistentDataContainer.getOrDefault(
corpseKey,
PersistentDataType.BOOLEAN,
false,
)
}.forEach { it.remove() }
event.world.players.forEach { player -> event.world.players.forEach { player ->
player.sendMessage( if (event.dayCount >= 1) {
Component player.sendMessage(
.text("Le jour se couche, ce soir un vote est organisé.") Component
.color(NamedTextColor.DARK_AQUA) .text("Le jour se couche, ce soir un vote est organisé.")
.appendNewline() .color(NamedTextColor.DARK_AQUA)
.append( .appendNewline()
Component .append(
.text("Faite /vote <pseudo> pour voter.") Component
.color(NamedTextColor.AQUA), .text("Faite /vote pour voter.")
), .color(NamedTextColor.AQUA),
) ),
)
} else {
player.sendMessage(
Component
.text("Le jour se couche, ce soir aucun vote n'est organisé. Faute de preuve.", NamedTextColor.DARK_AQUA),
)
}
} }
} }
NightLightCycle.Phase.NIGHT -> { NightLightCycle.Phase.NIGHT -> {
if (Vote.vote.isNotEmpty()) { if (Vote.vote.isNotEmpty() && current.timeGestion.dayCount >= 1) {
val voteMap = val voteMap =
Vote.vote.values Vote.vote.values
.groupingBy { it } .groupingBy { it }
@@ -103,6 +121,8 @@ object PhaseEvents : Listener {
Vote.vote.clear() Vote.vote.clear()
} }
Werewolf.remainingKill = 1
event.world.players.forEach { player -> event.world.players.forEach { player ->
player.sendMessage( player.sendMessage(
Component Component
@@ -148,7 +168,7 @@ object PhaseEvents : Listener {
} }
} }
}, },
Tcoww.instance.config.getLong("player-sleep"), Tcoww.instance.config.getLong("player-sleep") * 20,
) )
} }

View File

@@ -18,7 +18,6 @@ import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryMoveItemEvent import org.bukkit.event.inventory.InventoryMoveItemEvent
import org.bukkit.event.player.PlayerDropItemEvent import org.bukkit.event.player.PlayerDropItemEvent
import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.inventory.meta.Damageable
import org.bukkit.persistence.PersistentDataType 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
@@ -51,10 +50,11 @@ object PowerEvents : Listener {
fun clickEvent(event: PlayerInteractEvent) { fun clickEvent(event: PlayerInteractEvent) {
val item = event.item ?: return val item = event.item ?: return
val player = event.player val player = event.player
if (!item.persistentDataContainer.has(NamespacedKey("tcoww", "power"))) return
event.isCancelled = true
if (player.hasCooldown(item)) return if (player.hasCooldown(item)) return
when (item.persistentDataContainer.get(NamespacedKey("tcoww", "power"), PersistentDataType.INTEGER)) { when (item.persistentDataContainer.get(NamespacedKey("tcoww", "power"), PersistentDataType.INTEGER)) {
1 -> { 1 -> {
if ((item.itemMeta as Damageable).damage == 1) return
val current = Game.current ?: return val current = Game.current ?: return
val menu = PlayerSelectMenu(current.remainingPlayer) val menu = PlayerSelectMenu(current.remainingPlayer)
@@ -62,15 +62,13 @@ object PowerEvents : Listener {
menu.future.whenComplete { selectedPlayer, _ -> menu.future.whenComplete { selectedPlayer, _ ->
val target = selectedPlayer ?: return@whenComplete val target = selectedPlayer ?: return@whenComplete
(item.itemMeta as Damageable).damage = 1 player.inventory.remove(item)
target.addPotionEffect(PotionEffect(PotionEffectType.WITHER, 600, 4)) target.addPotionEffect(PotionEffect(PotionEffectType.WITHER, 600, 4))
} }
} }
2 -> { 2 -> {
if ((item.itemMeta as Damageable).damage == 1) return
val current = Game.current ?: return val current = Game.current ?: return
val menu = val menu =
PlayerSelectMenu( PlayerSelectMenu(
current.remainingPlayer.filter { current.remainingPlayer.filter {
@@ -85,7 +83,7 @@ object PowerEvents : Listener {
menu.future.whenComplete { selectedPlayer, _ -> menu.future.whenComplete { selectedPlayer, _ ->
val target = selectedPlayer ?: return@whenComplete val target = selectedPlayer ?: return@whenComplete
(item.itemMeta as Damageable).damage = 1 player.inventory.remove(item)
target.persistentDataContainer.set( target.persistentDataContainer.set(
NamespacedKey("tcoww", "dead"), NamespacedKey("tcoww", "dead"),
PersistentDataType.BOOLEAN, PersistentDataType.BOOLEAN,
@@ -104,13 +102,12 @@ object PowerEvents : Listener {
} }
3 -> { 3 -> {
player.setCooldown(item, 600)
if (player.isTransformed()) { if (player.isTransformed()) {
player.tfHuman() player.tfHuman()
} else { } else {
player.tfWerewolf() player.tfWerewolf()
} }
player.setCooldown(item, 200)
} }
4 -> { 4 -> {

View File

@@ -3,6 +3,8 @@ package fr.azur.tcoww.game
import fr.azur.tcoww.Tcoww import fr.azur.tcoww.Tcoww
import fr.azur.tcoww.roles.Role import fr.azur.tcoww.roles.Role
import fr.azur.tcoww.roles.Role.Companion.werewolfRole import fr.azur.tcoww.roles.Role.Companion.werewolfRole
import fr.azur.tcoww.utils.DataKeys.Insomnia
import fr.azur.tcoww.utils.DataKeys.PlayerDead
import fr.azur.tcoww.utils.Players.tfHuman 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
@@ -73,7 +75,7 @@ class Game(
} }
fun checkGameEnd(): Boolean { fun checkGameEnd(): Boolean {
val team = players.map { player -> player.werewolfRole.team }.toSet() val team = remainingPlayer.map { player -> player.werewolfRole.team }.toSet()
return team.count() <= 1 return team.count() <= 1
} }
@@ -82,33 +84,26 @@ class Game(
current = null current = null
timeGestion.stop() timeGestion.stop()
world.time = 18000 world.time = 18000
val endComponent =
Component
.text("La partie est terminée !", NamedTextColor.DARK_GREEN)
val winComponent =
Component
.text("Victoire des ", NamedTextColor.DARK_GREEN)
.append(remainingPlayer[0].werewolfRole.team.displayName)
.append(Component.text(".", NamedTextColor.DARK_GREEN))
players.forEach { player -> players.forEach { player ->
player.gameMode = GameMode.SPECTATOR player.gameMode = GameMode.SPECTATOR
player.sendMessage(
Component
.text("La partie est terminée !", NamedTextColor.DARK_GREEN)
.appendNewline()
.apply {
if (!withoutResult) return@apply
remainingPlayer.forEachIndexed { index, player ->
append(player.displayName())
if (index != remainingPlayer.lastIndex) { player.sendMessage(endComponent)
append( if (remainingPlayer[0].werewolfRole.team == Role.Team.Solo) {
Component.text( TODO()
when (index) { } else {
remainingPlayer.lastIndex - 1 -> " et " if (!withoutResult) player.sendMessage(winComponent)
else -> ", " }
},
NamedTextColor.DARK_GREEN,
),
)
}
append(Component.text(" ont gagné !", NamedTextColor.DARK_GREEN))
}
},
)
} }
val lobbyLoc = plugin.config.getLocation("lobby-location") val lobbyLoc = plugin.config.getLocation("lobby-location")
Bukkit.getScheduler().runTaskLater( Bukkit.getScheduler().runTaskLater(
@@ -117,6 +112,10 @@ class Game(
players.forEach { player -> players.forEach { player ->
if (lobbyLoc != null) player.teleport(lobbyLoc) if (lobbyLoc != null) player.teleport(lobbyLoc)
player.gameMode = GameMode.ADVENTURE player.gameMode = GameMode.ADVENTURE
player.persistentDataContainer.remove(PlayerDead)
player.persistentDataContainer.remove(Insomnia)
player.inventory.clear()
player.resetCooldown()
} }
}, },
200, 200,

View File

@@ -23,6 +23,7 @@ class NightLightCycle(
val world: World, val world: World,
val newPhase: Phase, val newPhase: Phase,
val duration: Duration, val duration: Duration,
val dayCount: Int,
) : Event() { ) : Event() {
override fun getHandlers(): HandlerList = handlerList override fun getHandlers(): HandlerList = handlerList
@@ -55,19 +56,19 @@ class NightLightCycle(
val duration = Duration.fromPlugin(plugin) val duration = Duration.fromPlugin(plugin)
var targetInstant: Long var targetInstant: Long = 0
var tick: Float = 0F
var tickOrigin: Int = 0 var tickOrigin: Int = 0
var realDifference: Int var realDifference: Long = 0
var tickDifference: Int var tickDifference: Int = 0
var realOrigin: Long = 0
var dayCount: Int = 0 var dayCount: Int = 0
init { init {
world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false) world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false)
realDifference = duration.day * 1000
targetInstant = System.currentTimeMillis() + realDifference.toLong() changePhase(Phase.DAY)
tickDifference = 12_000
Bukkit.getPluginManager().callEvent(NightLightCyclePhaseChangeEvent(world, phase, duration))
process = process =
Bukkit.getScheduler().runTaskTimer( Bukkit.getScheduler().runTaskTimer(
@@ -81,44 +82,49 @@ class NightLightCycle(
} }
fun changePhase(newPhase: Phase) { fun changePhase(newPhase: Phase) {
realOrigin = System.currentTimeMillis()
when (newPhase) { when (newPhase) {
Phase.DAY -> { Phase.DAY -> {
tickDifference = 12_000 tickDifference = 12_000
tickOrigin = 0 tickOrigin = 0
realDifference = duration.day * 1000 realDifference = duration.day * 1000L
} }
Phase.VOTE -> { Phase.VOTE -> {
tickDifference = 1_000 tickDifference = 1_000
tickOrigin = 12_000 tickOrigin = 12_000
realDifference = duration.vote * 1000 realDifference = duration.vote * 1000L
} }
Phase.NIGHT -> { Phase.NIGHT -> {
tickDifference = 11_000 tickDifference = 10_000
tickOrigin = 13_000 tickOrigin = 13_000
realDifference = duration.night * 1000 realDifference = duration.night * 1000L
} }
Phase.CREPUSCULAR -> { Phase.CREPUSCULAR -> {
tickDifference = 1_000 tickDifference = 1_000
tickOrigin = 23_000 tickOrigin = 23_000
realDifference = duration.crepuscular * 1000 realDifference = duration.crepuscular * 1000L
} }
} }
targetInstant = System.currentTimeMillis() + realDifference targetInstant = System.currentTimeMillis() + realDifference
tick = tickDifference / realDifference.toFloat()
phase = newPhase phase = newPhase
Bukkit.getPluginManager().callEvent(NightLightCyclePhaseChangeEvent(world, newPhase, duration)) Bukkit.getPluginManager().callEvent(NightLightCyclePhaseChangeEvent(world, newPhase, duration, dayCount))
} }
fun tick() { fun tick() {
if (System.currentTimeMillis() >= targetInstant) { val realtime = System.currentTimeMillis()
if (realtime >= targetInstant) {
val phase = phases[(phases.indexOf(phase) + 1) % phases.count()] val phase = phases[(phases.indexOf(phase) + 1) % phases.count()]
if (phase == Phase.DAY) { if (phase == Phase.DAY) {
dayCount += 1 dayCount += 1
} }
changePhase(phase) changePhase(phase)
} }
val result = tickOrigin + (realtime - realOrigin) * tick
world.time = result.toLong().coerceIn(0, 23999)
} }
fun stop() { fun stop() {

View File

@@ -59,10 +59,13 @@ enum class CustomItems(
BlasTechDL44(true, { BlasTechDL44(true, {
ItemStack.of(Material.CROSSBOW).apply { ItemStack.of(Material.CROSSBOW).apply {
itemMeta = itemMeta =
(itemMeta as DamageableCrossbow).apply { (itemMeta as CrossbowMeta).apply {
addChargedProjectile(GunBullet.item) addChargedProjectile(GunBullet.item)
displayName(Component.text("BlasTech DL-44", NamedTextColor.GOLD)) displayName(Component.text("BlasTech DL-44", NamedTextColor.GOLD))
addEnchant(Enchantment.INFINITY, 1, true) addEnchant(Enchantment.INFINITY, 1, true)
}
itemMeta =
(itemMeta as Damageable).apply {
setMaxDamage(1) setMaxDamage(1)
} }
} }
@@ -87,9 +90,9 @@ enum class CustomItems(
DeathPotion(true, { DeathPotion(true, {
ItemStack.of(Material.POTION).apply { ItemStack.of(Material.POTION).apply {
itemMeta = itemMeta =
(itemMeta as DamageablePotion).apply { (itemMeta as PotionMeta).apply {
setMaxStackSize(1) setMaxStackSize(1)
setMaxDamage(1)
customName( customName(
Component.text("Potion de poison", NamedTextColor.DARK_PURPLE), Component.text("Potion de poison", NamedTextColor.DARK_PURPLE),
) )
@@ -105,14 +108,18 @@ enum class CustomItems(
), ),
) )
} }
itemMeta =
(itemMeta as Damageable).apply {
setMaxDamage(1)
}
} }
}), }),
HealPotion(true, { HealPotion(true, {
ItemStack.of(Material.POTION).apply { ItemStack.of(Material.POTION).apply {
itemMeta = itemMeta =
(itemMeta as DamageablePotion).apply { (itemMeta as PotionMeta).apply {
setMaxStackSize(1) setMaxStackSize(1)
setMaxDamage(1)
customName( customName(
Component.text("Potion de vie", NamedTextColor.DARK_PURPLE), Component.text("Potion de vie", NamedTextColor.DARK_PURPLE),
) )
@@ -124,6 +131,10 @@ enum class CustomItems(
color = Color.RED color = Color.RED
lore(listOf(Component.text("Click droit pour utiliser.", NamedTextColor.GOLD))) lore(listOf(Component.text("Click droit pour utiliser.", NamedTextColor.GOLD)))
} }
itemMeta =
(itemMeta as Damageable).apply {
setMaxDamage(1)
}
} }
}), }),
SpawnLocTool(true, { SpawnLocTool(true, {
@@ -230,10 +241,6 @@ enum class CustomItems(
} }
} }
interface DamageableCrossbow :
Damageable,
CrossbowMeta
interface DamageablePotion : interface DamageablePotion :
Damageable, Damageable,
PotionMeta { PotionMeta {

View File

@@ -9,7 +9,7 @@ import org.bukkit.entity.Player
object FortuneTeller : Role { object FortuneTeller : Role {
override fun handle(player: Player) { override fun handle(player: Player) {
player.inventory.addItem(CustomItems.CrystalBall.item) player.inventory.setItem(9, CustomItems.CrystalBall.item)
} }
override val team = Role.Team.Villager override val team = Role.Team.Villager

View File

@@ -9,7 +9,7 @@ import org.bukkit.entity.Player
object Hunter : Role { object Hunter : Role {
override fun handle(player: Player) { override fun handle(player: Player) {
player.inventory.addItem(CustomItems.BlasTechDL44.item) player.inventory.setItem(9, CustomItems.BlasTechDL44.item)
} }
override val team = Role.Team.Villager override val team = Role.Team.Villager

View File

@@ -1,6 +1,7 @@
package fr.azur.tcoww.roles package fr.azur.tcoww.roles
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import net.kyori.adventure.text.JoinConfiguration
import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.text.format.NamedTextColor
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
@@ -37,12 +38,13 @@ interface Role {
val description: List<Component> val description: List<Component>
val lineDescription: Component val lineDescription: Component
get() { get() {
return Component.empty().apply { val joinConfig =
description.forEach { JoinConfiguration
append(it) .builder()
appendNewline() .separator(Component.newline())
} .build()
}
return Component.join(joinConfig, description)
} }
companion object { companion object {
@@ -56,19 +58,20 @@ interface Role {
player.sendMessage( player.sendMessage(
Component.text("Votre role est ", NamedTextColor.DARK_AQUA).append(role.displayName), Component.text("Votre role est ", NamedTextColor.DARK_AQUA).append(role.displayName),
) )
player.sendMessage(role.lineDescription)
player.sendMessage( player.sendMessage(
role.lineDescription.append { if (role.team == Team.Solo) {
if (role.team == Team.Solo) { Component.text("Vous gagnez Seul.", NamedTextColor.AQUA)
Component.text("Vous gagnez Seul.", NamedTextColor.AQUA) } else {
} else { Component
Component .text("Vous gagnez avec les ", NamedTextColor.AQUA)
.text("Vous gagnez avec les ", NamedTextColor.AQUA) .append(role.team.displayName)
.append(role.team.displayName) .append(Component.text(".", NamedTextColor.AQUA))
.append(Component.text(".", NamedTextColor.AQUA))
}
}, },
) )
role.handle(player)
player.persistentDataContainer.set(roleKey, PersistentDataType.STRING, role.id.toString()) player.persistentDataContainer.set(roleKey, PersistentDataType.STRING, role.id.toString())
} }

View File

@@ -9,6 +9,7 @@ import org.bukkit.NamespacedKey
import org.bukkit.entity.Player import org.bukkit.entity.Player
object Werewolf : Role { object Werewolf : Role {
var remainingKill = 0
override val team = Role.Team.LG override val team = Role.Team.LG
override var id = NamespacedKey("tcoww", "werewolf") override var id = NamespacedKey("tcoww", "werewolf")
override val displayName = Component.text("Loup-Garou", NamedTextColor.DARK_GRAY) override val displayName = Component.text("Loup-Garou", NamedTextColor.DARK_GRAY)
@@ -19,14 +20,21 @@ object Werewolf : Role {
listOf( listOf(
Component.text("Pour la faire courte, vous avez faim, très faim.", NamedTextColor.BLUE), 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.",
NamedTextColor.BLUE,
),
Component.text(
"Toute les nuits, vous pouvez vous tranformer en loup pour manger un villageois.",
NamedTextColor.BLUE, NamedTextColor.BLUE,
), ),
) )
override fun handle(player: Player) { override fun handle(player: Player) {
val tfItem = CustomItems.WereWolfTransformItem.item val tfItem = CustomItems.WereWolfTransformItem.item
player.inventory.addItem(tfItem) player.inventory.setItem(9, tfItem)
player.setCooldown(tfItem, ((Tcoww.instance.config.getInt("duration.day") + Tcoww.instance.config.getInt("duration.day")) * 20)) player.setCooldown(
tfItem,
((Tcoww.instance.config.getInt("duration.day") + Tcoww.instance.config.getInt("duration.day")) * 20),
)
} }
} }

View File

@@ -9,8 +9,8 @@ import org.bukkit.entity.Player
object Witch : Role { object Witch : Role {
override fun handle(player: Player) { override fun handle(player: Player) {
player.inventory.addItem(CustomItems.DeathPotion.item) player.inventory.setItem(9, CustomItems.DeathPotion.item)
player.inventory.addItem(CustomItems.HealPotion.item) player.inventory.setItem(10, CustomItems.HealPotion.item)
} }
override val team = Role.Team.Villager override val team = Role.Team.Villager

View File

@@ -1,6 +1,8 @@
package fr.azur.tcoww.ui package fr.azur.tcoww.ui
import fr.azur.tcoww.Tcoww import fr.azur.tcoww.Tcoww
import fr.azur.tcoww.utils.Players.isTransformed
import fr.azur.tcoww.utils.skins.Manager
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.Material
@@ -25,7 +27,12 @@ class PlayerSelectMenu(
ItemStack.of(Material.PLAYER_HEAD).apply { ItemStack.of(Material.PLAYER_HEAD).apply {
itemMeta = itemMeta =
(itemMeta as SkullMeta).apply { (itemMeta as SkullMeta).apply {
playerProfile = player.playerProfile playerProfile =
if (player.isTransformed()) {
Manager.oldPlayerProfile[player.uniqueId]
} else {
player.playerProfile
}
} }
} }
setItem(index, item) setItem(index, item)
@@ -36,8 +43,10 @@ class PlayerSelectMenu(
override fun onClick(event: InventoryClickEvent) { override fun onClick(event: InventoryClickEvent) {
val index = event.slot val index = event.slot
event.isCancelled = true
if (index !in 0..<players.count() || event.clickedInventory != inventory) return if (index !in 0..<players.count() || event.clickedInventory != inventory) return
future.complete(players.elementAt(index)) future.complete(players.elementAt(index))
event.inventory.close()
} }
override fun onClose(event: InventoryCloseEvent) { override fun onClose(event: InventoryCloseEvent) {

View File

@@ -26,7 +26,7 @@ object Players {
Bukkit Bukkit
.getServer() .getServer()
.scoreboardManager.mainScoreboard .scoreboardManager.mainScoreboard
.getTeam("NoCollide") .getTeam("NoCollision")
fun Player.tfWerewolf() { fun Player.tfWerewolf() {
if (isTransformed()) return if (isTransformed()) return

View File

@@ -4,7 +4,10 @@ import de.maxhenkel.voicechat.api.Group
import de.maxhenkel.voicechat.api.VoicechatPlugin import de.maxhenkel.voicechat.api.VoicechatPlugin
import de.maxhenkel.voicechat.api.VoicechatServerApi import de.maxhenkel.voicechat.api.VoicechatServerApi
import de.maxhenkel.voicechat.api.events.EventRegistration import de.maxhenkel.voicechat.api.events.EventRegistration
import de.maxhenkel.voicechat.api.events.LeaveGroupEvent
import de.maxhenkel.voicechat.api.events.VoicechatServerStartedEvent import de.maxhenkel.voicechat.api.events.VoicechatServerStartedEvent
import fr.azur.tcoww.game.Game
import fr.azur.tcoww.game.NightLightCycle
import org.bukkit.entity.Player import org.bukkit.entity.Player
import java.util.UUID import java.util.UUID
import kotlin.random.Random import kotlin.random.Random
@@ -17,6 +20,7 @@ object VoiceChatPlugin : VoicechatPlugin {
override fun registerEvents(registration: EventRegistration) { override fun registerEvents(registration: EventRegistration) {
registration.registerEvent(VoicechatServerStartedEvent::class.java, this::onServerStarted) registration.registerEvent(VoicechatServerStartedEvent::class.java, this::onServerStarted)
registration.registerEvent(LeaveGroupEvent::class.java, this::onGroupRemove)
} }
private fun onServerStarted(event: VoicechatServerStartedEvent) { private fun onServerStarted(event: VoicechatServerStartedEvent) {
@@ -32,6 +36,17 @@ object VoiceChatPlugin : VoicechatPlugin {
.build() .build()
} }
private fun onGroupRemove(event: LeaveGroupEvent) {
val current = Game.current ?: return
if ((
current.timeGestion.phase == NightLightCycle.Phase.NIGHT ||
current.timeGestion.phase == NightLightCycle.Phase.CREPUSCULAR
)
) {
event.cancel()
}
}
fun addWerewolf(player: Player) { fun addWerewolf(player: Player) {
val connection = api.getConnectionOf(player.uniqueId) ?: return val connection = api.getConnectionOf(player.uniqueId) ?: return
connection.group = werewolfGroup connection.group = werewolfGroup

View File

@@ -1,5 +1,6 @@
package fr.azur.tcoww.utils.skins package fr.azur.tcoww.utils.skins
import com.destroystokyo.paper.profile.PlayerProfile
import fr.azur.tcoww.Tcoww import fr.azur.tcoww.Tcoww
import net.skinsrestorer.api.SkinsRestorer import net.skinsrestorer.api.SkinsRestorer
import net.skinsrestorer.api.SkinsRestorerProvider import net.skinsrestorer.api.SkinsRestorerProvider
@@ -14,6 +15,7 @@ object Manager {
var maxSkinId: Int = 0 var maxSkinId: Int = 0
private lateinit var skinsRestorer: SkinsRestorer private lateinit var skinsRestorer: SkinsRestorer
var oldPlayerSkin = mutableMapOf<UUID, SkinIdentifier?>() var oldPlayerSkin = mutableMapOf<UUID, SkinIdentifier?>()
var oldPlayerProfile = mutableMapOf<UUID, PlayerProfile>()
var wwPlayerFur = mutableMapOf<UUID, Int>() var wwPlayerFur = mutableMapOf<UUID, Int>()
fun handle() { fun handle() {
@@ -32,13 +34,14 @@ object Manager {
maxSkinId = skinsValue.size maxSkinId = skinsValue.size
skinsValue.forEachIndexed { index, skin -> skinsValue.forEachIndexed { index, skin ->
skinsRestorer.skinStorage.setCustomSkinData("tcoww$index", SkinProperty.of(skin.value, skin.signature)) skinsRestorer.skinStorage.setCustomSkinData("tcoww_$index", SkinProperty.of(skin.value, skin.signature))
} }
} }
fun applyWerewolfFur(player: Player) { fun applyWerewolfFur(player: Player) {
val skin = skinsRestorer.playerStorage.getSkinIdOfPlayer(player.uniqueId) val skin = skinsRestorer.playerStorage.getSkinIdOfPlayer(player.uniqueId)
oldPlayerSkin[player.uniqueId] = skin.getOrNull() oldPlayerSkin[player.uniqueId] = skin.getOrNull()
oldPlayerProfile[player.uniqueId] = player.playerProfile
val result = skinsRestorer.skinStorage.findOrCreateSkinData("tcoww_${getWerewolfFur(player.uniqueId)}") val result = skinsRestorer.skinStorage.findOrCreateSkinData("tcoww_${getWerewolfFur(player.uniqueId)}")

View File

@@ -1,5 +1,5 @@
name: tcoww name: tcoww
version: '1.0-SNAPSHOT' version: '1.2.0'
main: fr.azur.tcoww.Tcoww main: fr.azur.tcoww.Tcoww
api-version: '1.21' api-version: '1.21'
load: POSTWORLD load: POSTWORLD