Re-implements the collision removal to fix a severe bug

This commit is contained in:
Kristian Knarvik 2023-05-12 14:31:30 +02:00
parent de5124c8dd
commit 38839c0287
5 changed files with 49 additions and 21 deletions

View File

@ -16,6 +16,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
@ -32,6 +33,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
private final boolean originalAllowFlight; private final boolean originalAllowFlight;
private final boolean originalInvulnerable; private final boolean originalInvulnerable;
private final boolean originalIsSwimming; private final boolean originalIsSwimming;
private final boolean originalCollideAble;
/** /**
* Instantiates a new abstract player entry state * Instantiates a new abstract player entry state
@ -46,6 +48,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
this.originalAllowFlight = player.getAllowFlight(); this.originalAllowFlight = player.getAllowFlight();
this.originalInvulnerable = player.isInvulnerable(); this.originalInvulnerable = player.isInvulnerable();
this.originalIsSwimming = player.isSwimming(); this.originalIsSwimming = player.isSwimming();
this.originalCollideAble = player.isCollidable();
} }
/** /**
@ -58,10 +61,12 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
* @param originalAllowFlight <p>Whether the player was allowed flight before entering the arena</p> * @param originalAllowFlight <p>Whether the player was allowed flight before entering the arena</p>
* @param originalInvulnerable <p>Whether the player was invulnerable before entering the arena</p> * @param originalInvulnerable <p>Whether the player was invulnerable before entering the arena</p>
* @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p> * @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p>
* @param originalCollideAble <p>Whether the player was collide-able before entering the arena</p>
*/ */
public AbstractPlayerEntryState(@NotNull UUID playerId, Location entryLocation, public AbstractPlayerEntryState(@NotNull UUID playerId, Location entryLocation,
boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight, boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight,
boolean originalInvulnerable, boolean originalIsSwimming) { boolean originalInvulnerable, boolean originalIsSwimming,
boolean originalCollideAble) {
this.playerId = playerId; this.playerId = playerId;
this.entryLocation = entryLocation; this.entryLocation = entryLocation;
this.originalIsFlying = originalIsFlying; this.originalIsFlying = originalIsFlying;
@ -69,6 +74,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
this.originalAllowFlight = originalAllowFlight; this.originalAllowFlight = originalAllowFlight;
this.originalInvulnerable = originalInvulnerable; this.originalInvulnerable = originalInvulnerable;
this.originalIsSwimming = originalIsSwimming; this.originalIsSwimming = originalIsSwimming;
this.originalCollideAble = originalCollideAble;
} }
@Override @Override
@ -88,6 +94,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
@Override @Override
public void restore(@NotNull Player player) { public void restore(@NotNull Player player) {
player.setCollidable(this.originalCollideAble);
player.setAllowFlight(this.originalAllowFlight); player.setAllowFlight(this.originalAllowFlight);
player.setFlying(player.getAllowFlight() && this.originalIsFlying); player.setFlying(player.getAllowFlight() && this.originalIsFlying);
player.setGameMode(this.originalGameMode); player.setGameMode(this.originalGameMode);
@ -126,6 +133,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
data.put("originalAllowFlight", this.originalAllowFlight); data.put("originalAllowFlight", this.originalAllowFlight);
data.put("originalInvulnerable", this.originalInvulnerable); data.put("originalInvulnerable", this.originalInvulnerable);
data.put("originalIsSwimming", this.originalIsSwimming); data.put("originalIsSwimming", this.originalIsSwimming);
data.put("originalCollideAble", this.originalCollideAble);
return data; return data;
} }
@ -155,4 +163,16 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
} }
} }
/**
* Gets a boolean value from a serialization map
*
* @param data <p>The serialization data to look through</p>
* @param key <p>The key to get</p>
* @return <p>The boolean value of the key</p>
*/
protected static boolean getBoolean(Map<String, Object> data, String key) {
Boolean value = (Boolean) data.get(key);
return Objects.requireNonNullElse(value, false);
}
} }

View File

