added translation to all messages, ChatFormatHandler and new chat icons

This commit is contained in:
2025-10-16 00:24:48 +02:00
parent d083ca3e1a
commit c301e775c9
16 changed files with 225 additions and 166 deletions

View File

@@ -21,7 +21,6 @@ public enum Commands {
ROOM(new RoomCommand()), ROOM(new RoomCommand()),
UPDATE(new RefreshCommandsCommand()), UPDATE(new RefreshCommandsCommand()),
OP(new OpCommand()), OP(new OpCommand()),
FAKEPLAYER(new FakeplayerCommand()),
KICK(new KickCommand()), KICK(new KickCommand()),
SKIN(new SkinCommand()), SKIN(new SkinCommand()),
SETOWNER(new SetRoomOwnerCommand()), SETOWNER(new SetRoomOwnerCommand()),
@@ -41,7 +40,11 @@ public enum Commands {
static { static {
MinecraftServer.getCommandManager().setUnknownCommandCallback((sender, command) -> { MinecraftServer.getCommandManager().setUnknownCommandCallback((sender, command) -> {
if(command.isBlank()) return; 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);
}); });
} }
} }

View File

@@ -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"));
}
}

View File

@@ -20,7 +20,7 @@ public class SetRoomOwnerCommand extends PrivilegedCommand {
setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
if(sender instanceof Player p) { if(sender instanceof Player p) {
Room.getRoom(p).orElseThrow().setOwner(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) { if(sender instanceof Player p) {
Player newOwner = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("player")); Player newOwner = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("player"));
Room.getRoom(p).orElseThrow().setOwner(Objects.requireNonNull(newOwner)); 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)); }, ArgumentType.Entity("player").onlyPlayers(true));
} }

View File

@@ -7,7 +7,8 @@ import net.minestom.server.event.EventListener;
public enum Listeners { public enum Listeners {
SPAWN(new AddEntityToInstanceEventListener()), SPAWN(new AddEntityToInstanceEventListener()),
LOGIN(new PlayerLoginHandler()), LOGIN(new PlayerLoginHandler()),
LEAVE(new PlayerLeaveHandler()); LEAVE(new PlayerLeaveHandler()),
CHAT(new ChatFormatHandler());
Listeners(EventListener<?> event) { Listeners(EventListener<?> event) {
MinecraftServer.getGlobalEventHandler().addListener(event); MinecraftServer.getGlobalEventHandler().addListener(event);

View File

@@ -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<PlayerChatEvent> {
@Override
public @NotNull Class<PlayerChatEvent> 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;
}
}

View File

@@ -1,5 +1,9 @@
package eu.mhsl.minenet.minigames.handler.global; 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.entity.Player;
import net.minestom.server.event.EventListener; import net.minestom.server.event.EventListener;
import net.minestom.server.event.player.PlayerDisconnectEvent; import net.minestom.server.event.player.PlayerDisconnectEvent;
@@ -14,7 +18,11 @@ public class PlayerLeaveHandler implements EventListener<PlayerDisconnectEvent>
@Override @Override
public @NotNull Result run(@NotNull PlayerDisconnectEvent event) { public @NotNull Result run(@NotNull PlayerDisconnectEvent event) {
Player p = event.getPlayer(); 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; return Result.SUCCESS;
} }
} }

View File

@@ -65,8 +65,6 @@ public class PlayerLoginHandler implements EventListener<AsyncPlayerConfiguratio
Logger.getLogger("user").info(p.getUsername() + " joined"); Logger.getLogger("user").info(p.getUsername() + " joined");
// new ChatMessage(Icon.SCIENCE).appendStatic("unübersetzter Jointext: ").appendStatic(p.getUsername()).send(MinecraftServer.getConnectionManager().getOnlinePlayers());
return Result.SUCCESS; return Result.SUCCESS;
} }
} }

View File

