From c301e775c90e3b5b92da35a7331870c03d2b9e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Thu, 16 Oct 2025 00:24:48 +0200 Subject: [PATCH] added translation to all messages, ChatFormatHandler and new chat icons --- .../minenet/minigames/command/Commands.java | 7 +- .../command/privileged/FakeplayerCommand.java | 31 --- .../privileged/SetRoomOwnerCommand.java | 4 +- .../minenet/minigames/handler/Listeners.java | 3 +- .../handler/global/ChatFormatHandler.java | 20 ++ .../handler/global/PlayerLeaveHandler.java | 10 +- .../handler/global/PlayerLoginHandler.java | 2 - .../minenet/minigames/instance/game/Game.java | 21 +- .../game/stateless/StatelessGame.java | 28 ++- .../types/elytraRace/ElytraRace.java | 206 +++++++++--------- .../instance/hub/inventory/JoinInventory.java | 6 +- .../minenet/minigames/instance/room/Room.java | 14 +- .../instance/room/entity/GameSelector.java | 4 +- .../mhsl/minenet/minigames/message/Icon.java | 5 +- .../message/TranslatableMessage.java | 17 +- src/main/resources/lang/locales.map.csv | 13 ++ 16 files changed, 225 insertions(+), 166 deletions(-) delete mode 100644 src/main/java/eu/mhsl/minenet/minigames/command/privileged/FakeplayerCommand.java create mode 100644 src/main/java/eu/mhsl/minenet/minigames/handler/global/ChatFormatHandler.java diff --git a/src/main/java/eu/mhsl/minenet/minigames/command/Commands.java b/src/main/java/eu/mhsl/minenet/minigames/command/Commands.java index a9a6a90..0c99f7e 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/command/Commands.java +++ b/src/main/java/eu/mhsl/minenet/minigames/command/Commands.java @@ -21,7 +21,6 @@ public enum Commands { ROOM(new RoomCommand()), UPDATE(new RefreshCommandsCommand()), OP(new OpCommand()), - FAKEPLAYER(new FakeplayerCommand()), KICK(new KickCommand()), SKIN(new SkinCommand()), SETOWNER(new SetRoomOwnerCommand()), @@ -41,7 +40,11 @@ public enum Commands { static { MinecraftServer.getCommandManager().setUnknownCommandCallback((sender, command) -> { if(command.isBlank()) return; - new ChatMessage(Icon.ERROR).appendStatic("Unknown command: ").quote(command).send(sender); + new ChatMessage(Icon.ERROR) + .appendTranslated("common#unknownCommand") + .appendSpace() + .quote(command) + .send(sender); }); } } diff --git a/src/main/java/eu/mhsl/minenet/minigames/command/privileged/FakeplayerCommand.java b/src/main/java/eu/mhsl/minenet/minigames/command/privileged/FakeplayerCommand.java deleted file mode 100644 index 69c31c5..0000000 --- a/src/main/java/eu/mhsl/minenet/minigames/command/privileged/FakeplayerCommand.java +++ /dev/null @@ -1,31 +0,0 @@ -package eu.mhsl.minenet.minigames.command.privileged; - -import eu.mhsl.minenet.minigames.command.PrivilegedCommand; -import eu.mhsl.minenet.minigames.instance.room.Room; -import eu.mhsl.minenet.minigames.message.Icon; -import eu.mhsl.minenet.minigames.message.type.ChatMessage; -import net.minestom.server.command.builder.arguments.ArgumentType; -import net.minestom.server.entity.Player; - -import java.util.UUID; - -public class FakeplayerCommand extends PrivilegedCommand { - public FakeplayerCommand() { - super("fakeplayer"); - - addSyntax((sender, context) -> { - if(sender instanceof Player p) { - if(p.getInstance() instanceof Room room) { -// FakePlayer.initPlayer( // TODO FakePlayer does no longer exists -// UUID.randomUUID(), -// context.getRaw("name"), -// new FakePlayerOption().setInTabList(true).setRegistered(true), -// fakePlayer -> Room.setRoom(fakePlayer, room) -// ); - } else { - new ChatMessage(Icon.ERROR).appendStatic("Du musst dich in einer Raumlobby befinden!").send(sender); - } - } - }, ArgumentType.String("name")); - } -} diff --git a/src/main/java/eu/mhsl/minenet/minigames/command/privileged/SetRoomOwnerCommand.java b/src/main/java/eu/mhsl/minenet/minigames/command/privileged/SetRoomOwnerCommand.java index 6a83853..85cf006 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/command/privileged/SetRoomOwnerCommand.java +++ b/src/main/java/eu/mhsl/minenet/minigames/command/privileged/SetRoomOwnerCommand.java @@ -20,7 +20,7 @@ public class SetRoomOwnerCommand extends PrivilegedCommand { setDefaultExecutor((sender, context) -> { if(sender instanceof Player p) { Room.getRoom(p).orElseThrow().setOwner(p); - new ChatMessage(Icon.SUCCESS).appendStatic("You are now the owner of this room!").send(sender); + new ChatMessage(Icon.SUCCESS).appendTranslated("room#ownerSelf").send(sender); } }); @@ -29,7 +29,7 @@ public class SetRoomOwnerCommand extends PrivilegedCommand { if(sender instanceof Player p) { Player newOwner = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("player")); Room.getRoom(p).orElseThrow().setOwner(Objects.requireNonNull(newOwner)); - new ChatMessage(Icon.SUCCESS).appendStatic("The new owner has been set!").send(sender); + new ChatMessage(Icon.SUCCESS).appendTranslated("room#ownerSet").send(sender); } }, ArgumentType.Entity("player").onlyPlayers(true)); } diff --git a/src/main/java/eu/mhsl/minenet/minigames/handler/Listeners.java b/src/main/java/eu/mhsl/minenet/minigames/handler/Listeners.java index 72b17c0..2794283 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/handler/Listeners.java +++ b/src/main/java/eu/mhsl/minenet/minigames/handler/Listeners.java @@ -7,7 +7,8 @@ import net.minestom.server.event.EventListener; public enum Listeners { SPAWN(new AddEntityToInstanceEventListener()), LOGIN(new PlayerLoginHandler()), - LEAVE(new PlayerLeaveHandler()); + LEAVE(new PlayerLeaveHandler()), + CHAT(new ChatFormatHandler()); Listeners(EventListener event) { MinecraftServer.getGlobalEventHandler().addListener(event); diff --git a/src/main/java/eu/mhsl/minenet/minigames/handler/global/ChatFormatHandler.java b/src/main/java/eu/mhsl/minenet/minigames/handler/global/ChatFormatHandler.java new file mode 100644 index 0000000..f548248 --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/handler/global/ChatFormatHandler.java @@ -0,0 +1,20 @@ +package eu.mhsl.minenet.minigames.handler.global; + +import eu.mhsl.minenet.minigames.message.Icon; +import eu.mhsl.minenet.minigames.message.type.ChatMessage; +import net.minestom.server.event.EventListener; +import net.minestom.server.event.player.PlayerChatEvent; +import org.jetbrains.annotations.NotNull; + +public class ChatFormatHandler implements EventListener { + @Override + public @NotNull Class eventType() { + return PlayerChatEvent.class; + } + + @Override + public @NotNull Result run(@NotNull PlayerChatEvent event) { + event.setFormattedMessage(new ChatMessage(Icon.CHAT).appendStatic(event.getRawMessage()).build(event.getPlayer())); + return Result.SUCCESS; + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLeaveHandler.java b/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLeaveHandler.java index fcfc4bb..afa771e 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLeaveHandler.java +++ b/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLeaveHandler.java @@ -1,5 +1,9 @@ package eu.mhsl.minenet.minigames.handler.global; +import eu.mhsl.minenet.minigames.message.Icon; +import eu.mhsl.minenet.minigames.message.type.ChatMessage; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minestom.server.MinecraftServer; import net.minestom.server.entity.Player; import net.minestom.server.event.EventListener; import net.minestom.server.event.player.PlayerDisconnectEvent; @@ -14,7 +18,11 @@ public class PlayerLeaveHandler implements EventListener @Override public @NotNull Result run(@NotNull PlayerDisconnectEvent event) { Player p = event.getPlayer(); -// new ChatMessage(Icon.SCIENCE).appendStatic("unübersetzter Leavetext: ").appendStatic(p.getDisplayName()).send(MinecraftServer.getConnectionManager().getOnlinePlayers()); + new ChatMessage(Icon.LEAVE) + .appendStatic(p.getName().color(NamedTextColor.GRAY)) + .appendSpace() + .appendTranslated("common#leave", NamedTextColor.DARK_GRAY) + .send(MinecraftServer.getConnectionManager().getOnlinePlayers()); return Result.SUCCESS; } } diff --git a/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLoginHandler.java b/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLoginHandler.java index b694668..fa8144f 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLoginHandler.java +++ b/src/main/java/eu/mhsl/minenet/minigames/handler/global/PlayerLoginHandler.java @@ -65,8 +65,6 @@ public class PlayerLoginHandler implements EventListener> options, Player owner) { try { - - Game game = factory.manufacture(Room.getRoom(owner).orElseThrow(), options); + Room originRoom = Room.getRoom(owner).orElseThrow(); + Game game = factory.manufacture(originRoom, options); game.load(); - Room.getRoom(owner).orElseThrow().moveMembersToInstance(game); - - MinecraftServer.getSchedulerManager().scheduleTask(() -> { - game.getPlayers().forEach(player -> new ChatMessage(Icon.SCIENCE) - .appendStatic(factory.name().getAssembled(player).asComponent()) - .newLine() - .appendStatic(factory.description().getAssembled(player).asComponent()) - .send(player)); - - return TaskSchedule.stop(); - }, TaskSchedule.seconds(3)); + originRoom.moveMembersToInstance(game); + new ChatMessage(Icon.INFO) + .appendTranslated(factory.name()) + .newLine() + .appendTranslated(factory.description()) + .send(originRoom.getAllMembers()); } catch (Exception e) { new ChatMessage(Icon.ERROR).appendStatic("Instance crashed: " + e.getMessage()).send(owner); diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java index e318dd5..36aa3f1 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java @@ -57,7 +57,11 @@ public class StatelessGame extends Game { int timeLeft = timeLimit - timePlayed; switch (timeLeft) { case 90, 60, 30, 10, 5, 4, 3, 2, 1 -> - new ChatMessage(Icon.SCIENCE).appendStatic("Noch " + timeLeft + " Sekunden!").send(getPlayers()); + new ChatMessage(Icon.TIME) + .appendStatic(String.valueOf(timeLeft)) + .appendSpace() + .appendTranslated(timeLeft == 1 ? "common#secondsLeft_singular" : "common#secondsLeft_plural") + .send(getPlayers()); } timePlayed++; @@ -77,13 +81,23 @@ public class StatelessGame extends Game { * When overriding make sure to call this::start after countdown! */ protected CompletableFuture countdownStart() { - return new Countdown(TitleMessage.class) - .countdown(Audience.audience(getPlayers()), 5, countdownModifier -> countdownModifier.message = new TitleMessage(Duration.ofMillis(300), Duration.ofMillis(700)) - .subtitle(subtitleMessage -> subtitleMessage.appendStatic(Component.text("in ", NamedTextColor.DARK_GREEN)) - .appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN)) - .appendStatic(Component.text(" seconds", NamedTextColor.DARK_GREEN)))); - } + Duration fadeIn = Duration.ofMillis(300); + Duration stay = Duration.ofMillis(700); + return new Countdown(TitleMessage.class) + .countdown( + Audience.audience(this.getPlayers()), + 5, + modifier -> modifier.message = new TitleMessage(fadeIn, stay) + .subtitle(subtitleMessage -> subtitleMessage + .appendTranslated("common#startIn", NamedTextColor.DARK_GREEN) + .appendSpace() + .appendStatic(Component.text(modifier.timeLeft, NamedTextColor.GREEN)) + .appendSpace() + .appendTranslated(modifier.timeLeft == 1 ? "common#second" : "common#seconds", NamedTextColor.DARK_GREEN) + ) + ); + } public void startAccessor() { this.start(); diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRace.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRace.java index 9f7a446..c36725a 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRace.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRace.java @@ -20,7 +20,10 @@ import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.EquipmentSlot; import net.minestom.server.entity.GameMode; import net.minestom.server.entity.Player; -import net.minestom.server.event.player.*; +import net.minestom.server.event.player.PlayerMoveEvent; +import net.minestom.server.event.player.PlayerStartFlyingWithElytraEvent; +import net.minestom.server.event.player.PlayerStopFlyingWithElytraEvent; +import net.minestom.server.event.player.PlayerUseItemEvent; import net.minestom.server.instance.batch.AbsoluteBlockBatch; import net.minestom.server.instance.block.Block; import net.minestom.server.item.ItemStack; @@ -49,80 +52,74 @@ public class ElytraRace extends StatelessGame { private final Material resetMaterial = Material.RED_DYE; private final int boostMultiplier = 50; private final Material ringMaterial = Material.GOLD_BLOCK; - private int generatedUntil = 0; - - private record CheckPointData(int currentCheckpoint, int nextCheckpoint) { - public CheckPointData next(int spacing) { - return new CheckPointData(nextCheckpoint, nextCheckpoint + spacing); - } - } private final Map playerCheckpoints = new HashMap<>(); + private int generatedUntil = 0; public ElytraRace(int ringCount) { super(Dimension.OVERWORLD.key, "ElytraRace", new FirstWinsScore()); this.ringCount = ringCount; - setGenerator(vale); - vale.setCalculateSeaLevel(point -> seaLevel); - vale.setXShiftMultiplier(integer -> NumberUtil.map(integer, 50, 500, 0, 1)); - vale.addMixIn(new PlaneTerrainGenerator(gameHeight, Block.BARRIER)); + this.setGenerator(this.vale); + this.vale.setCalculateSeaLevel(point -> this.seaLevel); + this.vale.setXShiftMultiplier(integer -> NumberUtil.map(integer, 50, 500, 0, 1)); + this.vale.addMixIn(new PlaneTerrainGenerator(this.gameHeight, Block.BARRIER)); - eventNode().addListener(PlayerUseItemEvent.class, playerUseItemEvent -> { + this.eventNode().addListener(PlayerUseItemEvent.class, playerUseItemEvent -> { Player player = playerUseItemEvent.getPlayer(); Material usedMaterial = playerUseItemEvent.getItemStack().material(); - if(usedMaterial.equals(boostMaterial)) { - if(!player.isFlyingWithElytra()) return; + if (usedMaterial.equals(this.boostMaterial)) { + if (!player.isFlyingWithElytra()) return; - boost(player); - InventoryUtil.removeItemFromPlayer(player, boostMaterial, 1); - } else if(usedMaterial.equals(resetMaterial)) { - toCheckpoint(player); - InventoryUtil.removeItemFromPlayer(player, resetMaterial, 1); + this.boost(player); + InventoryUtil.removeItemFromPlayer(player, this.boostMaterial, 1); + } else if (usedMaterial.equals(this.resetMaterial)) { + this.toCheckpoint(player); + InventoryUtil.removeItemFromPlayer(player, this.resetMaterial, 1); } }); - eventNode().addListener(PlayerStopFlyingWithElytraEvent.class, playerStopFlyingWithElytraEvent -> { + this.eventNode().addListener(PlayerStopFlyingWithElytraEvent.class, playerStopFlyingWithElytraEvent -> { Player player = playerStopFlyingWithElytraEvent.getPlayer(); - if(Position.blocksBelowPlayer(this, player).contains(ringMaterial.block())) { + if (Position.blocksBelowPlayer(this, player).contains(this.ringMaterial.block())) { player.setFlyingWithElytra(true); - boost(player); + this.boost(player); } else { - toCheckpoint(player); + this.toCheckpoint(player); // getScore().insertResult(playerStopFlyingWithElytraEvent.getPlayer()); // playerStopFlyingWithElytraEvent.getPlayer().setGameMode(GameMode.SPECTATOR); } }); - eventNode().addListener(PlayerStartFlyingWithElytraEvent.class, playerStartFlyingWithElytraEvent -> { - if(!isRunning) { + this.eventNode().addListener(PlayerStartFlyingWithElytraEvent.class, playerStartFlyingWithElytraEvent -> { + if (!this.isRunning) { playerStartFlyingWithElytraEvent.getPlayer().setFlyingWithElytra(false); return; } - boost(playerStartFlyingWithElytraEvent.getPlayer()); + this.boost(playerStartFlyingWithElytraEvent.getPlayer()); }); } @Override protected void onLoad(@NotNull CompletableFuture callback) { - Point spawnpoint = new Pos(vale.getXShiftAtZ(0), -46, 0); - GeneratorUtils.iterateArea(spawnpoint.sub(5, 0, 5), spawnpoint.add(5, 0, 5), point -> setBlock(point, BlockPallet.STREET.rnd())); + Point spawnpoint = new Pos(this.vale.getXShiftAtZ(0), -46, 0); + GeneratorUtils.iterateArea(spawnpoint.sub(5, 0, 5), spawnpoint.add(5, 0, 5), point -> this.setBlock(point, BlockPallet.STREET.rnd())); - generateRing(ringSpacing); - generateRing(ringSpacing * 2); + this.generateRing(this.ringSpacing); + this.generateRing(this.ringSpacing * 2); callback.complete(null); } @Override protected void onStart() { - getPlayers().forEach(player -> { + this.getPlayers().forEach(player -> { player.getInventory().setEquipment(EquipmentSlot.CHESTPLATE, (byte) 0, ItemStack.of(Material.ELYTRA)); - for(int i = 0; i < 3; i++) { - player.getInventory().setItemStack(i, ItemStack.builder(boostMaterial).customName(TranslatedComponent.byId("boost").getAssembled(player)).build()); + for (int i = 0; i < 3; i++) { + player.getInventory().setItemStack(i, ItemStack.builder(this.boostMaterial).customName(TranslatedComponent.byId("boost").getAssembled(player)).build()); } - addResetItemToPlayer(player); + this.addResetItemToPlayer(player); }); } @@ -131,44 +128,44 @@ public class ElytraRace extends StatelessGame { Player player = playerMoveEvent.getPlayer(); Point newPos = playerMoveEvent.getNewPosition(); - if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() < getSpawn().y()) { - player.teleport(getSpawn()); + if (this.isBeforeBeginning && playerMoveEvent.getNewPosition().y() < this.getSpawn().y()) { + player.teleport(this.getSpawn()); return; } - playerCheckpoints.putIfAbsent(player, new CheckPointData(ringSpacing, ringSpacing * 2)); + this.playerCheckpoints.putIfAbsent(player, new CheckPointData(this.ringSpacing, this.ringSpacing * 2)); - if(newPos.z() > generatedUntil - ringSpacing) { - generateRing(generatedUntil + ringSpacing); + if (newPos.z() > this.generatedUntil - this.ringSpacing) { + this.generateRing(this.generatedUntil + this.ringSpacing); } - if(newPos.z() > playerCheckpoints.get(player).nextCheckpoint) { - playerCheckpoints.put(player, playerCheckpoints.get(player).next(ringSpacing)); - boost(player); + if (newPos.z() > this.playerCheckpoints.get(player).nextCheckpoint) { + this.playerCheckpoints.put(player, this.playerCheckpoints.get(player).next(this.ringSpacing)); + this.boost(player); } - if(newPos.y() > gameHeight - 5) { - Point particlePoint = newPos.withY(gameHeight); + if (newPos.y() > this.gameHeight - 5) { + Point particlePoint = newPos.withY(this.gameHeight); ParticlePacket particle = new ParticlePacket( - Particle.WAX_ON, - particlePoint.blockX(), - particlePoint.blockY(), - particlePoint.withZ(z -> z+10).blockZ(), - 20, - 0, - 30, - 1f, - Math.toIntExact((long) NumberUtil.map(newPos.y(), gameHeight - 5, gameHeight, 50, 500)) + Particle.WAX_ON, + particlePoint.blockX(), + particlePoint.blockY(), + particlePoint.withZ(z -> z + 10).blockZ(), + 20, + 0, + 30, + 1f, + Math.toIntExact((long) NumberUtil.map(newPos.y(), this.gameHeight - 5, this.gameHeight, 50, 500)) ); player.sendPacket(particle); } - if(getBlock(player.getPosition()).equals(Block.WATER)) { - toCheckpoint(player); + if (this.getBlock(player.getPosition()).equals(Block.WATER)) { + this.toCheckpoint(player); } - if(newPos.z() > ringCount * ringSpacing) { - getScore().insertResult(player); + if (newPos.z() > this.ringCount * this.ringSpacing) { + this.getScore().insertResult(player); player.setGameMode(GameMode.SPECTATOR); player.setFlyingWithElytra(false); } @@ -176,43 +173,44 @@ public class ElytraRace extends StatelessGame { @Override public Pos getSpawn() { - return new Pos(vale.getXShiftAtZ(0), -45, 0); + return new Pos(this.vale.getXShiftAtZ(0), -45, 0); } private void addResetItemToPlayer(Player p) { - p.getInventory().setItemStack(8, ItemStack.builder(resetMaterial).customName(TranslatedComponent.byId("reset").getAssembled(p)).build()); + p.getInventory().setItemStack(8, ItemStack.builder(this.resetMaterial).customName(TranslatedComponent.byId("reset").getAssembled(p)).build()); } private Point getRingPositionAtZ(int z) { Random random = new Random(this.hashCode() + z); - return new Pos(vale.getXShiftAtZ(z), -45 + random.nextInt(-5, 15), z); + return new Pos(this.vale.getXShiftAtZ(z), -45 + random.nextInt(-5, 15), z); } private CompletableFuture generateRing(int zPos) { - if(zPos > ringCount * ringSpacing) return null; - boolean isLast = (zPos == ringCount * ringSpacing); + if (zPos > this.ringCount * this.ringSpacing) return null; + boolean isLast = (zPos == this.ringCount * this.ringSpacing); - generatedUntil = zPos; + this.generatedUntil = zPos; AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); - Point ringPos = getRingPositionAtZ(zPos); + Point ringPos = this.getRingPositionAtZ(zPos); GeneratorUtils.iterateArea( - ringPos.sub(100, 0, 0).withY(0), - ringPos.add(100, 0, 0).withY(seaLevel), - point -> batch.setBlock(point, Block.BARRIER) + ringPos.sub(100, 0, 0).withY(0), + ringPos.add(100, 0, 0).withY(this.seaLevel), + point -> batch.setBlock(point, Block.BARRIER) ); GeneratorUtils.iterateArea( - ringPos.sub(3, 3, 0), - ringPos.add(3, 3, 0), - point -> batch.setBlock(point, isLast ? Block.DIAMOND_BLOCK : ringMaterial.block()) + ringPos.sub(3, 3, 0), + ringPos.add(3, 3, 0), + point -> batch.setBlock(point, isLast ? Block.DIAMOND_BLOCK : this.ringMaterial.block()) ); GeneratorUtils.iterateArea( - ringPos.sub(2, 2, 0), - ringPos.add(2, 2, 0), - point -> batch.setBlock(point, Block.AIR) + ringPos.sub(2, 2, 0), + ringPos.add(2, 2, 0), + point -> batch.setBlock(point, Block.AIR) ); - BatchUtil.loadAndApplyBatch(batch, this, () -> {}); + BatchUtil.loadAndApplyBatch(batch, this, () -> { + }); return null; } @@ -221,13 +219,13 @@ public class ElytraRace extends StatelessGame { Vec playerVelocity = player.getPosition().direction(); player.setVelocity( - player.getVelocity().add(playerVelocity.mul(boostMultiplier)) - .withY(playerVelocity.withY(v -> v * boostMultiplier).y()) + player.getVelocity().add(playerVelocity.mul(this.boostMultiplier)) + .withY(playerVelocity.withY(v -> v * this.boostMultiplier).y()) ); } private void toCheckpoint(Player p) { - Point checkpointPos = getRingPositionAtZ(playerCheckpoints.get(p).currentCheckpoint); + Point checkpointPos = this.getRingPositionAtZ(this.playerCheckpoints.get(p).currentCheckpoint); p.setVelocity(Vec.ZERO); p.setFlyingWithElytra(false); p.teleport(Pos.fromPoint(checkpointPos).add(0.5, 0, 0.5)); @@ -236,27 +234,35 @@ public class ElytraRace extends StatelessGame { p.setFlyingSpeed(0); new Countdown(TitleMessage.class) - .countdown( - Audience.audience(p), - 3, - countdownModifier -> - countdownModifier.message = new TitleMessage( - Duration.ofMillis(300), - Duration.ofMillis(700) - ) - .subtitle( - subtitleMessage -> - subtitleMessage - .appendStatic(Component.text("Launch in ", NamedTextColor.DARK_GREEN)) - .appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN)) - .appendStatic(Component.text(" seconds", NamedTextColor.DARK_GREEN)) - ) - ).thenRun(() -> { - p.setFlying(false); - p.setFlyingSpeed(1); - p.setFlyingWithElytra(true); - boost(p); - addResetItemToPlayer(p); - }); + .countdown( + Audience.audience(p), + 3, + countdownModifier -> + countdownModifier.message = new TitleMessage( + Duration.ofMillis(300), + Duration.ofMillis(700) + ) + .subtitle( + subtitleMessage -> + subtitleMessage + .appendTranslated("game_ElytraRace#launchIn") + .appendSpace() + .appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN)) + .appendSpace() + .appendTranslated(countdownModifier.timeLeft == 1 ? "common#second" : "common#seconds") + ) + ).thenRun(() -> { + p.setFlying(false); + p.setFlyingSpeed(1); + p.setFlyingWithElytra(true); + this.boost(p); + this.addResetItemToPlayer(p); + }); + } + + private record CheckPointData(int currentCheckpoint, int nextCheckpoint) { + public CheckPointData next(int spacing) { + return new CheckPointData(this.nextCheckpoint, this.nextCheckpoint + spacing); + } } } diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/hub/inventory/JoinInventory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/hub/inventory/JoinInventory.java index 467edcb..4244894 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/hub/inventory/JoinInventory.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/hub/inventory/JoinInventory.java @@ -55,7 +55,11 @@ public class JoinInventory extends InteractableInventory { if(target.isPresent()) Room.setRoom(player, target.get()); else - new ChatMessage(Icon.ERROR).appendTranslated("hub#join_notFound").appendStatic(" " + typedText).send(player); + new ChatMessage(Icon.ERROR) + .appendTranslated("hub#join_notFound") + .appendSpace() + .quote(typedText.trim()) + .send(player); } private String formatInput(String raw) { diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/room/Room.java b/src/main/java/eu/mhsl/minenet/minigames/instance/room/Room.java index 6b525f3..cc2f0df 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/room/Room.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/room/Room.java @@ -135,9 +135,17 @@ public class Room extends MineNetInstance implements Spawnable { Room.unsetRoom(p); - new ChatMessage(Icon.ERROR).appendStatic("The room leader left!").send(this.getAllMembers()); - new ChatMessage(Icon.SCIENCE).appendStatic(this.owner.getUsername()).appendStatic(" is the new Leader!").send(this.getAllMembers().stream().filter(player -> player != this.owner).collect(Collectors.toSet())); - new ChatMessage(Icon.SUCCESS).appendStatic("You are now the leader.").send(this.owner); + new ChatMessage(Icon.ERROR) + .appendTranslated("room#ownerLeft") + .send(this.getAllMembers()); + new ChatMessage(Icon.SCIENCE) + .appendStatic(this.owner.getUsername()) + .appendSpace() + .appendTranslated("room#newOwnerAnnounce") + .send(this.getAllMembers().stream().filter(player -> player != this.owner).collect(Collectors.toSet())); + new ChatMessage(Icon.SUCCESS) + .appendTranslated("room#ownerSelf") + .send(this.owner); }); } diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/room/entity/GameSelector.java b/src/main/java/eu/mhsl/minenet/minigames/instance/room/entity/GameSelector.java index 7603fe7..8ad6ac9 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/room/entity/GameSelector.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/room/entity/GameSelector.java @@ -37,7 +37,9 @@ public class GameSelector extends InteractableEntity { if(playerEntityInteractEvent.getPlayer() != room.getOwner()) { abstractVillagerMeta.setHeadShakeTimer(20); - new ChatMessage(Icon.ERROR).appendStatic("Only the room leader can start games!").send(playerEntityInteractEvent.getPlayer()); + new ChatMessage(Icon.ERROR) + .appendTranslated("room#onlyOwnerCanStart") + .send(playerEntityInteractEvent.getPlayer()); return; } diff --git a/src/main/java/eu/mhsl/minenet/minigames/message/Icon.java b/src/main/java/eu/mhsl/minenet/minigames/message/Icon.java index 35efac2..0879e21 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/message/Icon.java +++ b/src/main/java/eu/mhsl/minenet/minigames/message/Icon.java @@ -8,7 +8,10 @@ public enum Icon { STAR("\u2606", NamedTextColor.GOLD), CHAT("\u276F\u276F", NamedTextColor.WHITE), SUCCESS("\u2714", NamedTextColor.GREEN), - ERROR("\u274C", NamedTextColor.RED); + ERROR("\u274C", NamedTextColor.RED), + TIME("\u231B", NamedTextColor.YELLOW), + INFO("\uD83D\uDD14", NamedTextColor.AQUA), + LEAVE("\u2B05", NamedTextColor.DARK_GRAY); private final String symbol; private final NamedTextColor color; diff --git a/src/main/java/eu/mhsl/minenet/minigames/message/TranslatableMessage.java b/src/main/java/eu/mhsl/minenet/minigames/message/TranslatableMessage.java index 855ee5c..a485896 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/message/TranslatableMessage.java +++ b/src/main/java/eu/mhsl/minenet/minigames/message/TranslatableMessage.java @@ -31,8 +31,23 @@ public abstract class TranslatableMessage implements Sendable { return this; } + public TranslatableMessage appendSpace() { + chain.add(Component.text(" ")); + return this; + } + public TranslatableMessage appendTranslated(String mapId) { - chain.add(TranslatedComponent.byId(mapId)); + chain.add(TranslatedComponent.byId(mapId).setColor(NamedTextColor.WHITE)); + return this; + } + + public TranslatableMessage appendTranslated(String mapId, NamedTextColor color) { + chain.add(TranslatedComponent.byId(mapId).setColor(color)); + return this; + } + + public TranslatableMessage appendTranslated(TranslatedComponent component) { + chain.add(component); return this; } diff --git a/src/main/resources/lang/locales.map.csv b/src/main/resources/lang/locales.map.csv index 5de9337..135c512 100644 --- a/src/main/resources/lang/locales.map.csv +++ b/src/main/resources/lang/locales.map.csv @@ -9,6 +9,13 @@ select_language;Please select your prefered Language;Bitte wähle deine bevorzug welcome;Welcome!;Willkommen! back;Back;Zurück forward;Next;Nächste +leave;left the game;hat das Spiel verlassen +secondsLeft_singular;second left;Sekunde verbleibt +secondsLeft_plural;seconds left;Sekunden verbleiben +unknownCommand;Unknown command;Unbekannter Befehl +startIn;Start in;Startet in +second;second;Sekunde +seconds;seconds;Sekunden ;; ns:tablist#UNUSED;; title;MineNet Network;MineNet Servernetzwerk @@ -65,6 +72,11 @@ ns:room#;; invTitle;Select a Minigame;Wähle einen Spielmodus noOption;No options here;Keine Optionen hier noOptionDescription;There are no options for this Game;Es gibt keine Einstellungen für dieses Spiel +ownerSelf;You are now the owner of this room!;Du bist nun Besitzer dieser Lobby! +ownerSet;The new owner has been set!;Der neue Besitzer wurde festgelegt! +ownerLeft;The room owner has left!;Der Lobbybesitzer hat das Spiel verlassen! +newOwnerAnnounce;is the new owner!;ist der neue Besitzer +onlyOwnerCanStart;Only the room leader can start games!;Nur der Raumbesitzer kann Spiele starten! ;; ns:GameFactory#;; missingDescription;No description;Keine Beschreibung @@ -78,6 +90,7 @@ ns:game_ElytraRace#;; name;Elytra race;Elytra Rennen description;Be fast while flying through the rings;Sei schnell während du durch die Ringe fliegst ringCount;ring count;Anzahl der Ringe +launchIn;Launch in;Abschuss in ;; ns:game_Minerun#;; name;Minerun;Minenrennen