@ -44,14 +44,15 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState {
* @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p> * @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p>
* @param originalFlySpeed <p>The fly-speed of the player before entering the arena</p> * @param originalFlySpeed <p>The fly-speed of the player before entering the arena</p>
* @param horizontalVelocity <p>The horizontal velocity of the player before entering the arena</p> * @param horizontalVelocity <p>The horizontal velocity of the player before entering the arena</p>
* @param originalCollideAble <p>Whether the player was collide-able before entering the arena</p>
*/ */
public DropperPlayerEntryState(@NotNull UUID playerId, Location entryLocation, public DropperPlayerEntryState(@NotNull UUID playerId, Location entryLocation,
boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight, boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight,
boolean originalInvulnerable, boolean originalIsSwimming, boolean originalInvulnerable, boolean originalIsSwimming,
float originalFlySpeed, float horizontalVelocity, float originalFlySpeed, float horizontalVelocity,
DropperArenaGameMode arenaGameMode) { DropperArenaGameMode arenaGameMode, boolean originalCollideAble) {
super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight, super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight,
originalInvulnerable, originalIsSwimming); originalInvulnerable, originalIsSwimming, originalCollideAble);
this.originalFlySpeed = originalFlySpeed; this.originalFlySpeed = originalFlySpeed;
this.horizontalVelocity = horizontalVelocity; this.horizontalVelocity = horizontalVelocity;
this.arenaGameMode = arenaGameMode; this.arenaGameMode = arenaGameMode;
@ -111,18 +112,19 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState {
public static DropperPlayerEntryState deserialize(Map<String, Object> data) { public static DropperPlayerEntryState deserialize(Map<String, Object> data) {
UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue(); UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue();
Location entryLocation = (Location) data.get("entryLocation"); Location entryLocation = (Location) data.get("entryLocation");
boolean originalIsFlying = (boolean) data.get("originalIsFlying"); boolean originalIsFlying = getBoolean(data, "originalIsFlying");
GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode")); GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode"));
boolean originalAllowFlight = (boolean) data.get("originalAllowFlight"); boolean originalAllowFlight = getBoolean(data, "originalAllowFlight");
boolean originalInvulnerable = (boolean) data.get("originalInvulnerable"); boolean originalInvulnerable = getBoolean(data, "originalInvulnerable");
boolean originalIsSwimming = (boolean) data.get("originalIsSwimming"); boolean originalIsSwimming = getBoolean(data, "originalIsSwimming");
float originalFlySpeed = ((Number) data.get("originalFlySpeed")).floatValue(); float originalFlySpeed = ((Number) data.get("originalFlySpeed")).floatValue();
float horizontalVelocity = ((Number) data.get("horizontalVelocity")).floatValue(); float horizontalVelocity = ((Number) data.get("horizontalVelocity")).floatValue();
DropperArenaGameMode arenaGameMode = (DropperArenaGameMode) data.get("arenaGameMode"); DropperArenaGameMode arenaGameMode = (DropperArenaGameMode) data.get("arenaGameMode");
boolean originalCollideAble = getBoolean(data, "originalCollideAble");
return new DropperPlayerEntryState(playerId, entryLocation, originalIsFlying, return new DropperPlayerEntryState(playerId, entryLocation, originalIsFlying,
originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming,
originalFlySpeed, horizontalVelocity, arenaGameMode); originalFlySpeed, horizontalVelocity, arenaGameMode, originalCollideAble);
} }
} }

View File