@@ -58,21 +58,16 @@ public abstract class Game extends MineNetInstance implements Spawnable {
public static void initialize(GameFactory factory, List<Option<?>> options, Player owner) { public static void initialize(GameFactory factory, List<Option<?>> options, Player owner) {
try { try {
Room originRoom = Room.getRoom(owner).orElseThrow();
Game game = factory.manufacture(Room.getRoom(owner).orElseThrow(), options); Game game = factory.manufacture(originRoom, options);
game.load(); game.load();
Room.getRoom(owner).orElseThrow().moveMembersToInstance(game); originRoom.moveMembersToInstance(game);
MinecraftServer.getSchedulerManager().scheduleTask(() -> { new ChatMessage(Icon.INFO)
game.getPlayers().forEach(player -> new ChatMessage(Icon.SCIENCE) .appendTranslated(factory.name())
.appendStatic(factory.name().getAssembled(player).asComponent())
.newLine() .newLine()
.appendStatic(factory.description().getAssembled(player).asComponent()) .appendTranslated(factory.description())
.send(player)); .send(originRoom.getAllMembers());
return TaskSchedule.stop();
}, TaskSchedule.seconds(3));
} catch (Exception e) { } catch (Exception e) {
new ChatMessage(Icon.ERROR).appendStatic("Instance crashed: " + e.getMessage()).send(owner); new ChatMessage(Icon.ERROR).appendStatic("Instance crashed: " + e.getMessage()).send(owner);

View File

@@ -57,7 +57,11 @@ public class StatelessGame extends Game {
int timeLeft = timeLimit - timePlayed; int timeLeft = timeLimit - timePlayed;
switch (timeLeft) { switch (timeLeft) {
case 90, 60, 30, 10, 5, 4, 3, 2, 1 -> 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++; timePlayed++;
@@ -77,13 +81,23 @@ public class StatelessGame extends Game {
* When overriding make sure to call this::start after countdown! * When overriding make sure to call this::start after countdown!
*/ */
protected CompletableFuture<Void> countdownStart() { protected CompletableFuture<Void> countdownStart() {
return new Countdown(TitleMessage.class) Duration fadeIn = Duration.ofMillis(300);
.countdown(Audience.audience(getPlayers()), 5, countdownModifier -> countdownModifier.message = new TitleMessage(Duration.ofMillis(300), Duration.ofMillis(700)) Duration stay = 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))));
}
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() { public void startAccessor() {
this.start(); this.start();

View File

@@ -20,7 +20,10 @@ import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.EquipmentSlot; import net.minestom.server.entity.EquipmentSlot;
import net.minestom.server.entity.GameMode; import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player; 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.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
@@ -49,80 +52,74 @@ public class ElytraRace extends StatelessGame {
private final Material resetMaterial = Material.RED_DYE; private final Material resetMaterial = Material.RED_DYE;
private final int boostMultiplier = 50; private final int boostMultiplier = 50;
private final Material ringMaterial = Material.GOLD_BLOCK; 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<Player, CheckPointData> playerCheckpoints = new HashMap<>(); private final Map<Player, CheckPointData> playerCheckpoints = new HashMap<>();
private int generatedUntil = 0;
public ElytraRace(int ringCount) { public ElytraRace(int ringCount) {
super(Dimension.OVERWORLD.key, "ElytraRace", new FirstWinsScore()); super(Dimension.OVERWORLD.key, "ElytraRace", new FirstWinsScore());
this.ringCount = ringCount; this.ringCount = ringCount;
setGenerator(vale); this.setGenerator(this.vale);
vale.setCalculateSeaLevel(point -> seaLevel); this.vale.setCalculateSeaLevel(point -> this.seaLevel);
vale.setXShiftMultiplier(integer -> NumberUtil.map(integer, 50, 500, 0, 1)); this.vale.setXShiftMultiplier(integer -> NumberUtil.map(integer, 50, 500, 0, 1));
vale.addMixIn(new PlaneTerrainGenerator(gameHeight, Block.BARRIER)); this.vale.addMixIn(new PlaneTerrainGenerator(this.gameHeight, Block.BARRIER));
eventNode().addListener(PlayerUseItemEvent.class, playerUseItemEvent -> { this.eventNode().addListener(PlayerUseItemEvent.class, playerUseItemEvent -> {
Player player = playerUseItemEvent.getPlayer(); Player player = playerUseItemEvent.getPlayer();
Material usedMaterial = playerUseItemEvent.getItemStack().material(); Material usedMaterial = playerUseItemEvent.getItemStack().material();
if(usedMaterial.equals(boostMaterial)) { if (usedMaterial.equals(this.boostMaterial)) {
if(!player.isFlyingWithElytra()) return; if (!player.isFlyingWithElytra()) return;
boost(player); this.boost(player);
InventoryUtil.removeItemFromPlayer(player, boostMaterial, 1); InventoryUtil.removeItemFromPlayer(player, this.boostMaterial, 1);
} else if(usedMaterial.equals(resetMaterial)) { } else if (usedMaterial.equals(this.resetMaterial)) {
toCheckpoint(player); this.toCheckpoint(player);
InventoryUtil.removeItemFromPlayer(player, resetMaterial, 1); InventoryUtil.removeItemFromPlayer(player, this.resetMaterial, 1);
} }
}); });
eventNode().addListener(PlayerStopFlyingWithElytraEvent.class, playerStopFlyingWithElytraEvent -> { this.eventNode().addListener(PlayerStopFlyingWithElytraEvent.class, playerStopFlyingWithElytraEvent -> {
Player player = playerStopFlyingWithElytraEvent.getPlayer(); Player player = playerStopFlyingWithElytraEvent.getPlayer();
if(Position.blocksBelowPlayer(this, player).contains(ringMaterial.block())) { if (Position.blocksBelowPlayer(this, player).contains(this.ringMaterial.block())) {
player.setFlyingWithElytra(true); player.setFlyingWithElytra(true);
boost(player); this.boost(player);
} else { } else {
toCheckpoint(player); this.toCheckpoint(player);
// getScore().insertResult(playerStopFlyingWithElytraEvent.getPlayer()); // getScore().insertResult(playerStopFlyingWithElytraEvent.getPlayer());
// playerStopFlyingWithElytraEvent.getPlayer().setGameMode(GameMode.SPECTATOR); // playerStopFlyingWithElytraEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
} }
}); });
eventNode().addListener(PlayerStartFlyingWithElytraEvent.class, playerStartFlyingWithElytraEvent -> { this.eventNode().addListener(PlayerStartFlyingWithElytraEvent.class, playerStartFlyingWithElytraEvent -> {
if(!isRunning) { if (!this.isRunning) {
playerStartFlyingWithElytraEvent.getPlayer().setFlyingWithElytra(false); playerStartFlyingWithElytraEvent.getPlayer().setFlyingWithElytra(false);
return; return;
} }
boost(playerStartFlyingWithElytraEvent.getPlayer()); this.boost(playerStartFlyingWithElytraEvent.getPlayer());
}); });
} }
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
Point spawnpoint = new Pos(vale.getXShiftAtZ(0), -46, 0); Point spawnpoint = new Pos(this.vale.getXShiftAtZ(0), -46, 0);
GeneratorUtils.iterateArea(spawnpoint.sub(5, 0, 5), spawnpoint.add(5, 0, 5), point -> setBlock(point, BlockPallet.STREET.rnd())); GeneratorUtils.iterateArea(spawnpoint.sub(5, 0, 5), spawnpoint.add(5, 0, 5), point -> this.setBlock(point, BlockPallet.STREET.rnd()));
generateRing(ringSpacing); this.generateRing(this.ringSpacing);
generateRing(ringSpacing * 2); this.generateRing(this.ringSpacing * 2);
callback.complete(null); callback.complete(null);
} }
@Override @Override
protected void onStart() { protected void onStart() {
getPlayers().forEach(player -> { this.getPlayers().forEach(player -> {
player.getInventory().setEquipment(EquipmentSlot.CHESTPLATE, (byte) 0, ItemStack.of(Material.ELYTRA)); player.getInventory().setEquipment(EquipmentSlot.CHESTPLATE, (byte) 0, ItemStack.of(Material.ELYTRA));
for(int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
player.getInventory().setItemStack(i, ItemStack.builder(boostMaterial).customName(TranslatedComponent.byId("boost").getAssembled(player)).build()); 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(); Player player = playerMoveEvent.getPlayer();
Point newPos = playerMoveEvent.getNewPosition(); Point newPos = playerMoveEvent.getNewPosition();
if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() < getSpawn().y()) { if (this.isBeforeBeginning && playerMoveEvent.getNewPosition().y() < this.getSpawn().y()) {
player.teleport(getSpawn()); player.teleport(this.getSpawn());
return; 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) { if (newPos.z() > this.generatedUntil - this.ringSpacing) {
generateRing(generatedUntil + ringSpacing); this.generateRing(this.generatedUntil + this.ringSpacing);
} }
if(newPos.z() > playerCheckpoints.get(player).nextCheckpoint) { if (newPos.z() > this.playerCheckpoints.get(player).nextCheckpoint) {
playerCheckpoints.put(player, playerCheckpoints.get(player).next(ringSpacing)); this.playerCheckpoints.put(player, this.playerCheckpoints.get(player).next(this.ringSpacing));
boost(player); this.boost(player);
} }
if(newPos.y() > gameHeight - 5) { if (newPos.y() > this.gameHeight - 5) {
Point particlePoint = newPos.withY(gameHeight); Point particlePoint = newPos.withY(this.gameHeight);
ParticlePacket particle = new ParticlePacket( ParticlePacket particle = new ParticlePacket(
Particle.WAX_ON, Particle.WAX_ON,
particlePoint.blockX(), particlePoint.blockX(),
particlePoint.blockY(), particlePoint.blockY(),
particlePoint.withZ(z -> z+10).blockZ(), particlePoint.withZ(z -> z + 10).blockZ(),
20, 20,
0, 0,
30, 30,
1f, 1f,
Math.toIntExact((long) NumberUtil.map(newPos.y(), gameHeight - 5, gameHeight, 50, 500)) Math.toIntExact((long) NumberUtil.map(newPos.y(), this.gameHeight - 5, this.gameHeight, 50, 500))
); );
player.sendPacket(particle); player.sendPacket(particle);
} }
if(getBlock(player.getPosition()).equals(Block.WATER)) { if (this.getBlock(player.getPosition()).equals(Block.WATER)) {
toCheckpoint(player); this.toCheckpoint(player);
} }
if(newPos.z() > ringCount * ringSpacing) { if (newPos.z() > this.ringCount * this.ringSpacing) {
getScore().insertResult(player); this.getScore().insertResult(player);
player.setGameMode(GameMode.SPECTATOR); player.setGameMode(GameMode.SPECTATOR);
player.setFlyingWithElytra(false); player.setFlyingWithElytra(false);
} }
@@ -176,35 +173,35 @@ public class ElytraRace extends StatelessGame {
@Override @Override
public Pos getSpawn() { 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) { 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) { private Point getRingPositionAtZ(int z) {
Random random = new Random(this.hashCode() + 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<Void> generateRing(int zPos) { private CompletableFuture<Void> generateRing(int zPos) {
if(zPos > ringCount * ringSpacing) return null; if (zPos > this.ringCount * this.ringSpacing) return null;
boolean isLast = (zPos == ringCount * ringSpacing); boolean isLast = (zPos == this.ringCount * this.ringSpacing);
generatedUntil = zPos; this.generatedUntil = zPos;
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
Point ringPos = getRingPositionAtZ(zPos); Point ringPos = this.getRingPositionAtZ(zPos);
GeneratorUtils.iterateArea( GeneratorUtils.iterateArea(
ringPos.sub(100, 0, 0).withY(0), ringPos.sub(100, 0, 0).withY(0),
ringPos.add(100, 0, 0).withY(seaLevel), ringPos.add(100, 0, 0).withY(this.seaLevel),
point -> batch.setBlock(point, Block.BARRIER) point -> batch.setBlock(point, Block.BARRIER)
); );
GeneratorUtils.iterateArea( GeneratorUtils.iterateArea(
ringPos.sub(3, 3, 0), ringPos.sub(3, 3, 0),
ringPos.add(3, 3, 0), ringPos.add(3, 3, 0),
point -> batch.setBlock(point, isLast ? Block.DIAMOND_BLOCK : ringMaterial.block()) point -> batch.setBlock(point, isLast ? Block.DIAMOND_BLOCK : this.ringMaterial.block())
); );
GeneratorUtils.iterateArea( GeneratorUtils.iterateArea(
ringPos.sub(2, 2, 0), ringPos.sub(2, 2, 0),
@@ -212,7 +209,8 @@ public class ElytraRace extends StatelessGame {
point -> batch.setBlock(point, Block.AIR) point -> batch.setBlock(point, Block.AIR)
); );
BatchUtil.loadAndApplyBatch(batch, this, () -> {}); BatchUtil.loadAndApplyBatch(batch, this, () -> {
});
return null; return null;
} }
@@ -221,13 +219,13 @@ public class ElytraRace extends StatelessGame {
Vec playerVelocity = player.getPosition().direction(); Vec playerVelocity = player.getPosition().direction();
player.setVelocity( player.setVelocity(
player.getVelocity().add(playerVelocity.mul(boostMultiplier)) player.getVelocity().add(playerVelocity.mul(this.boostMultiplier))
.withY(playerVelocity.withY(v -> v * boostMultiplier).y()) .withY(playerVelocity.withY(v -> v * this.boostMultiplier).y())
); );
} }
private void toCheckpoint(Player p) { 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.setVelocity(Vec.ZERO);
p.setFlyingWithElytra(false); p.setFlyingWithElytra(false);
p.teleport(Pos.fromPoint(checkpointPos).add(0.5, 0, 0.5)); p.teleport(Pos.fromPoint(checkpointPos).add(0.5, 0, 0.5));
@@ -247,16 +245,24 @@ public class ElytraRace extends StatelessGame {
.subtitle( .subtitle(
subtitleMessage -> subtitleMessage ->
subtitleMessage subtitleMessage
.appendStatic(Component.text("Launch in ", NamedTextColor.DARK_GREEN)) .appendTranslated("game_ElytraRace#launchIn")
.appendSpace()
.appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN)) .appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN))
.appendStatic(Component.text(" seconds", NamedTextColor.DARK_GREEN)) .appendSpace()
.appendTranslated(countdownModifier.timeLeft == 1 ? "common#second" : "common#seconds")
) )
).thenRun(() -> { ).thenRun(() -> {
p.setFlying(false); p.setFlying(false);
p.setFlyingSpeed(1); p.setFlyingSpeed(1);
p.setFlyingWithElytra(true); p.setFlyingWithElytra(true);
boost(p); this.boost(p);
addResetItemToPlayer(p); this.addResetItemToPlayer(p);
}); });
} }
private record CheckPointData(int currentCheckpoint, int nextCheckpoint) {
public CheckPointData next(int spacing) {
return new CheckPointData(this.nextCheckpoint, this.nextCheckpoint + spacing);
}
}
} }

View File

@@ -55,7 +55,11 @@ public class JoinInventory extends InteractableInventory {
if(target.isPresent()) if(target.isPresent())
Room.setRoom(player, target.get()); Room.setRoom(player, target.get());
else 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) { private String formatInput(String raw) {

View File

@@ -135,9 +135,17 @@ public class Room extends MineNetInstance implements Spawnable {
Room.unsetRoom(p); Room.unsetRoom(p);
new ChatMessage(Icon.ERROR).appendStatic("The room leader left!").send(this.getAllMembers()); new ChatMessage(Icon.ERROR)
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())); .appendTranslated("room#ownerLeft")
new ChatMessage(Icon.SUCCESS).appendStatic("You are now the leader.").send(this.owner); .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);
}); });
} }

View File

@@ -37,7 +37,9 @@ public class GameSelector extends InteractableEntity {
if(playerEntityInteractEvent.getPlayer() != room.getOwner()) { if(playerEntityInteractEvent.getPlayer() != room.getOwner()) {
abstractVillagerMeta.setHeadShakeTimer(20); 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; return;
} }

View File

@@ -8,7 +8,10 @@ public enum Icon {
STAR("\u2606", NamedTextColor.GOLD), STAR("\u2606", NamedTextColor.GOLD),
CHAT("\u276F\u276F", NamedTextColor.WHITE), CHAT("\u276F\u276F", NamedTextColor.WHITE),
SUCCESS("\u2714", NamedTextColor.GREEN), 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 String symbol;
private final NamedTextColor color; private final NamedTextColor color;

View File

@@ -31,8 +31,23 @@ public abstract class TranslatableMessage implements Sendable {
return this; return this;
} }
public TranslatableMessage appendSpace() {
chain.add(Component.text(" "));
return this;
}
public TranslatableMessage appendTranslated(String mapId) { 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; return this;
} }

View File

@@ -9,6 +9,13 @@ select_language;Please select your prefered Language;Bitte wähle deine bevorzug
welcome;Welcome!;Willkommen! welcome;Welcome!;Willkommen!
back;Back;Zurück back;Back;Zurück
forward;Next;Nächste 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;; ns:tablist#UNUSED;;
title;MineNet Network;MineNet Servernetzwerk title;MineNet Network;MineNet Servernetzwerk
@@ -65,6 +72,11 @@ ns:room#;;
invTitle;Select a Minigame;Wähle einen Spielmodus invTitle;Select a Minigame;Wähle einen Spielmodus
noOption;No options here;Keine Optionen hier noOption;No options here;Keine Optionen hier
noOptionDescription;There are no options for this Game;Es gibt keine Einstellungen für dieses Spiel 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#;; ns:GameFactory#;;
missingDescription;No description;Keine Beschreibung missingDescription;No description;Keine Beschreibung
@@ -78,6 +90,7 @@ ns:game_ElytraRace#;;
name;Elytra race;Elytra Rennen name;Elytra race;Elytra Rennen
description;Be fast while flying through the rings;Sei schnell während du durch die Ringe fliegst description;Be fast while flying through the rings;Sei schnell während du durch die Ringe fliegst
ringCount;ring count;Anzahl der Ringe ringCount;ring count;Anzahl der Ringe
launchIn;Launch in;Abschuss in
;; ;;
ns:game_Minerun#;; ns:game_Minerun#;;
name;Minerun;Minenrennen name;Minerun;Minenrennen
1 map en_us de_de
9 welcome Welcome! Willkommen!
10 back Back Zurück
11 forward Next Nächste
12 leave left the game hat das Spiel verlassen
13 secondsLeft_singular second left Sekunde verbleibt
14 secondsLeft_plural seconds left Sekunden verbleiben
15 unknownCommand Unknown command Unbekannter Befehl
16 startIn Start in Startet in
17 second second Sekunde
18 seconds seconds Sekunden
19
20 ns:tablist#UNUSED
21 title MineNet Network MineNet Servernetzwerk
72 invTitle Select a Minigame Wähle einen Spielmodus
73 noOption No options here Keine Optionen hier
74 noOptionDescription There are no options for this Game Es gibt keine Einstellungen für dieses Spiel
75 ownerSelf You are now the owner of this room! Du bist nun Besitzer dieser Lobby!
76 ownerSet The new owner has been set! Der neue Besitzer wurde festgelegt!
77 ownerLeft The room owner has left! Der Lobbybesitzer hat das Spiel verlassen!
78 newOwnerAnnounce is the new owner! ist der neue Besitzer
79 onlyOwnerCanStart Only the room leader can start games! Nur der Raumbesitzer kann Spiele starten!
80
81 ns:GameFactory#
82 missingDescription No description Keine Beschreibung
90 name Elytra race Elytra Rennen
91 description Be fast while flying through the rings Sei schnell während du durch die Ringe fliegst
92 ringCount ring count Anzahl der Ringe
93 launchIn Launch in Abschuss in
94
95 ns:game_Minerun#
96 name Minerun Minenrennen