Merge pull request 'Finish TNTLeague' (#53) from TNTLeague/finish into main

Reviewed-on: https://steamwar.de/devlabs/SteamWar/SteamWar/pulls/53
Reviewed-by: Lixfel <lixfel@steamwar.de>
This commit is contained in:
2024-12-11 10:53:39 +01:00
25 changed files with 461 additions and 266 deletions

View File

@ -32,4 +32,6 @@ tasks.shadowJar {
dependencies { dependencies {
compileOnly(libs.paperapi21) compileOnly(libs.paperapi21)
compileOnly(libs.nms21)
compileOnly(project(":SpigotCore"))
} }

View File

@ -32,6 +32,7 @@ class KotlinCore : JavaPlugin() {
} }
override fun onEnable() { override fun onEnable() {
} }
override fun onDisable() { override fun onDisable() {

View File

@ -1,4 +1,23 @@
package de.steamwar.tntleague.inventory /*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.inventory
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.InventoryCloseEvent import org.bukkit.event.inventory.InventoryCloseEvent

View File

@ -1,4 +1,23 @@
package de.steamwar.tntleague.util /*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.kotlin.util
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.block.Block import org.bukkit.block.Block

View File

@ -1,3 +1,22 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
plugins { plugins {
steamwar.kotlin steamwar.kotlin
} }

View File

@ -1,19 +1,36 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.tntleague package de.steamwar.tntleague
import de.steamwar.message.Message
import de.steamwar.tntleague.command.AcceptCommand import de.steamwar.tntleague.command.AcceptCommand
import de.steamwar.tntleague.command.InviteCommand import de.steamwar.tntleague.command.InviteCommand
import de.steamwar.tntleague.command.LeaveCommand import de.steamwar.tntleague.command.LeaveCommand
import de.steamwar.tntleague.command.RemoveCommand import de.steamwar.tntleague.command.RemoveCommand
import de.steamwar.tntleague.events.GlobalListener import de.steamwar.tntleague.events.GlobalListener
import de.steamwar.tntleague.events.LobbyListener import de.steamwar.tntleague.events.LobbyListener
import net.kyori.adventure.key.Key import de.steamwar.tntleague.game.TNTLeagueTeam
import net.kyori.adventure.translation.GlobalTranslator
import net.kyori.adventure.translation.TranslationRegistry
import net.kyori.adventure.util.UTF8ResourceBundleControl
import org.bukkit.plugin.java.JavaPlugin import org.bukkit.plugin.java.JavaPlugin
import java.util.*
lateinit var plugin: TNTLeague lateinit var plugin: TNTLeague
lateinit var message: Message
class TNTLeague : JavaPlugin() { class TNTLeague : JavaPlugin() {
init { init {
@ -22,18 +39,8 @@ class TNTLeague : JavaPlugin() {
override fun onEnable() { override fun onEnable() {
saveResource("config.yml", false) saveResource("config.yml", false)
saveDefaultConfig()
val registry = TranslationRegistry.create(Key.key("steamwar:tntleague")) message = Message("de.steamwar.tntleague.TNTLeague", classLoader)
val bundleDe = ResourceBundle.getBundle("de.steamwar.tntleague.TNTLeague", Locale.GERMAN, UTF8ResourceBundleControl())
val bundleEn = ResourceBundle.getBundle("de.steamwar.tntleague.TNTLeague", Locale.US, UTF8ResourceBundleControl())
registry.defaultLocale(Locale.US)
registry.registerAll(Locale.GERMAN, bundleDe, true)
registry.registerAll(Locale.US, bundleEn, true)
GlobalTranslator.translator().addSource(registry)
server.pluginManager.registerEvents(LobbyListener, this) server.pluginManager.registerEvents(LobbyListener, this)
server.pluginManager.registerEvents(GlobalListener, this) server.pluginManager.registerEvents(GlobalListener, this)
@ -46,3 +53,8 @@ class TNTLeague : JavaPlugin() {
LeaveCommand.register() LeaveCommand.register()
} }
} }
fun String.colorByTeam(team: TNTLeagueTeam?) = when (team) {
null -> "§7${this}"
else -> "§${team.color}${this}"
}

View File

@ -0,0 +1,49 @@
#
# This file is a part of the SteamWar software.
#
# Copyright (C) 2024 SteamWar.de-Serverteam
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
PREFIX=§eTNT§7League§8»
JOIN=§e{0} §7joined the game!
JOIN_TEAM={0} §7joined the {1} §7team!
QUIT={0} §7left the game!
QUIT_TEAM={0} §7left the {1} §7team!
BLUE=blue
RED=red
SHUTDOWN=§7The server stops in §e{0} §7seconds!
TEAM_WIN=§aTeam {0} §awins!
NOT_ENOUGH_COINS=§cYou don't have enough coins to buy this item!
GAME_STARTING=§aThe game starts in §e{0} §aseconds!
GAME_START=
GAME_STARTED=§aThe game has started!
TIME_REMAINING=§e{0} §7minutes remaining!
GAME_ENDED=§cThe game has ended!
DRAW=§cThe game ended in a draw!
DEALER=Shopkeeper
DEALER_ITEM={0} {1}
DEALER_PRICE=
SCOREBOARD_TARGET=
SCOREBOARD_TIME=§7Time§8: §e{0}§8:§e{1}
SCOREBOARD_COINS=§7Coins§8: §e{0}
SCOREBOARD_TEAM=§7Team {0}§8: §e{1}
READY=§aReady
NOT_READY=§cNot ready
IS_READY=§aTeam {0} §ais ready!
IS_NOT_READY=§cTeam {0} §cis not ready!
INVITED={0} §ainvited you to join team {1}§7! *Click*
INVITED_HOVER=§7Click to join team {0}§7!
INVITED_PLAYER=§aInvited §e{0} §ato join your team!

View File

@ -0,0 +1,44 @@
#
# This file is a part of the SteamWar software.
#
# Copyright (C) 2024 SteamWar.de-Serverteam
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
JOIN=§e{0} §7ist dem Spiel beigetreten!
JOIN_TEAM={0} §7ist Team {1} §7begetreten!
QUIT={0} §7hat das Spiel verlassen!
QUIT_TEAM={0} §7hat Team {1} §7verlassen!
BLUE=Blau
RED=Rot
SHUTDOWN=§7Der Server fährt in §e{0} §7Sekunden herunter!
TEAM_WIN=§aTeam {0} §agewinnt!
NOT_ENOUGH_COINS=§cDu hast nicht genug Coins, um dir das zu kaufen!
GAME_STARTING=§aDas Spiel beginnt in §e{0} §aSekunden!
GAME_STARTED=§aDas Spiel beginnt!
TIME_REMAINING=§7noch §e{0} §7Minuten!
GAME_ENDED=§cDas Spiel ist vorbei!
DRAW=§cKeiner hat gewonnen!
DEALER=Händler
DEALER_PRICE=§7Kosten: §e{0} Coins
SCOREBOARD_TARGET=§7Ziel§8: {0}
SCOREBOARD_TIME=§7Zeit§8: §e{0}§8:§e{1}
READY=§aBereit
NOT_READY=§cNicht bereit
IS_READY=§aTeam {0} §aist bereit!
IS_NOT_READY=§cTeam {0} §cist nicht bereit!
INVITED={0} §ahat dich in Team {1} §aeingeladen! *Klick*
INVITED_HOVER=§7Team {0} §7beitreten!
INVITED_PLAYER={0} §awurde eingeladen!

View File

@ -1,18 +0,0 @@
join={0} ist dem Spiel beigetreten!
joinTeam={0} ist dem {1} team begetreten!
quit={0} hat das Spiel verlassen!
blue=Blau
red=Rot
shutdown=Der Server fährt in {0} sekunden herunter!
teamWin=Team {0} gewinnt!
notEnoughCoins=Du hast nicht genug Coins um dir das zu kaufen!
gameStarting=Das Spiel beginnt in {0} Sekunden!
gameStart=Start in {0}
gameStarted=Das Spiel beginnt!
gameEnded=Das Spiel ist aus!
dealer=Händler
dealerItem=
dealerPrice=Kosten: {0} Coins
scoreboardTarget=Ziel: {0}
scoreboardTime=Zeit: {0}:{1}
scoreboardTeam=

View File

@ -1,37 +0,0 @@
join={0} joined the game!
joinTeam={0} joined the {1} team!
quit={0} left the game!
quitTeam={0} left the {1} team!
blue=Blue
red=Red
shutdown=The server stops in {0} seconds!
teamWin=Team {0} wins!
notEnoughCoins=You don't have enough coins to buy this item!
gameStarting=The game starts in {0} seconds!
gameStart=Starting in {0}
gameStarted=The game has started!
timeRemaining={0} minutes remaining!
gameEnded=The game has ended!
draw=The game ended in a draw!
chat={0}<7D> {1}
dealer=Shopkeeper
dealerItem={0} {1}
dealerPrice=Price: {0} Coins
scoreboardTarget=Target: {0}
scoreboardTime=Time: {0}:{1}
scoreboardTeam=Team {0}: {1}
ready=Ready
notReady=Not ready
isReady=Team {0} is ready!
isNotReady=Team {0} is not ready!
invited={0} invited you to join the {1} team! *Click*
invitedHover=Click to join the {0} team!
invitedPlayer=Invited {0} to join your team!

View File

@ -21,10 +21,10 @@ package de.steamwar.tntleague.command
import de.steamwar.command.SWCommand import de.steamwar.command.SWCommand
import de.steamwar.command.TypeValidator import de.steamwar.command.TypeValidator
import de.steamwar.tntleague.colorByTeam
import de.steamwar.tntleague.game.TNTLeagueGame import de.steamwar.tntleague.game.TNTLeagueGame
import de.steamwar.tntleague.util.* import de.steamwar.tntleague.message
import net.kyori.adventure.text.event.ClickEvent import net.md_5.bungee.api.chat.ClickEvent
import net.kyori.adventure.text.event.HoverEvent
import org.bukkit.entity.Player import org.bukkit.entity.Player
object InviteCommand: SWCommand("invite") { object InviteCommand: SWCommand("invite") {
@ -37,20 +37,15 @@ object InviteCommand: SWCommand("invite") {
val team = TNTLeagueGame.getTeam(sender)!! val team = TNTLeagueGame.getTeam(sender)!!
team.invites.add(target) team.invites.add(target)
target.sendMessage(translate("invited", sender.name.yellow(), translate(team.name).colorByTeam(team)).basic().clickEvent( message
ClickEvent.callback { .send("INVITED", target, message.parse("INVITED_HOVER", target, team.name.colorByTeam(team)),
if (target !in team.invites) return@callback ClickEvent(ClickEvent.Action.RUN_COMMAND, "/accept "), sender.name, team.name.colorByTeam(team), )
team.invites.remove(target) message.send("INVITED_PLAYER", sender, target.name)
team.opposite.invites.remove(target)
team.join(target)
})
.hoverEvent(HoverEvent.showText(translate("invitedHover", translate(team.name).colorByTeam(team)).green())))
sender.sendMessage(translate("invitedPlayer", target.name.yellow()).basic())
} }
@Validator("isLeader", local = false) @Validator("isLeader", local = false)
fun isLeader(): TypeValidator<Player> { fun isLeader(): TypeValidator<Player> {
return TypeValidator<Player> { _, player, _ -> TNTLeagueGame.getTeam(player)?.leader == player} return TypeValidator<Player> { _, player, _ -> TNTLeagueGame.getTeam(player)?.leader == player}
} }
} }

View File

@ -26,5 +26,5 @@ import org.bukkit.entity.Player
object LeaveCommand: SWCommand("leave", "l") { object LeaveCommand: SWCommand("leave", "l") {
@Register @Register
fun leave(player: Player) = TNTLeagueGame.getTeam(player)?.remove(player) fun leave(player: Player) = TNTLeagueGame.getTeam(player)?.remove(player) ?: Unit
} }

View File

@ -1,3 +1,22 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.tntleague.config package de.steamwar.tntleague.config
import de.steamwar.tntleague.plugin import de.steamwar.tntleague.plugin

View File

@ -1,13 +1,31 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.tntleague.config package de.steamwar.tntleague.config
import de.steamwar.tntleague.plugin import de.steamwar.tntleague.plugin
import de.steamwar.tntleague.util.Area import de.steamwar.kotlin.util.Area
import de.steamwar.tntleague.util.translate import net.kyori.adventure.text.Component
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.configuration.file.YamlConfiguration
import org.bukkit.entity.Villager
import org.bukkit.entity.WanderingTrader import org.bukkit.entity.WanderingTrader
import java.io.File import java.io.File
@ -62,7 +80,7 @@ object TNTLeagueWorldConfig {
private fun spawnDealer(loc: Location) = world.spawn(loc, WanderingTrader::class.java) private fun spawnDealer(loc: Location) = world.spawn(loc, WanderingTrader::class.java)
.apply { .apply {
customName(translate("dealer")) customName(Component.text("Shop"))
isCustomNameVisible = false isCustomNameVisible = false
isInvulnerable = true isInvulnerable = true
isSilent = true isSilent = true

View File

@ -21,5 +21,4 @@ package de.steamwar.tntleague.events
import org.bukkit.event.Listener import org.bukkit.event.Listener
object DummyListener: Listener { object DummyListener: Listener
}

View File

@ -1,12 +1,30 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.tntleague.events package de.steamwar.tntleague.events
import de.steamwar.tntleague.colorByTeam
import de.steamwar.tntleague.config.TNTLeagueWorldConfig import de.steamwar.tntleague.config.TNTLeagueWorldConfig
import de.steamwar.tntleague.game.TNTLeagueGame import de.steamwar.tntleague.game.TNTLeagueGame
import de.steamwar.tntleague.game.TNTLeagueTeam import de.steamwar.tntleague.game.TNTLeagueTeam
import de.steamwar.tntleague.inventory.SWInventoryHolder import de.steamwar.kotlin.inventory.SWInventoryHolder
import de.steamwar.tntleague.plugin import de.steamwar.tntleague.message
import de.steamwar.tntleague.util.*
import io.papermc.paper.event.player.AsyncChatEvent
import org.bukkit.GameMode import org.bukkit.GameMode
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
@ -27,7 +45,7 @@ object GlobalListener: Listener {
with(e.player) { with(e.player) {
teleport(TNTLeagueWorldConfig.lobby) teleport(TNTLeagueWorldConfig.lobby)
inventory.clear() inventory.clear()
plugin.server.broadcast(translate("join", name.bold()).basic()) message.broadcast("JOIN", name)
isOp = false isOp = false
gameMode = GameMode.SPECTATOR gameMode = GameMode.SPECTATOR
respawnLocation = TNTLeagueWorldConfig.lobby respawnLocation = TNTLeagueWorldConfig.lobby
@ -37,7 +55,7 @@ object GlobalListener: Listener {
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
fun onPlayerQuit(e: PlayerQuitEvent) { fun onPlayerQuit(e: PlayerQuitEvent) {
e.quitMessage(null) e.quitMessage(null)
plugin.server.broadcast(translate("quit", e.player.name.bold().colorByTeam(TNTLeagueGame.getTeam(e.player))).basic()) message.broadcast("QUIT", e.player.name.colorByTeam(TNTLeagueGame.getTeam(e.player)))
TNTLeagueGame.playerLeave(e.player) TNTLeagueGame.playerLeave(e.player)
} }
@ -67,6 +85,7 @@ object GlobalListener: Listener {
fun onPlayerDeath(e: PlayerDeathEvent) { fun onPlayerDeath(e: PlayerDeathEvent) {
e.deathMessage(null) e.deathMessage(null)
e.drops.clear() e.drops.clear()
e.keepInventory = true
e.itemsToKeep.removeIf { it.type != Material.DIAMOND_PICKAXE } e.itemsToKeep.removeIf { it.type != Material.DIAMOND_PICKAXE }
} }
@ -78,11 +97,4 @@ object GlobalListener: Listener {
null -> e.respawnLocation = TNTLeagueWorldConfig.lobby null -> e.respawnLocation = TNTLeagueWorldConfig.lobby
} }
} }
@EventHandler
fun onChat(e: AsyncChatEvent) {
e.renderer { source, sourceDisplayName, message, _ ->
translate("chat", sourceDisplayName.colorByTeam(TNTLeagueGame.getTeam(source)), message).basic()
}
}
} }

View File

@ -1,3 +1,22 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.tntleague.events package de.steamwar.tntleague.events
import de.steamwar.scoreboard.SWScoreboard import de.steamwar.scoreboard.SWScoreboard
@ -13,12 +32,11 @@ import org.bukkit.entity.EntityType
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.entity.EntityExplodeEvent import org.bukkit.event.entity.EntityExplodeEvent
import org.bukkit.event.entity.PlayerDeathEvent import org.bukkit.event.player.PlayerAttemptPickupItemEvent
import org.bukkit.event.player.PlayerDropItemEvent import org.bukkit.event.player.PlayerDropItemEvent
import org.bukkit.event.player.PlayerInteractEntityEvent import org.bukkit.event.player.PlayerInteractEntityEvent
import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerMoveEvent import org.bukkit.event.player.PlayerMoveEvent
import org.bukkit.event.player.PlayerQuitEvent
object IngameListener: Listener { object IngameListener: Listener {
@ -26,7 +44,7 @@ object IngameListener: Listener {
fun onEntityInteract(e: PlayerInteractEntityEvent) { fun onEntityInteract(e: PlayerInteractEntityEvent) {
if (e.player.gameMode == GameMode.SPECTATOR) return if (e.player.gameMode == GameMode.SPECTATOR) return
if(e.rightClicked.type == EntityType.VILLAGER) { if(e.rightClicked.type == EntityType.WANDERING_TRADER) {
e.isCancelled = true e.isCancelled = true
e.player.openInventory(DealerInventory(e.player).getInventory()) e.player.openInventory(DealerInventory(e.player).getInventory())
} }
@ -63,6 +81,17 @@ object IngameListener: Listener {
} }
} }
@EventHandler
fun onPickupCoins(e: PlayerAttemptPickupItemEvent) {
if (e.item.itemStack.isSimilar(DealerInventory.coins)) {
TNTLeagueGame.getTeam(e.player)?.coins = e.item.itemStack.amount + (TNTLeagueGame.getTeam(e.player)?.coins ?: 0)
e.item.itemStack.amount = 0
e.isCancelled = true
e.flyAtPlayer = true
}
}
private fun getTeamByTargetLocation(location: Location): TNTLeagueTeam? = private fun getTeamByTargetLocation(location: Location): TNTLeagueTeam? =
when (location) { when (location) {
in TNTLeagueWorldConfig.redTeam.target -> TNTLeagueGame.redTeam in TNTLeagueWorldConfig.redTeam.target -> TNTLeagueGame.redTeam

View File

@ -1,22 +1,33 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.tntleague.events package de.steamwar.tntleague.events
import de.steamwar.tntleague.game.TNTLeagueGame import de.steamwar.tntleague.game.TNTLeagueGame
import de.steamwar.tntleague.plugin import org.bukkit.GameMode
import de.steamwar.tntleague.util.basic import org.bukkit.entity.EntityType
import de.steamwar.tntleague.util.colorByTeam
import de.steamwar.tntleague.util.translate
import de.steamwar.tntleague.util.yellow
import io.papermc.paper.util.Tick
import org.bukkit.event.EventHandler 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.block.Action
import org.bukkit.event.entity.EntityDamageEvent import org.bukkit.event.entity.EntityDamageEvent
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.player.PlayerDropItemEvent import org.bukkit.event.player.*
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.event.player.PlayerQuitEvent
object LobbyListener: Listener { object LobbyListener: Listener {
@ -30,8 +41,7 @@ object LobbyListener: Listener {
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
fun onPlayerQuit(e: PlayerQuitEvent) { fun onPlayerQuit(e: PlayerQuitEvent) {
val team = TNTLeagueGame.getTeam(e.player) ?: return TNTLeagueGame.getTeam(e.player)?.leave(e.player)
team.leave(e.player)
} }
@EventHandler @EventHandler
@ -58,4 +68,13 @@ object LobbyListener: Listener {
e.isCancelled = true e.isCancelled = true
} }
} }
@EventHandler
fun onEntityInteract(e: PlayerInteractEntityEvent) {
if (e.player.gameMode == GameMode.SPECTATOR) return
if(e.rightClicked.type == EntityType.WANDERING_TRADER) {
e.isCancelled = true
}
}
} }

View File

@ -1,9 +1,30 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.tntleague.game package de.steamwar.tntleague.game
import de.steamwar.kotlin.util.Area
import de.steamwar.scoreboard.SWScoreboard import de.steamwar.scoreboard.SWScoreboard
import de.steamwar.sql.Fight import de.steamwar.sql.Fight
import de.steamwar.sql.FightPlayer import de.steamwar.sql.FightPlayer
import de.steamwar.sql.SteamwarUser import de.steamwar.sql.SteamwarUser
import de.steamwar.tntleague.colorByTeam
import de.steamwar.tntleague.config.TNTLeagueConfig import de.steamwar.tntleague.config.TNTLeagueConfig
import de.steamwar.tntleague.config.TNTLeagueWorldConfig import de.steamwar.tntleague.config.TNTLeagueWorldConfig
import de.steamwar.tntleague.config.world import de.steamwar.tntleague.config.world
@ -11,6 +32,7 @@ import de.steamwar.tntleague.events.DummyListener
import de.steamwar.tntleague.events.IngameListener import de.steamwar.tntleague.events.IngameListener
import de.steamwar.tntleague.events.LobbyListener import de.steamwar.tntleague.events.LobbyListener
import de.steamwar.tntleague.inventory.DealerInventory import de.steamwar.tntleague.inventory.DealerInventory
import de.steamwar.tntleague.message
import de.steamwar.tntleague.plugin import de.steamwar.tntleague.plugin
import de.steamwar.tntleague.util.* import de.steamwar.tntleague.util.*
import net.kyori.adventure.bossbar.BossBar import net.kyori.adventure.bossbar.BossBar
@ -18,12 +40,9 @@ import net.kyori.adventure.sound.Sound
import org.bukkit.GameMode import org.bukkit.GameMode
import org.bukkit.Location import org.bukkit.Location
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.block.data.type.TNT
import org.bukkit.entity.Entity
import org.bukkit.entity.Item import org.bukkit.entity.Item
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.entity.TNTPrimed import org.bukkit.entity.TNTPrimed
import org.bukkit.entity.Villager
import org.bukkit.event.HandlerList import org.bukkit.event.HandlerList
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@ -62,7 +81,7 @@ object TNTLeagueGame {
blueTeam.start() blueTeam.start()
redTeam.start() redTeam.start()
plugin.server.broadcast(translate("gameStarted").success()) message.broadcast("GAME_STARTED")
val tnt = ItemStack(Material.TNT) val tnt = ItemStack(Material.TNT)
@ -87,7 +106,7 @@ object TNTLeagueGame {
} }
if (gameTimeRemaining % 300 == 0) { if (gameTimeRemaining % 300 == 0) {
plugin.server.broadcast(translate("timeRemaining", (gameTimeRemaining / 60).toString().yellow()).basic()) message.broadcast("TIME_REMAINING", (gameTimeRemaining / 60))
plugin.server.onlinePlayers.forEach { it.playSound(Sound.sound(org.bukkit.Sound.BLOCK_NOTE_BLOCK_PLING.key, Sound.Source.MASTER, 1f, 1f)) } plugin.server.onlinePlayers.forEach { it.playSound(Sound.sound(org.bukkit.Sound.BLOCK_NOTE_BLOCK_PLING.key, Sound.Source.MASTER, 1f, 1f)) }
} }
}, 20, 20) }, 20, 20)
@ -105,7 +124,7 @@ object TNTLeagueGame {
it.playSound(Sound.sound(org.bukkit.Sound.ENTITY_ENDER_DRAGON_DEATH.key, Sound.Source.MASTER, 1f, 1f)) it.playSound(Sound.sound(org.bukkit.Sound.ENTITY_ENDER_DRAGON_DEATH.key, Sound.Source.MASTER, 1f, 1f))
} }
plugin.server.broadcast(translate("gameEnded").success()) message.broadcast("GAME_ENDED")
spawnerTask.cancel() spawnerTask.cancel()
@ -116,7 +135,7 @@ object TNTLeagueGame {
plugin.server.shutdown() plugin.server.shutdown()
} }
plugin.server.broadcast(translate("shutdown", shutdown.toString().yellow()).basic()) message.broadcast("SHUTDOWN", shutdown)
shutdown-- shutdown--
}, 20, 20) }, 20, 20)
@ -135,19 +154,15 @@ object TNTLeagueGame {
state = GameState.STARTING state = GameState.STARTING
var countdown = TNTLeagueConfig.config.startDelay var countdown = TNTLeagueConfig.config.startDelay
plugin.server.broadcast(translate("gameStarting", countdown.toString().yellow()).basic()) message.broadcast("GAME_STARTING", countdown.toString())
val bar = BossBar.bossBar(translate("gameStart", countdown.toString().yellow()).gray(), (TNTLeagueConfig.config.startDelay - countdown) / TNTLeagueConfig.config.startDelay.toFloat(), BossBar.Color.GREEN, BossBar.Overlay.NOTCHED_10)
plugin.server.onlinePlayers.forEach { bar.addViewer(it) }
task = plugin.server.scheduler.scheduleSyncRepeatingTask(plugin, { task = plugin.server.scheduler.scheduleSyncRepeatingTask(plugin, {
plugin.server.onlinePlayers.forEach { it.playSound(Sound.sound(org.bukkit.Sound.ENTITY_EXPERIENCE_ORB_PICKUP.key, Sound.Source.MASTER, 1f, 1f)) } plugin.server.onlinePlayers.forEach { it.playSound(Sound.sound(org.bukkit.Sound.ENTITY_EXPERIENCE_ORB_PICKUP.key, Sound.Source.MASTER, 1f, 1f)) }
if (countdown-- == 0) { if (--countdown == 0) {
plugin.server.onlinePlayers.forEach { it.hideBossBar(bar) } plugin.server.onlinePlayers.forEach { it.level = 0 }
task = task?.also { plugin.server.scheduler.cancelTask(it) }.let { null } task = task?.also { plugin.server.scheduler.cancelTask(it) }.let { null }
setup() setup()
} else { } else {
bar.name(translate("gameStart", countdown.toString().yellow()).gray()) plugin.server.onlinePlayers.forEach { it.level = countdown }
bar.progress((TNTLeagueConfig.config.startDelay - countdown) / TNTLeagueConfig.config.startDelay.toFloat())
plugin.server.onlinePlayers.filter { !it.activeBossBars().contains(bar) }.forEach { bar.addViewer(it) }
} }
}, 20, 20) }, 20, 20)
@ -162,7 +177,7 @@ object TNTLeagueGame {
redTeam.invites.remove(player) redTeam.invites.remove(player)
getTeam(player)?.apply { getTeam(player)?.apply {
members.remove(player) members.remove(player)
if (leader == player) { if (leader == player && members.isNotEmpty() && state == GameState.RUNNING) {
win(this.opposite, WinReason.LEAVE) win(this.opposite, WinReason.LEAVE)
} }
} }
@ -173,7 +188,6 @@ object TNTLeagueGame {
if (state == GameState.STARTING) { if (state == GameState.STARTING) {
task = task?.also { plugin.server.scheduler.cancelTask(it) }.let { null } task = task?.also { plugin.server.scheduler.cancelTask(it) }.let { null }
plugin.server.onlinePlayers.forEach { p -> p.activeBossBars().forEach { it.removeViewer(p) } }
state = GameState.LOBBY state = GameState.LOBBY
} }
} }
@ -181,7 +195,7 @@ object TNTLeagueGame {
fun win(tntLeagueTeam: TNTLeagueTeam, reason: WinReason) { fun win(tntLeagueTeam: TNTLeagueTeam, reason: WinReason) {
if (state != GameState.RUNNING) return if (state != GameState.RUNNING) return
end() end()
plugin.server.broadcast(translate("teamWin", translate(tntLeagueTeam.name).color(tntLeagueTeam.color)).success()) plugin.server.onlinePlayers.forEach { message.send("TEAM_WIN", it, message.parse(tntLeagueTeam.name, it).colorByTeam(tntLeagueTeam)) }
statistic(tntLeagueTeam, reason) statistic(tntLeagueTeam, reason)
explode(tntLeagueTeam.opposite) explode(tntLeagueTeam.opposite)
} }
@ -189,7 +203,7 @@ object TNTLeagueGame {
fun draw(reason: WinReason) { fun draw(reason: WinReason) {
if (state != GameState.RUNNING) return if (state != GameState.RUNNING) return
end() end()
plugin.server.broadcast(translate("draw").success()) message.broadcast("DRAW")
statistic(null, reason) statistic(null, reason)
} }

View File

@ -1,18 +1,36 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.tntleague.game package de.steamwar.tntleague.game
import de.steamwar.tntleague.colorByTeam
import de.steamwar.tntleague.config.TNTLeagueWorldConfig import de.steamwar.tntleague.config.TNTLeagueWorldConfig
import de.steamwar.tntleague.config.targetedBlocks import de.steamwar.tntleague.config.targetedBlocks
import de.steamwar.tntleague.message
import de.steamwar.tntleague.plugin import de.steamwar.tntleague.plugin
import de.steamwar.tntleague.util.*
import net.kyori.adventure.sound.Sound import net.kyori.adventure.sound.Sound
import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.text.Component
import net.kyori.adventure.text.format.TextColor
import org.bukkit.GameMode import org.bukkit.GameMode
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.enchantments.Enchantment import org.bukkit.enchantments.Enchantment
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.awt.Color.green
data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private val team: Team) { data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private val team: Team) {
@ -33,7 +51,7 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va
val name: String val name: String
get() = team.name.lowercase() get() = team.name.lowercase()
val color: TextColor val color: Char
get() = team.color get() = team.color
var isReady: Boolean = false var isReady: Boolean = false
@ -42,13 +60,7 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va
leader?.inventory?.setItem(4, readyItem()) leader?.inventory?.setItem(4, readyItem())
leader?.playSound(Sound.sound(org.bukkit.Sound.BLOCK_NOTE_BLOCK_PLING.key, Sound.Source.MASTER, 1f, 1f)) leader?.playSound(Sound.sound(org.bukkit.Sound.BLOCK_NOTE_BLOCK_PLING.key, Sound.Source.MASTER, 1f, 1f))
plugin.server.onlinePlayers.forEach { it.sendActionBar(translate(if (value) "isReady" else "isNotReady", translate(this.name).colorByTeam(this)).let { cmp -> message.broadcastActionbar(if (value) "IS_READY" else "IS_NOT_READY", name.colorByTeam(this))
if (value) {
cmp.green()
} else {
cmp.red()
}
}) }
if (value && opposite.isReady) { if (value && opposite.isReady) {
TNTLeagueGame.checkStart() TNTLeagueGame.checkStart()
@ -63,6 +75,8 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va
} }
} }
var coins: Int = 0
val opposite: TNTLeagueTeam val opposite: TNTLeagueTeam
get() = when (team) { get() = when (team) {
Team.BLUE -> TNTLeagueGame.redTeam Team.BLUE -> TNTLeagueGame.redTeam
@ -76,7 +90,7 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va
teleport(config.spawnLocation) teleport(config.spawnLocation)
gameMode = GameMode.ADVENTURE gameMode = GameMode.ADVENTURE
inventory.clear() inventory.clear()
plugin.server.broadcast(translate("joinTeam", name().colorByTeam(this@TNTLeagueTeam), translate(this@TNTLeagueTeam.name).colorByTeam(this@TNTLeagueTeam)).basic()) message.broadcast("JOIN_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name.colorByTeam(this@TNTLeagueTeam))
} }
if (leader == null) { if (leader == null) {
@ -89,13 +103,13 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va
fun readyItem() = if (isReady) { fun readyItem() = if (isReady) {
ItemStack.of(Material.LIME_DYE).apply { ItemStack.of(Material.LIME_DYE).apply {
itemMeta = itemMeta.apply { itemMeta = itemMeta.apply {
displayName(translate("ready").green().translate(leader!!)) displayName(Component.text(message.parse("READY", leader!!)))
} }
} }
} else { } else {
ItemStack.of(Material.RED_DYE).apply { ItemStack.of(Material.RED_DYE).apply {
itemMeta = itemMeta.apply { itemMeta = itemMeta.apply {
displayName(translate("notReady").red().translate(leader!!)) displayName(Component.text(message.parse("NOT_READY", leader!!)))
} }
} }
} }
@ -113,9 +127,7 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va
} }
fun leave(player: Player) { fun leave(player: Player) {
if (TNTLeagueGame.state == TNTLeagueGame.GameState.RUNNING) { if (TNTLeagueGame.state != TNTLeagueGame.GameState.RUNNING) {
TNTLeagueGame.playerLeave(player)
} else {
members.remove(player) members.remove(player)
if (members.isEmpty()) { if (members.isEmpty()) {
@ -125,6 +137,10 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va
} }
if (leader == player) { if (leader == player) {
leader = members.firstOrNull() leader = members.firstOrNull()
if (leader == null && TNTLeagueGame.state == TNTLeagueGame.GameState.LOBBY) {
isReady = false
}
} }
} }
} }
@ -135,12 +151,12 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va
teleport(TNTLeagueWorldConfig.lobby) teleport(TNTLeagueWorldConfig.lobby)
gameMode = GameMode.SPECTATOR gameMode = GameMode.SPECTATOR
inventory.clear() inventory.clear()
plugin.server.broadcast(translate("quitTeam", name().colorByTeam(this@TNTLeagueTeam), translate(this@TNTLeagueTeam.name).colorByTeam(this@TNTLeagueTeam)).basic()) message.broadcast("QUIT_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name.colorByTeam(this@TNTLeagueTeam))
} }
} }
enum class Team(val color: TextColor) { enum class Team(val color: Char) {
BLUE(NamedTextColor.BLUE), BLUE('9'),
RED(NamedTextColor.RED); RED('c');
} }
} }

View File

@ -1,11 +1,32 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.tntleague.inventory package de.steamwar.tntleague.inventory
import de.steamwar.kotlin.inventory.SWInventoryHolder
import de.steamwar.tntleague.config.TNTLeagueConfig import de.steamwar.tntleague.config.TNTLeagueConfig
import de.steamwar.tntleague.game.TNTLeagueGame
import de.steamwar.tntleague.message
import de.steamwar.tntleague.plugin import de.steamwar.tntleague.plugin
import de.steamwar.tntleague.util.*
import net.kyori.adventure.sound.Sound import net.kyori.adventure.sound.Sound
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import net.kyori.adventure.text.format.Style import net.kyori.adventure.text.format.NamedTextColor
import net.kyori.adventure.text.format.TextDecoration import net.kyori.adventure.text.format.TextDecoration
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
@ -16,7 +37,7 @@ import org.bukkit.persistence.PersistentDataType
import java.util.* import java.util.*
import kotlin.math.ceil import kotlin.math.ceil
class DealerInventory(player: Player): SWInventoryHolder() { class DealerInventory(val player: Player): SWInventoryHolder() {
init { init {
items.forEachIndexed { index, item -> items.forEachIndexed { index, item ->
@ -24,19 +45,21 @@ class DealerInventory(player: Player): SWInventoryHolder() {
val price = item.second.price * if (it.isShiftClick) 5 else 1 val price = item.second.price * if (it.isShiftClick) 5 else 1
val amount = item.second.amount * if (it.isShiftClick) 5 else 1 val amount = item.second.amount * if (it.isShiftClick) 5 else 1
if (!player.inventory.containsAtLeast(coins, price)) { val team = TNTLeagueGame.getTeam(player) ?: return@to
player.sendMessage(translate("notEnoughCoins").error())
if (team.coins < price) {
message.send("NOT_ENOUGH_COINS", player)
player.playSound(Sound.sound(org.bukkit.Sound.ENTITY_VILLAGER_HURT.key, net.kyori.adventure.sound.Sound.Source.MASTER, 1f, 1f)) player.playSound(Sound.sound(org.bukkit.Sound.ENTITY_VILLAGER_HURT.key, net.kyori.adventure.sound.Sound.Source.MASTER, 1f, 1f))
return@to return@to
} }
player.inventory.removeItem(coins.asQuantity(price)) team.coins -= price
player.inventory.addItem(ItemStack.of(item.first.type, amount)) player.inventory.addItem(ItemStack.of(item.first.type, amount))
} }
} }
} }
override fun createInventory(): Inventory = plugin.server.createInventory(this, ceil(TNTLeagueConfig.config.prices.size / 9f).toInt() * 9, translate("dealer").reset()) override fun createInventory(): Inventory = plugin.server.createInventory(this, ceil(TNTLeagueConfig.config.prices.size / 9f).toInt() * 9, Component.text(message.parse("DEALER", player)))
companion object { companion object {
private val priceKey = NamespacedKey(plugin, "price") private val priceKey = NamespacedKey(plugin, "price")
@ -45,7 +68,7 @@ class DealerInventory(player: Player): SWInventoryHolder() {
val coins = ItemStack(Material.RAW_GOLD).apply { val coins = ItemStack(Material.RAW_GOLD).apply {
itemMeta = itemMeta.apply { itemMeta = itemMeta.apply {
displayName(Component.text("Coins").bold().gold()) displayName(Component.text("Coins").color(NamedTextColor.GOLD))
persistentDataContainer.apply { persistentDataContainer.apply {
set(coinKey, PersistentDataType.BOOLEAN, true) set(coinKey, PersistentDataType.BOOLEAN, true)
} }
@ -58,11 +81,13 @@ class DealerInventory(player: Player): SWInventoryHolder() {
prices.map { (material, price) -> prices.map { (material, price) ->
ItemStack(material).apply { ItemStack(material).apply {
itemMeta = itemMeta.apply { itemMeta = itemMeta.apply {
displayName(material.name.lowercase().replace("_", " ") displayName(Component.text(material.name.lowercase().replace("_", " ")
.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() })
.component().gray().appendSpace().append(price.amount.toString().component().yellow())) .color(NamedTextColor.GRAY).appendSpace().append(Component.text(price.amount).color(NamedTextColor.YELLOW)))
amount = price.amount amount = price.amount
lore(listOf(price.price.toString().component().yellow().bold().appendSpace().append(Component.text("Coins").yellow()))) lore(listOf(Component.text(price.price).color(NamedTextColor.YELLOW).decorate(TextDecoration.BOLD).appendSpace().append(Component.text("Coins").color(NamedTextColor.YELLOW))))
persistentDataContainer.apply { persistentDataContainer.apply {
set(priceKey, PersistentDataType.INTEGER, price.price) set(priceKey, PersistentDataType.INTEGER, price.price)
set(amountKey, PersistentDataType.INTEGER, price.amount) set(amountKey, PersistentDataType.INTEGER, price.amount)

View File

@ -1,73 +0,0 @@
package de.steamwar.tntleague.util
import de.steamwar.tntleague.game.TNTLeagueTeam
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.ComponentLike
import net.kyori.adventure.text.TranslatableComponent
import net.kyori.adventure.text.format.NamedTextColor
import net.kyori.adventure.text.format.Style
import net.kyori.adventure.text.format.TextDecoration
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import net.kyori.adventure.translation.GlobalTranslator
import org.bukkit.entity.Player
import java.util.Locale
val prefix = Component.text("Steam").yellow()
.append(Component.text("War").darkGray())
.appendSpace()
val tntLeaguePrefix = Component.text("TNT").color(NamedTextColor.DARK_RED)
.append(Component.text("League").color(NamedTextColor.GOLD))
val tntLeagueChatPrefix: Component = tntLeaguePrefix
.append(Component.text("»").darkGray())
.appendSpace()
fun TranslatableComponent.basic(): Component = tntLeagueChatPrefix.append(this.gray())
fun TranslatableComponent.error(): Component = tntLeagueChatPrefix.append(this.red())
fun TranslatableComponent.success(): Component = tntLeagueChatPrefix.append(this.green())
fun String.component(): Component = Component.text(this)
fun Component.bold(): Component = this.decorate(TextDecoration.BOLD)
fun String.bold(): Component = this.component().bold()
fun Component.yellow(): Component = this.color(NamedTextColor.YELLOW)
fun String.yellow(): Component = this.component().yellow()
fun Component.red(): Component = this.color(NamedTextColor.RED)
fun String.red(): Component = this.component().red()
fun Component.green(): Component = this.color(NamedTextColor.GREEN)
fun String.green(): Component = this.component().green()
fun Component.gray(): Component = this.color(NamedTextColor.GRAY)
fun String.gray(): Component = this.component().gray()
fun Component.darkGray(): Component = this.color(NamedTextColor.DARK_GRAY)
fun String.darkGray(): Component = this.component().darkGray()
fun Component.gold(): Component = this.color(NamedTextColor.GOLD)
fun translate(key: String, vararg args: ComponentLike): TranslatableComponent = Component.translatable(key, *args).decoration(TextDecoration.ITALIC, false)
fun Component.reset(): Component = this.style(Style.empty())
fun Component.colorByTeam(team: TNTLeagueTeam?) = when (team) {
null -> this.gray()
else -> this.color(team.color)
}
fun Component.translate(locale: Locale): Component = GlobalTranslator.render(this, locale)
fun Component.translate(p: Player): Component = this.translate(p.locale())
fun Component.toLegacy(): String = LegacyComponentSerializer.legacySection().serialize(this)

View File

@ -20,38 +20,46 @@
package de.steamwar.tntleague.util package de.steamwar.tntleague.util
import de.steamwar.scoreboard.ScoreboardCallback import de.steamwar.scoreboard.ScoreboardCallback
import de.steamwar.tntleague.colorByTeam
import de.steamwar.tntleague.config.targetedBlocks import de.steamwar.tntleague.config.targetedBlocks
import de.steamwar.tntleague.game.TNTLeagueGame import de.steamwar.tntleague.game.TNTLeagueGame
import net.kyori.adventure.text.Component import de.steamwar.tntleague.game.TNTLeagueTeam
import de.steamwar.tntleague.message
import org.bukkit.entity.Player import org.bukkit.entity.Player
import kotlin.collections.HashMap import kotlin.collections.HashMap
private val scoreboardTitle by lazy { tntLeaguePrefix.toLegacy() }
data class TNTLeagueScoreboard(val p: Player): ScoreboardCallback { data class TNTLeagueScoreboard(val p: Player): ScoreboardCallback {
override fun getData(): HashMap<String, Int> { override fun getData(): HashMap<String, Int> {
val lines = mutableListOf<Component>() val lines = mutableListOf<String>()
lines.add(Component.space().green()) lines.add("§1")
val minutes = TNTLeagueGame.gameTimeRemaining.floorDiv(60) val minutes = TNTLeagueGame.gameTimeRemaining.floorDiv(60)
val seconds = TNTLeagueGame.gameTimeRemaining.rem(60).toString().padStart(2, '0') val seconds = TNTLeagueGame.gameTimeRemaining.rem(60).toString().padStart(2, '0')
lines.add(translate("scoreboardTime", minutes.toString().yellow(), seconds.yellow()).gray()) lines.add(message.parse("SCOREBOARD_TIME", p, minutes, seconds))
lines.add(Component.space().yellow()) lines.add("§2")
with(TNTLeagueGame.blueTeam) { when (val team = TNTLeagueGame.getTeam(p)) {
lines.add(translate("scoreboardTeam", translate(name).colorByTeam(this), (targetedBlocks - damagedBlocks).toString().yellow()).gray()) is TNTLeagueTeam -> lines.add(message.parse("SCOREBOARD_COINS", p, team.coins))
else -> lines.add(message.parse("SCOREBOARD_COINS", p,
"§${TNTLeagueGame.blueTeam.color}${TNTLeagueGame.blueTeam.coins}§8:§${TNTLeagueGame.redTeam.color}${TNTLeagueGame.redTeam.coins}"))
} }
lines.add("§3")
with(TNTLeagueGame.redTeam) { with(TNTLeagueGame.redTeam) {
lines.add(translate("scoreboardTeam", translate(name).colorByTeam(this), (targetedBlocks - damagedBlocks).toString().yellow()).gray()) lines.add(message.parse("SCOREBOARD_TEAM", p, message.parse(name, p).colorByTeam(this), targetedBlocks - damagedBlocks))
}
with(TNTLeagueGame.blueTeam) {
lines.add(message.parse("SCOREBOARD_TEAM", p, message.parse(name, p).colorByTeam(this), targetedBlocks - damagedBlocks))
} }
lines.add(Component.space().gray()) lines.add("§4")
return lines return lines
.foldIndexed(HashMap()) { index, acc, component -> acc.also { it[component.translate(p).toLegacy()] = index } } .foldIndexed(HashMap()) { index, acc, component -> acc.also { it[component] = index } }
} }
override fun getTitle(): String = scoreboardTitle override fun getTitle(): String = message.parse("PREFIX", p).dropLast(1)
} }

View File

@ -4,7 +4,10 @@ main: de.steamwar.tntleague.TNTLeague
load: POSTWORLD load: POSTWORLD
api-version: '1.21' api-version: '1.21'
dependencies: dependencies:
- name: SpigotCore server:
required: true SpigotCore:
- name: KotlinCore required: true
required: true load: BEFORE
KotlinCore:
required: true
load: BEFORE

View File

@ -7,7 +7,8 @@ artifacts:
"/binarys/fightsystem.jar": "FightSystem/build/libs/FightSystem-all.jar" "/binarys/fightsystem.jar": "FightSystem/build/libs/FightSystem-all.jar"
"/binarys/FightSystem_Standalone.jar": "FightSystem/FightSystem_Standalone/build/libs/FightSystem_Standalone-all.jar" "/binarys/FightSystem_Standalone.jar": "FightSystem/FightSystem_Standalone/build/libs/FightSystem_Standalone-all.jar"
# KotlinCore !! "/binarys/kotlincore.jar": "KotlinCore/build/libs/KotlinCore-all.jar"
"/binarys/tntleague.jar": "TNTLeague/build/libs/TNTLeague.jar"
"/binarys/lobbysystem2.0.jar": "LobbySystem/build/libs/LobbySystem.jar" "/binarys/lobbysystem2.0.jar": "LobbySystem/build/libs/LobbySystem.jar"