diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index 67fc95b9d40..fc602641e78 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -52,6 +52,7 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerEggThrowEvent; import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerLoginEvent; @@ -1059,6 +1060,27 @@ public void onPlayerFishEvent(final PlayerFishEvent event) { user.updateActivityOnInteract(true); } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerGameModeChange(final PlayerGameModeChangeEvent event) { + if (!ess.getSettings().isGamemodeChangePreserveFlying()) { + return; + } + + final User user = ess.getUser(event.getPlayer()); + if (!user.isAuthorized("essentials.fly")) { + return; + } + + final Player player = event.getPlayer(); + if (player.isFlying() && player.getAllowFlight() && user.isAuthorized("essentials.fly")) { + // The gamemode change happens after the event, so we need to delay the flight enable + ess.scheduleSyncDelayedTask(() -> { + player.setAllowFlight(true); + player.setFlying(true); + }, 1); + } + } + private static final class ArrowPickupListener implements Listener { @EventHandler(priority = EventPriority.LOW) public void onArrowPickup(final org.bukkit.event.player.PlayerPickupArrowEvent event) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java index 77b8f1151e9..d5ca80bc429 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java @@ -356,6 +356,8 @@ public interface ISettings extends IConf { boolean isWorldChangePreserveFlying(); + boolean isGamemodeChangePreserveFlying(); + boolean isWorldChangeSpeedResetEnabled(); long getCommandCooldownMs(String label); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Settings.java b/Essentials/src/main/java/com/earth2me/essentials/Settings.java index 4cda6a58bc3..daa7a3595a5 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Settings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Settings.java @@ -1964,6 +1964,11 @@ public boolean isWorldChangePreserveFlying() { return config.getBoolean("world-change-preserve-flying", true); } + @Override + public boolean isGamemodeChangePreserveFlying() { + return config.getBoolean("gamemode-change-preserve-flying", false); + } + @Override public boolean isWorldChangeSpeedResetEnabled() { return config.getBoolean("world-change-speed-reset", true); diff --git a/Essentials/src/main/resources/config.yml b/Essentials/src/main/resources/config.yml index 360df648908..02f1c2c3f95 100644 --- a/Essentials/src/main/resources/config.yml +++ b/Essentials/src/main/resources/config.yml @@ -235,6 +235,11 @@ world-change-fly-reset: true # This will only work if the player has the 'essentials.fly' permission. world-change-preserve-flying: true +# Should Essentials preserve a player's flight status when they change game modes? +# When enabled, if a player is flying when switching game modes, their flight will be maintained. +# This will only work if the player has the 'essentials.fly' permission. +gamemode-change-preserve-flying: false + # When a player changes worlds, should Essentials reset their speed according to their permissions? # This resets the player's speed to the default if they don't have 'essentials.speed'. # If the player doesn't have 'essentials.speed.bypass', their speed will be reset to the maximum values