mirror of
https://github.com/SunNetservers/MiniGames.git
synced 2024-12-05 00:43:15 +01:00
Fixes various smaller issues
Fixes players immediately being thrown out because the spawn teleportation triggered the PlayerLeaveListener Reduces default velocity from the insane terminal velocity to just 1 Uses UUID instead of player object when storing dropper arena sessions Prevents players from joining an arena if in creative, spectator mode, or is flying Implements the leave command to allow leaving the arena Only counts fall damage as a loss, but still prevents all damage in the arena Prevents players from dying of fall damage when exiting the dropper arena Prevents loadArenas from returning null
This commit is contained in:
parent
b840a3f500
commit
eb67705300
@ -1,46 +1,46 @@
|
||||
package net.knarcraft.dropper.arena;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A registry to keep track of which players are playing in which arenas
|
||||
*/
|
||||
public class DropperArenaPlayerRegistry {
|
||||
|
||||
private final Map<Player, DropperArenaSession> arenaPlayers = new HashMap<>();
|
||||
private final Map<UUID, DropperArenaSession> arenaPlayers = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Registers that the given player has started playing the given dropper arena session
|
||||
*
|
||||
* @param player <p>The player that started playing</p>
|
||||
* @param arena <p>The arena session to register</p>
|
||||
* @param playerId <p>The id of the player that started playing</p>
|
||||
* @param arena <p>The arena session to register</p>
|
||||
*/
|
||||
public void registerPlayer(@NotNull Player player, @NotNull DropperArenaSession arena) {
|
||||
this.arenaPlayers.put(player, arena);
|
||||
public void registerPlayer(@NotNull UUID playerId, @NotNull DropperArenaSession arena) {
|
||||
this.arenaPlayers.put(playerId, arena);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes this player from players currently playing
|
||||
*
|
||||
* @param player <p>The player to remove</p>
|
||||
* @param playerId <p>The id of the player to remove</p>
|
||||
*/
|
||||
public boolean removePlayer(@NotNull Player player) {
|
||||
return this.arenaPlayers.remove(player) != null;
|
||||
public boolean removePlayer(@NotNull UUID playerId) {
|
||||
return this.arenaPlayers.remove(playerId) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player's active dropper arena session
|
||||
*
|
||||
* @param player <p>The player to get arena for</p>
|
||||
* @param playerId <p>The id of the player to get arena for</p>
|
||||
* @return <p>The player's active arena session, or null if not currently playing</p>
|
||||
*/
|
||||
public @Nullable DropperArenaSession getArenaSession(@NotNull Player player) {
|
||||
return this.arenaPlayers.getOrDefault(player, null);
|
||||
public @Nullable DropperArenaSession getArenaSession(@NotNull UUID playerId) {
|
||||
return this.arenaPlayers.getOrDefault(playerId, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,6 +65,8 @@ public class DropperArenaSession {
|
||||
}
|
||||
}
|
||||
|
||||
player.sendMessage("You won!");
|
||||
|
||||
// Teleport the player out of the arena
|
||||
teleportToExit();
|
||||
}
|
||||
@ -88,7 +90,7 @@ public class DropperArenaSession {
|
||||
*/
|
||||
private void removeSession() {
|
||||
// Remove this session for game sessions to stop listeners from fiddling more with the player
|
||||
boolean removedSession = Dropper.getInstance().getPlayerRegistry().removePlayer(player);
|
||||
boolean removedSession = Dropper.getInstance().getPlayerRegistry().removePlayer(player.getUniqueId());
|
||||
if (!removedSession) {
|
||||
Dropper.getInstance().getLogger().log(Level.SEVERE, "Unable to remove dropper arena session for " +
|
||||
player.getName() + ". This will have unintended consequences.");
|
||||
@ -134,6 +136,8 @@ public class DropperArenaSession {
|
||||
player.setAllowFlight(false);
|
||||
// Teleport the player out of the arena
|
||||
teleportToExit();
|
||||
|
||||
player.sendMessage("You quit the arena!");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,7 @@ import net.knarcraft.dropper.arena.DropperArenaSession;
|
||||
import net.knarcraft.dropper.property.ArenaGameMode;
|
||||
import net.knarcraft.dropper.util.ArenaStorageHelper;
|
||||
import net.knarcraft.dropper.util.PlayerTeleporter;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -30,8 +31,14 @@ public class JoinArenaCommand implements CommandExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player.isFlying() || player.getGameMode() == GameMode.CREATIVE ||
|
||||
player.getGameMode() == GameMode.SPECTATOR) {
|
||||
commandSender.sendMessage("You cannot join a dropper arena while able to fly!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disallow joining if the player is already in a dropper arena
|
||||
DropperArenaSession existingSession = Dropper.getInstance().getPlayerRegistry().getArenaSession(player);
|
||||
DropperArenaSession existingSession = Dropper.getInstance().getPlayerRegistry().getArenaSession(player.getUniqueId());
|
||||
if (existingSession != null) {
|
||||
commandSender.sendMessage("You are already in a dropper arena!");
|
||||
return false;
|
||||
@ -64,7 +71,7 @@ public class JoinArenaCommand implements CommandExecutor {
|
||||
// Register the player's session
|
||||
DropperArenaSession newSession = new DropperArenaSession(specifiedArena, player, gameMode);
|
||||
DropperArenaPlayerRegistry playerRegistry = Dropper.getInstance().getPlayerRegistry();
|
||||
playerRegistry.registerPlayer(player, newSession);
|
||||
playerRegistry.registerPlayer(player.getUniqueId(), newSession);
|
||||
|
||||
// Try to teleport the player to the arena
|
||||
boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false);
|
||||
|
@ -1,8 +1,11 @@
|
||||
package net.knarcraft.dropper.command;
|
||||
|
||||
import net.knarcraft.dropper.Dropper;
|
||||
import net.knarcraft.dropper.arena.DropperArenaSession;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@ -13,10 +16,19 @@ public class LeaveArenaCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] strings) {
|
||||
//TODO: Make sure the console cannot run this
|
||||
//TODO: If the player isn't currently in an arena, just display an error message
|
||||
//TODO: Trigger the player's session's triggerQuit() method
|
||||
return false;
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendMessage("This command must be used by a player");
|
||||
return false;
|
||||
}
|
||||
|
||||
DropperArenaSession existingSession = Dropper.getInstance().getPlayerRegistry().getArenaSession(player.getUniqueId());
|
||||
if (existingSession == null) {
|
||||
commandSender.sendMessage("You are not in a dropper arena!");
|
||||
return false;
|
||||
}
|
||||
|
||||
existingSession.triggerQuit();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,14 +23,17 @@ public class DamageListener implements Listener {
|
||||
Player player = (Player) event.getEntity();
|
||||
|
||||
// We don't care about damage outside arenas
|
||||
DropperArenaSession arenaSession = Dropper.getInstance().getPlayerRegistry().getArenaSession(player);
|
||||
DropperArenaSession arenaSession = Dropper.getInstance().getPlayerRegistry().getArenaSession(player.getUniqueId());
|
||||
if (arenaSession == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
arenaSession.triggerLoss();
|
||||
// Only trigger a loss when a player suffers fall damage
|
||||
if (event.getCause() == EntityDamageEvent.DamageCause.FALL) {
|
||||
arenaSession.triggerLoss();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,16 +17,11 @@ import org.bukkit.util.Vector;
|
||||
*/
|
||||
public class MoveListener implements Listener {
|
||||
|
||||
/**
|
||||
* The terminal velocity of a falling player, as defined by the WIKI
|
||||
*/
|
||||
private static final double TERMINAL_VELOCITY = 78.4;
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
DropperArenaPlayerRegistry playerRegistry = Dropper.getInstance().getPlayerRegistry();
|
||||
DropperArenaSession arenaSession = playerRegistry.getArenaSession(player);
|
||||
DropperArenaSession arenaSession = playerRegistry.getArenaSession(player.getUniqueId());
|
||||
if (arenaSession == null) {
|
||||
return;
|
||||
}
|
||||
@ -63,8 +58,7 @@ public class MoveListener implements Listener {
|
||||
Player player = session.getPlayer();
|
||||
Vector playerVelocity = player.getVelocity();
|
||||
double arenaVelocity = session.getArena().getPlayerVelocity();
|
||||
double yVelocity = TERMINAL_VELOCITY * arenaVelocity;
|
||||
Vector newVelocity = new Vector(playerVelocity.getX(), yVelocity, playerVelocity.getZ());
|
||||
Vector newVelocity = new Vector(playerVelocity.getX(), -arenaVelocity, playerVelocity.getZ());
|
||||
player.setVelocity(newVelocity);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A listener for players leaving the server or the arena
|
||||
@ -20,6 +22,15 @@ public class PlayerLeaveListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
DropperArenaSession arenaSession = getSession(event.getPlayer());
|
||||
if (arenaSession == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getTo().equals(arenaSession.getArena().getSpawnLocation())) {
|
||||
return;
|
||||
}
|
||||
|
||||
triggerQuit(event.getPlayer());
|
||||
}
|
||||
|
||||
@ -29,15 +40,25 @@ public class PlayerLeaveListener implements Listener {
|
||||
* @param player <p>The player to trigger a quit for</p>
|
||||
*/
|
||||
private void triggerQuit(Player player) {
|
||||
DropperArenaSession arenaSession = Dropper.getInstance().getPlayerRegistry().getArenaSession(player);
|
||||
DropperArenaSession arenaSession = getSession(player);
|
||||
if (arenaSession == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
arenaSession.triggerQuit();
|
||||
|
||||
//TODO: It might not be possible to alter the player's location here. It might be necessary to move them once
|
||||
//TODO: It might not be possible to alter a leaving player's location here. It might be necessary to move them once
|
||||
// they join again
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the arena session for the given player
|
||||
*
|
||||
* @param player <p>The player to get the arena session for</p>
|
||||
* @return <p>The player's session, or null if not in a session</p>
|
||||
*/
|
||||
private @Nullable DropperArenaSession getSession(@NotNull Player player) {
|
||||
return Dropper.getInstance().getPlayerRegistry().getArenaSession(player.getUniqueId());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,12 +58,12 @@ public final class ArenaStorageHelper {
|
||||
* @param arenaFile <p>The file used to store the arenas</p>
|
||||
* @return <p>The loaded arenas, or null if the arenas configuration section is missing.</p>
|
||||
*/
|
||||
public static @Nullable List<DropperArena> loadArenas(@NotNull File arenaFile) {
|
||||
public static @NotNull List<DropperArena> loadArenas(@NotNull File arenaFile) {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(arenaFile);
|
||||
ConfigurationSection arenaSection = configuration.getConfigurationSection(arenasConfigurationSection);
|
||||
//If no such section exists, it must be the case that there is no data to load
|
||||
if (arenaSection == null) {
|
||||
return null;
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<DropperArena> loadedArenas = new ArrayList<>();
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.knarcraft.dropper.util;
|
||||
|
||||
import net.knarcraft.dropper.Dropper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -46,9 +48,14 @@ public final class PlayerTeleporter {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//Stop the player velocity to prevent unevenness between players
|
||||
//Stop the existing player velocity to prevent unevenness between players
|
||||
player.setVelocity(new Vector(0, 0, 0));
|
||||
player.setInvulnerable(true);
|
||||
player.teleport(location);
|
||||
player.setVelocity(new Vector(0, 0, 0));
|
||||
//When teleporting a player out of the arena, sometimes the move listener is slow to react, giving the player
|
||||
// lethal velocity, and causing damage. That's why the player is given 5 ticks of invulnerability
|
||||
Bukkit.getScheduler().runTaskLater(Dropper.getInstance(), () -> player.setInvulnerable(false), 5);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user