diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java index eca895f4..b9ae84b7 100644 --- a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/Message.java @@ -71,6 +71,13 @@ public class Message { pattern = fromRB(resourceBundle, "PREFIX") + " "; pattern += fromRB(resourceBundle, message); + for (int i = 0; i < params.length; i++) { + if (params[i] instanceof SubMessage) { + SubMessage smsg = (SubMessage) params[i]; + params[i] = parse(smsg.getMessage(), sender, smsg.getParams()); + } + } + return new MessageFormat(pattern, locale).format(params); } diff --git a/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java new file mode 100644 index 00000000..d6a87ba7 --- /dev/null +++ b/SpigotCore/SpigotCore_Main/src/de/steamwar/message/SubMessage.java @@ -0,0 +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 . + */ + +package de.steamwar.message; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class SubMessage { + private final String message; + private final Object[] params = new Object[0]; +} diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties index 03a4e361..05d998e2 100644 --- a/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties +++ b/TNTLeague/src/de/steamwar/tntleague/TNTLeague.properties @@ -22,8 +22,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 +BLUE=§3Blue +RED=§cRed 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! @@ -46,4 +46,12 @@ 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! \ No newline at end of file +INVITED_PLAYER=§aInvited §e{0} §ato join your team! + +DEALER_REDSTONE=§eRedstone +DEALER_BLOCKS=§eBlocks +DEALER_TOOLS=§eTools +DEALER_ANGLES=§eAngle Blocks + +PARTICIPANT_CHAT={0} {1}§8» §7{2} +SPECTATOR_CHAT=§7{0}§8» §7{1} \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de.properties b/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de.properties index 8d3d3d06..db81812b 100644 --- a/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de.properties +++ b/TNTLeague/src/de/steamwar/tntleague/TNTLeague_de.properties @@ -20,8 +20,8 @@ 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 +BLUE=§3Blau +RED=§cRot 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! @@ -41,4 +41,8 @@ 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! \ No newline at end of file +INVITED_PLAYER={0} §awurde eingeladen! + +DEALER_BLOCKS=§eBlöcke +DEALER_TOOLS=§eWerkzeuge +DEALER_ANGLES=§eAuflageblöcke \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt b/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt index feec0215..8ecf50cb 100644 --- a/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt +++ b/TNTLeague/src/de/steamwar/tntleague/command/InviteCommand.kt @@ -21,6 +21,7 @@ package de.steamwar.tntleague.command import de.steamwar.command.SWCommand import de.steamwar.command.TypeValidator +import de.steamwar.message.SubMessage import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.game.TNTLeagueGame import de.steamwar.tntleague.message @@ -38,8 +39,8 @@ object InviteCommand: SWCommand("invite") { team.invites.add(target) message - .send("INVITED", target, message.parse("INVITED_HOVER", target, team.name.colorByTeam(team)), - ClickEvent(ClickEvent.Action.RUN_COMMAND, "/accept " + sender.name), sender.name, team.name.colorByTeam(team), ) + .send("INVITED", target, message.parse("INVITED_HOVER", target, SubMessage(team.name)), + ClickEvent(ClickEvent.Action.RUN_COMMAND, "/accept " + sender.name), sender.name.colorByTeam(team), SubMessage(team.name), ) message.send("INVITED_PLAYER", sender, target.name) } diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt index cf48afe7..1a3dd221 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueConfig.kt @@ -23,12 +23,21 @@ import de.steamwar.tntleague.plugin import org.bukkit.Material import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.file.FileConfiguration +import org.bukkit.enchantments.Enchantment +import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.BookMeta +import org.bukkit.inventory.meta.Damageable +import org.bukkit.inventory.meta.ItemMeta +import java.util.UUID data class TNTLeagueConfig( val startDelay: Int = 10, val gameTime: Int = 60 * 20, - val prices: Map + val prices: Map, + + val blueLeader: UUID? = System.getProperty("blueLeader")?.let { UUID.fromString(it) }, + val redLeader: UUID? = System.getProperty("redLeader")?.let { UUID.fromString(it) }, ) { companion object { val config: TNTLeagueConfig by lazy { loadConfig(plugin.config) } @@ -41,14 +50,48 @@ data class TNTLeagueConfig( return config.getKeys(false).associateWith { Price( config.getInt("$it.amount"), - config.getInt("$it.price") + config.getInt("$it.price"), + config.getString("$it.category")?.let { s -> categoryFromString[s] } ?: ItemCategory.REDSTONE, + config.getInt("$it.pinned", -1), + config.getStringList("$it.extras").map { s -> extrasFromString[s]!! }.toSet() ) - }.mapKeys { Material.getMaterial(it.key)!! } + }.mapKeys { Material.getMaterial(it.key) ?: Material.BARRIER } } } data class Price( val amount: Int, val price: Int, + val category: ItemCategory, + val pinned: Int, + val extras: Set ) + + enum class ItemCategory { + REDSTONE, + BLOCKS, + TOOLS, + ANGLES; + } + + enum class ItemExtra(val func: (item: ItemMeta) -> ItemMeta) { + ONESHOT({ + if (it is Damageable) { + it.damage = 384 + } + + it + }), + FLAME({ + it.addEnchant(Enchantment.FLAME, 1, false) + it + }), + UNBREAKING({ + it.addEnchant(Enchantment.UNBREAKING, 1, false) + it + }) + } } + +val categoryFromString = TNTLeagueConfig.ItemCategory.entries.associateBy { it.name.lowercase() } +val extrasFromString = TNTLeagueConfig.ItemExtra.entries.associateBy { it.name.lowercase() } diff --git a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt index 6be87d7e..7fc94826 100644 --- a/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt +++ b/TNTLeague/src/de/steamwar/tntleague/config/TNTLeagueWorldConfig.kt @@ -69,6 +69,7 @@ object TNTLeagueWorldConfig { minHeight = config.getInt("minHeight", 0) target = config.getInt("target", -1) } catch (e: NullPointerException) { + e.printStackTrace() Bukkit.shutdown() } } diff --git a/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt index e930106b..1d9eb19d 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/GlobalListener.kt @@ -19,14 +19,14 @@ package de.steamwar.tntleague.events +import de.steamwar.kotlin.inventory.SWInventoryHolder +import de.steamwar.message.SubMessage import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.TNTLeagueWorldConfig import de.steamwar.tntleague.game.TNTLeagueGame import de.steamwar.tntleague.game.TNTLeagueTeam -import de.steamwar.kotlin.inventory.SWInventoryHolder import de.steamwar.tntleague.message import de.steamwar.tntleague.plugin -import org.bukkit.Bukkit import org.bukkit.GameMode import org.bukkit.Material import org.bukkit.event.EventHandler @@ -35,10 +35,8 @@ import org.bukkit.event.Listener import org.bukkit.event.entity.PlayerDeathEvent import org.bukkit.event.inventory.CraftItemEvent import org.bukkit.event.inventory.InventoryClickEvent -import org.bukkit.event.player.PlayerJoinEvent -import org.bukkit.event.player.PlayerMoveEvent -import org.bukkit.event.player.PlayerQuitEvent -import org.bukkit.event.player.PlayerRespawnEvent +import org.bukkit.event.player.* +import java.util.logging.Level object GlobalListener: Listener { @@ -48,7 +46,6 @@ object GlobalListener: Listener { with(e.player) { teleport(TNTLeagueWorldConfig.lobby) inventory.clear() - message.broadcast("JOIN", name) isOp = false gameMode = GameMode.SPECTATOR respawnLocation = TNTLeagueWorldConfig.lobby @@ -58,7 +55,6 @@ object GlobalListener: Listener { @EventHandler(priority = EventPriority.HIGHEST) fun onPlayerQuit(e: PlayerQuitEvent) { e.quitMessage(null) - message.broadcast("QUIT", e.player.name.colorByTeam(TNTLeagueGame.getTeam(e.player))) TNTLeagueGame.playerLeave(e.player) if (plugin.server.onlinePlayers.size == 1 && plugin.server.onlinePlayers.first() == e.player) { @@ -109,4 +105,20 @@ object GlobalListener: Listener { null -> e.respawnLocation = TNTLeagueWorldConfig.lobby } } + + + @EventHandler + fun handlePlayerChat(event: AsyncPlayerChatEvent) { + val player = event.player + val msg = event.message + + val fightTeam = TNTLeagueGame.getTeam(player) + if (fightTeam != null) { + message.broadcastPrefixless("PARTICIPANT_CHAT", SubMessage(fightTeam.name), player.name, msg) + } else { + message.broadcastPrefixless("SPECTATOR_CHAT", player.name, msg) + } + + event.isCancelled = true + } } \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt b/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt index d61be80b..586b0e79 100644 --- a/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt +++ b/TNTLeague/src/de/steamwar/tntleague/events/LobbyListener.kt @@ -33,7 +33,7 @@ object LobbyListener: Listener { @EventHandler fun onPlayerJoin(e: PlayerJoinEvent) { - TNTLeagueGame.getFreeTeam()?.run { + TNTLeagueGame.getFreeTeam(e.player)?.run { join(e.player) TNTLeagueGame.checkStart() } diff --git a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt index 8c278620..d8a36718 100644 --- a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt +++ b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueGame.kt @@ -20,6 +20,9 @@ package de.steamwar.tntleague.game import de.steamwar.kotlin.util.Area +import de.steamwar.message.SubMessage +import de.steamwar.network.NetworkSender +import de.steamwar.network.packets.common.FightInfoPacket import de.steamwar.scoreboard.SWScoreboard import de.steamwar.sql.Fight import de.steamwar.sql.FightPlayer @@ -80,6 +83,8 @@ object TNTLeagueGame { blueTeam.start() redTeam.start() + updateFightinfo() + message.broadcast("GAME_STARTED") val tnt = ItemStack(Material.TNT) @@ -143,13 +148,17 @@ object TNTLeagueGame { shutdown-- }, 20, 20) + + updateFightinfo() } private fun spawnItems(loc: Location, item: ItemStack) = plugin.server.worlds.first().dropItem(loc, item) fun getTeam(player: Player) = if (player in blueTeam.members) blueTeam else if (player in redTeam.members) redTeam else null - fun getFreeTeam() = if (blueTeam.leader == null) blueTeam else if (redTeam.leader == null) redTeam else null + fun getFreeTeam(player: Player) = if (blueTeam.leader == null && (TNTLeagueConfig.config.blueLeader == null || player.uniqueId == TNTLeagueConfig.config.blueLeader)) blueTeam + else if (redTeam.leader == null && TNTLeagueConfig.config.redLeader == null || player.uniqueId == TNTLeagueConfig.config.redLeader) redTeam + else null fun checkStart() { if (blueTeam.isReady && redTeam.isReady) { @@ -173,6 +182,8 @@ object TNTLeagueGame { if (task == -1) { error("Failed to start countdown task") } + + updateFightinfo() } } @@ -191,12 +202,14 @@ object TNTLeagueGame { task = task?.also { plugin.server.scheduler.cancelTask(it) }.let { null } state = GameState.LOBBY } + + updateFightinfo() } fun win(tntLeagueTeam: TNTLeagueTeam, reason: WinReason) { if (state != GameState.RUNNING) return end() - plugin.server.onlinePlayers.forEach { message.send("TEAM_WIN", it, message.parse(tntLeagueTeam.name, it).colorByTeam(tntLeagueTeam)) } + plugin.server.onlinePlayers.forEach { message.send("TEAM_WIN", it, SubMessage(tntLeagueTeam.name)) } explode(tntLeagueTeam.opposite) } @@ -217,18 +230,23 @@ object TNTLeagueGame { } } - private fun addTeamMember(team: TNTLeagueTeam, fightId: Int) { - team.members.filter { team.leader != it } - .forEach { - FightPlayer.create( - fightId, - SteamwarUser.get(it.uniqueId).id, - team == blueTeam, - "TNTLeague", - 0, - false - ) - } + fun updateFightinfo() { + NetworkSender.send(FightInfoPacket( + plugin.server.worlds.first().name, + "TNTLeague", + "", + blueTeam.name.colorByTeam(blueTeam), + redTeam.name.colorByTeam(redTeam), + state.name, + TNTLeagueConfig.config.gameTime - gameTimeRemaining, + blueTeam.leader?.let { SteamwarUser.get(it.uniqueId).id } ?: 0, + redTeam.leader?.let { SteamwarUser.get(it.uniqueId).id } ?: 0, + 0, + 0, + blueTeam.members.map { SteamwarUser.get(it.uniqueId).id }, + redTeam.members.map { SteamwarUser.get(it.uniqueId).id }, + plugin.server.onlinePlayers.filter {! blueTeam.members.contains(it) && !redTeam.members.contains(it) }.map { SteamwarUser.get(it.uniqueId).id } + )) } enum class GameState(val listener: Listener) { diff --git a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt index cfb23dca..862337ba 100644 --- a/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt +++ b/TNTLeague/src/de/steamwar/tntleague/game/TNTLeagueTeam.kt @@ -19,10 +19,12 @@ package de.steamwar.tntleague.game +import de.steamwar.message.SubMessage import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.TNTLeagueWorldConfig import de.steamwar.tntleague.config.targetedBlocks import de.steamwar.tntleague.game.TNTLeagueGame.WinReason +import de.steamwar.tntleague.game.TNTLeagueGame.updateFightinfo import de.steamwar.tntleague.game.TNTLeagueGame.win import de.steamwar.tntleague.message import de.steamwar.tntleague.plugin @@ -62,7 +64,7 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va leader?.inventory?.setItem(4, readyItem()) leader?.let { it.playSound(it.location, Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 1f) } - message.broadcastActionbar(if (value) "IS_READY" else "IS_NOT_READY", name.colorByTeam(this)) + message.broadcastActionbar(if (value) "IS_READY" else "IS_NOT_READY", SubMessage(name)) if (value && opposite.isReady) { TNTLeagueGame.checkStart() @@ -73,7 +75,7 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va set(value) { field = value if (value >= targetedBlocks) { - TNTLeagueGame.win(this, TNTLeagueGame.WinReason.DESTROYED) + win(this, WinReason.DESTROYED) } } @@ -92,13 +94,15 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va teleport(config.spawnLocation) gameMode = GameMode.ADVENTURE inventory.clear() - message.broadcast("JOIN_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name.colorByTeam(this@TNTLeagueTeam)) + message.broadcast("JOIN_TEAM", name.colorByTeam(this@TNTLeagueTeam), SubMessage(name)) } if (leader == null) { leader = player } + updateFightinfo() + return true } @@ -156,12 +160,13 @@ data class TNTLeagueTeam(val config: TNTLeagueWorldConfig.TeamConfig, private va teleport(TNTLeagueWorldConfig.lobby) gameMode = GameMode.SPECTATOR inventory.clear() - message.broadcast("QUIT_TEAM", name.colorByTeam(this@TNTLeagueTeam), this@TNTLeagueTeam.name.colorByTeam(this@TNTLeagueTeam)) + message.broadcast("QUIT_TEAM", name.colorByTeam(this@TNTLeagueTeam), SubMessage(name)) } + updateFightinfo() } enum class Team(val color: Char) { - BLUE('9'), + BLUE('3'), RED('c'); } } \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/inventory/CategoryInventory.kt b/TNTLeague/src/de/steamwar/tntleague/inventory/CategoryInventory.kt new file mode 100644 index 00000000..3a23812f --- /dev/null +++ b/TNTLeague/src/de/steamwar/tntleague/inventory/CategoryInventory.kt @@ -0,0 +1,40 @@ +/* + * 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 . + */ + +package de.steamwar.tntleague.inventory + +import de.steamwar.kotlin.inventory.SWInventoryHolder +import de.steamwar.tntleague.config.TNTLeagueConfig +import de.steamwar.tntleague.inventory.DealerInventory.Companion.buyItem +import de.steamwar.tntleague.inventory.DealerInventory.Companion.itemsByCategory +import de.steamwar.tntleague.message +import net.kyori.adventure.text.Component +import org.bukkit.Bukkit +import org.bukkit.entity.Player +import org.bukkit.inventory.Inventory + +class CategoryInventory(val player: Player, category: TNTLeagueConfig.ItemCategory): SWInventoryHolder() { + override fun createInventory(): Inventory = Bukkit.createInventory(this, 9 * 6, Component.text(message.parse("DEALER", player))) + + init { + itemsByCategory[category]!!.forEachIndexed { index, item -> + this[index] = item.first to { buyItem(player, item, it) } + } + } +} \ No newline at end of file diff --git a/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt b/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt index dc5813b8..7103edd8 100644 --- a/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt +++ b/TNTLeague/src/de/steamwar/tntleague/inventory/DealerInventory.kt @@ -19,6 +19,7 @@ package de.steamwar.tntleague.inventory +import de.steamwar.inventory.SWItem import de.steamwar.kotlin.inventory.SWInventoryHolder import de.steamwar.tntleague.config.TNTLeagueConfig import de.steamwar.tntleague.game.TNTLeagueGame @@ -31,6 +32,7 @@ import org.bukkit.Material import org.bukkit.NamespacedKey import org.bukkit.Sound import org.bukkit.entity.Player +import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.inventory.Inventory import org.bukkit.inventory.ItemStack import org.bukkit.persistence.PersistentDataType @@ -40,26 +42,19 @@ import kotlin.math.ceil class DealerInventory(val player: Player): SWInventoryHolder() { init { - items.forEachIndexed { index, item -> - this[index] = item.first to { - val price = item.second.price * if (it.isShiftClick) 5 else 1 - val amount = item.second.amount * if (it.isShiftClick) 5 else 1 + this[10] = SWItem(Material.REDSTONE_BLOCK, message.parse("DEALER_REDSTONE", player)).itemStack to openCategory(TNTLeagueConfig.ItemCategory.REDSTONE) + this[12] = SWItem(Material.END_STONE, message.parse("DEALER_BLOCKS", player)).itemStack to openCategory(TNTLeagueConfig.ItemCategory.BLOCKS) + this[14] = SWItem(Material.DIAMOND_PICKAXE, message.parse("DEALER_TOOLS", player)).itemStack to openCategory(TNTLeagueConfig.ItemCategory.TOOLS) + this[16] = SWItem(Material.BREWING_STAND, message.parse("DEALER_ANGLES", player)).itemStack to openCategory(TNTLeagueConfig.ItemCategory.ANGLES) - val team = TNTLeagueGame.getTeam(player) ?: return@to - - if (team.coins < price) { - message.send("NOT_ENOUGH_COINS", player) - player.playSound(player, Sound.ENTITY_VILLAGER_HURT, 1f, 1f) - return@to - } - - team.coins -= price - player.inventory.addItem(ItemStack.of(item.first.type, amount)) - } + pinnedItems.forEach { item -> + this[item.key] = item.value.first to { buyItem(player, item.value, it) } } } - override fun createInventory(): Inventory = plugin.server.createInventory(this, ceil(TNTLeagueConfig.config.prices.size / 9f).toInt() * 9, Component.text(message.parse("DEALER", player))) + private fun openCategory(cat: TNTLeagueConfig.ItemCategory): (e: InventoryClickEvent) -> Unit = { player.openInventory(CategoryInventory(player, cat).inventory) } + + override fun createInventory(): Inventory = plugin.server.createInventory(this, 6 * 9, Component.text(message.parse("DEALER", player))) companion object { private val priceKey = NamespacedKey(plugin, "price") @@ -75,7 +70,23 @@ class DealerInventory(val player: Player): SWInventoryHolder() { } } - val items by lazy { + fun buyItem(player: Player, item: Pair, e: InventoryClickEvent) { + val price = item.second.price * if (e.isShiftClick) 5 else 1 + val amount = item.second.amount * if (e.isShiftClick) 5 else 1 + + val team = TNTLeagueGame.getTeam(player) ?: return + + if (team.coins < price) { + message.send("NOT_ENOUGH_COINS", player) + player.playSound(player, Sound.ENTITY_VILLAGER_HURT, 1f, 1f) + return + } + + team.coins -= price + player.inventory.addItem(ItemStack.of(item.first.type, amount).also { item.second.extras.forEach { extra -> it.itemMeta = extra.func(it.itemMeta) } }) + } + + private val items by lazy { val prices = TNTLeagueConfig.config.prices prices.map { (material, price) -> @@ -96,5 +107,8 @@ class DealerInventory(val player: Player): SWInventoryHolder() { } to price } } + + val itemsByCategory = items.groupBy { it.second.category } + val pinnedItems = items.filter { it.second.pinned != -1 }.associateBy { it.second.pinned } } } diff --git a/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt b/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt index 27c129de..77ba1d48 100644 --- a/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt +++ b/TNTLeague/src/de/steamwar/tntleague/util/TNTLeagueScoreboard.kt @@ -19,6 +19,7 @@ package de.steamwar.tntleague.util +import de.steamwar.message.SubMessage import de.steamwar.scoreboard.ScoreboardCallback import de.steamwar.tntleague.colorByTeam import de.steamwar.tntleague.config.targetedBlocks @@ -49,10 +50,10 @@ data class TNTLeagueScoreboard(val p: Player): ScoreboardCallback { lines.add("§3") with(TNTLeagueGame.redTeam) { - lines.add(message.parse("SCOREBOARD_TEAM", p, message.parse(name, p).colorByTeam(this), targetedBlocks - damagedBlocks)) + lines.add(message.parse("SCOREBOARD_TEAM", p, SubMessage(name), targetedBlocks - damagedBlocks)) } with(TNTLeagueGame.blueTeam) { - lines.add(message.parse("SCOREBOARD_TEAM", p, message.parse(name, p).colorByTeam(this), targetedBlocks - damagedBlocks)) + lines.add(message.parse("SCOREBOARD_TEAM", p, SubMessage(name), targetedBlocks - damagedBlocks)) } lines.add("§4")