From a1048133d1de753c7088a08481816cad73a7f5ca Mon Sep 17 00:00:00 2001 From: TheMode Date: Wed, 4 Sep 2024 01:49:35 +0200 Subject: [PATCH] GameMode hardcoded abilities (#2366) --- .../net/minestom/server/entity/GameMode.java | 51 ++++++++++--------- .../net/minestom/server/entity/Player.java | 37 ++++---------- .../minestom/server/entity/GameModeTest.java | 16 ++---- 3 files changed, 41 insertions(+), 63 deletions(-) diff --git a/src/main/java/net/minestom/server/entity/GameMode.java b/src/main/java/net/minestom/server/entity/GameMode.java index c72cd4a55..83d473dd4 100644 --- a/src/main/java/net/minestom/server/entity/GameMode.java +++ b/src/main/java/net/minestom/server/entity/GameMode.java @@ -11,49 +11,50 @@ import static net.minestom.server.network.NetworkBuffer.BYTE; * Can be set with {@link Player#setGameMode(GameMode)}. */ public enum GameMode { - SURVIVAL((byte) 0, true), - CREATIVE((byte) 1, false), - ADVENTURE((byte) 2, true), - SPECTATOR((byte) 3, false); + SURVIVAL(false, false, false), + CREATIVE(true, true, true), + ADVENTURE(false, false, false), + SPECTATOR(true, true, false); - private final byte id; - private final boolean canTakeDamage; + private final boolean allowFlying; + private final boolean invulnerable; + private final boolean instantBreak; - GameMode(byte id, boolean canTakeDamage) { - this.id = id; - this.canTakeDamage = canTakeDamage; + GameMode(boolean allowFlying, boolean invulnerable, boolean instantBreak) { + this.allowFlying = allowFlying; + this.invulnerable = invulnerable; + this.instantBreak = instantBreak; } - public byte id() { - return id; + public boolean allowFlying() { + return allowFlying; } public boolean canTakeDamage() { - return canTakeDamage; + return invulnerable; } - public static final NetworkBuffer.Type NETWORK_TYPE = BYTE.transform(GameMode::fromId, gameMode -> gameMode.id); + public boolean instantBreak() { + return instantBreak; + } + + private static final GameMode[] VALUES = values(); + + public static final NetworkBuffer.Type NETWORK_TYPE = BYTE.transform( + id -> VALUES[id], + gameMode -> (byte) gameMode.ordinal() + ); public static final NetworkBuffer.Type OPT_NETWORK_TYPE = new NetworkBuffer.Type<>() { @Override public void write(@NotNull NetworkBuffer buffer, GameMode value) { - buffer.write(BYTE, value != null ? value.id() : -1); + buffer.write(BYTE, value != null ? (byte) value.ordinal() : -1); } @Override public GameMode read(@NotNull NetworkBuffer buffer) { final byte id = buffer.read(BYTE); - return id != -1 ? GameMode.fromId(id) : null; + return id != -1 ? VALUES[id] : null; } }; - - public static @NotNull GameMode fromId(int id) { - return switch (id) { - case 0 -> SURVIVAL; - case 1 -> CREATIVE; - case 2 -> ADVENTURE; - case 3 -> SPECTATOR; - default -> throw new IllegalArgumentException("Unknown game mode id: " + id); - }; - } } diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 2bd770cea..622d499c4 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -1614,36 +1614,21 @@ public class Player extends LivingEntity implements CommandSender, HoverEventSou this.gameMode = gameMode; // Condition to prevent sending the packets before spawning the player if (isActive()) { - sendPacket(new ChangeGameStatePacket(ChangeGameStatePacket.Reason.CHANGE_GAMEMODE, gameMode.id())); + sendPacket(new ChangeGameStatePacket(ChangeGameStatePacket.Reason.CHANGE_GAMEMODE, gameMode.ordinal())); PacketSendingUtils.broadcastPlayPacket(new PlayerInfoUpdatePacket(PlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, infoEntry())); } // The client updates their abilities based on the GameMode as follows - switch (gameMode) { - case CREATIVE -> { - this.allowFlying = true; - this.instantBreak = true; - this.invulnerable = true; - } - case SPECTATOR -> { - this.allowFlying = true; - this.instantBreak = false; - this.invulnerable = true; - if (isActive()) { - refreshFlying(true); - } else { - this.flying = true; - } - } - default -> { - this.allowFlying = false; - this.instantBreak = false; - this.invulnerable = false; - if (isActive()) { - refreshFlying(false); - } else { - this.flying = false; - } + this.allowFlying = gameMode.allowFlying(); + this.instantBreak = gameMode.instantBreak(); + this.invulnerable = gameMode.canTakeDamage(); + // Spectator automatically enables flying + // If new game mode cannot fly, disable it + if (gameMode == GameMode.SPECTATOR || !gameMode.allowFlying()) { + if (isActive()) { + refreshFlying(gameMode.allowFlying()); + } else { + this.flying = gameMode.allowFlying(); } } // Make sure that the player is in the PLAY state and synchronize their flight speed. diff --git a/src/test/java/net/minestom/server/entity/GameModeTest.java b/src/test/java/net/minestom/server/entity/GameModeTest.java index 2d7ea85dd..8e11426c9 100644 --- a/src/test/java/net/minestom/server/entity/GameModeTest.java +++ b/src/test/java/net/minestom/server/entity/GameModeTest.java @@ -8,17 +8,9 @@ public class GameModeTest { @Test public void toId() { - assertEquals(GameMode.SURVIVAL.id(), 0); - assertEquals(GameMode.CREATIVE.id(), 1); - assertEquals(GameMode.ADVENTURE.id(), 2); - assertEquals(GameMode.SPECTATOR.id(), 3); - } - - @Test - public void fromId() { - assertEquals(GameMode.SURVIVAL, GameMode.fromId(0)); - assertEquals(GameMode.CREATIVE, GameMode.fromId(1)); - assertEquals(GameMode.ADVENTURE, GameMode.fromId(2)); - assertEquals(GameMode.SPECTATOR, GameMode.fromId(3)); + assertEquals(GameMode.SURVIVAL.ordinal(), 0); + assertEquals(GameMode.CREATIVE.ordinal(), 1); + assertEquals(GameMode.ADVENTURE.ordinal(), 2); + assertEquals(GameMode.SPECTATOR.ordinal(), 3); } }