GameMode hardcoded abilities (#2366)

This commit is contained in:
TheMode 2024-09-04 01:49:35 +02:00 committed by Matt Worzala
parent 5ccd0f0789
commit a1048133d1
3 changed files with 41 additions and 63 deletions

View File

@ -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<GameMode> 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<GameMode> NETWORK_TYPE = BYTE.transform(
id -> VALUES[id],
gameMode -> (byte) gameMode.ordinal()
);
public static final NetworkBuffer.Type<GameMode> 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);
};
}
}

View File

@ -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.

View File

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