@ -34,12 +34,13 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState {
* @param originalAllowFlight <p>Whether the player was allowed flight before entering the arena</p> * @param originalAllowFlight <p>Whether the player was allowed flight before entering the arena</p>
* @param originalInvulnerable <p>Whether the player was invulnerable before entering the arena</p> * @param originalInvulnerable <p>Whether the player was invulnerable before entering the arena</p>
* @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p> * @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p>
* @param originalCollideAble <p>Whether the player was collide-able before entering the arena</p>
*/ */
public ParkourPlayerEntryState(@NotNull UUID playerId, Location entryLocation, public ParkourPlayerEntryState(@NotNull UUID playerId, Location entryLocation,
boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight, boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight,
boolean originalInvulnerable, boolean originalIsSwimming) { boolean originalInvulnerable, boolean originalIsSwimming, boolean originalCollideAble) {
super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight, super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight,
originalInvulnerable, originalIsSwimming); originalInvulnerable, originalIsSwimming, originalCollideAble);
} }
@Override @Override
@ -63,14 +64,15 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState {
public static ParkourPlayerEntryState deserialize(Map<String, Object> data) { public static ParkourPlayerEntryState deserialize(Map<String, Object> data) {
UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue(); UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue();
Location entryLocation = (Location) data.get("entryLocation"); Location entryLocation = (Location) data.get("entryLocation");
boolean originalIsFlying = (boolean) data.get("originalIsFlying"); boolean originalIsFlying = getBoolean(data, "originalIsFlying");
GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode")); GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode"));
boolean originalAllowFlight = (boolean) data.get("originalAllowFlight"); boolean originalAllowFlight = getBoolean(data, "originalAllowFlight");
boolean originalInvulnerable = (boolean) data.get("originalInvulnerable"); boolean originalInvulnerable = getBoolean(data, "originalInvulnerable");
boolean originalIsSwimming = (boolean) data.get("originalIsSwimming"); boolean originalIsSwimming = getBoolean(data, "originalIsSwimming");
boolean originalCollideAble = getBoolean(data, "originalCollideAble");
return new ParkourPlayerEntryState(playerId, entryLocation, originalIsFlying, return new ParkourPlayerEntryState(playerId, entryLocation, originalIsFlying,
originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming); originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, originalCollideAble);
} }
} }

View File

@ -91,6 +91,9 @@ public class JoinDropperArenaCommand implements CommandExecutor {
ArenaPlayerRegistry<DropperArena> playerRegistry = MiniGames.getInstance().getDropperArenaPlayerRegistry(); ArenaPlayerRegistry<DropperArena> playerRegistry = MiniGames.getInstance().getDropperArenaPlayerRegistry();
playerRegistry.registerPlayer(player.getUniqueId(), newSession); playerRegistry.registerPlayer(player.getUniqueId(), newSession);
// Update visibility and hit-box for the player
MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player);
// Try to teleport the player to the arena // Try to teleport the player to the arena
boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false); boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false);
if (!teleported) { if (!teleported) {
@ -98,10 +101,9 @@ public class JoinDropperArenaCommand implements CommandExecutor {
newSession.triggerQuit(false, true); newSession.triggerQuit(false, true);
return false; return false;
} else { } else {
// Make sure to update the state again in the air to remove a potential swimming state // Update the player's state to follow the arena's rules
newSession.getEntryState().setArenaState(); newSession.getEntryState().setArenaState();
// Update visibility for the player
MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player);
player.getInventory().addItem(GUIHelper.getGUIOpenItem()); player.getInventory().addItem(GUIHelper.getGUIOpenItem());
player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage()); player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage());
return true; return true;

View File

@ -89,6 +89,9 @@ public class JoinParkourArenaCommand implements CommandExecutor {
ArenaPlayerRegistry<ParkourArena> playerRegistry = MiniGames.getInstance().getParkourArenaPlayerRegistry(); ArenaPlayerRegistry<ParkourArena> playerRegistry = MiniGames.getInstance().getParkourArenaPlayerRegistry();
playerRegistry.registerPlayer(player.getUniqueId(), newSession); playerRegistry.registerPlayer(player.getUniqueId(), newSession);
// Update visibility and hit-box for the player
MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player);
// Try to teleport the player to the arena // Try to teleport the player to the arena
boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false); boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false);
if (!teleported) { if (!teleported) {
@ -96,10 +99,9 @@ public class JoinParkourArenaCommand implements CommandExecutor {
newSession.triggerQuit(false, true); newSession.triggerQuit(false, true);
return false; return false;
} else { } else {
// Make sure to update the state again in the air to remove a potential swimming state // Update the player's state to follow the arena's rules
newSession.getEntryState().setArenaState(); newSession.getEntryState().setArenaState();
// Update visibility for the player
MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player);
player.getInventory().addItem(GUIHelper.getGUIOpenItem()); player.getInventory().addItem(GUIHelper.getGUIOpenItem());
player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage()); player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage());
return true; return true;