mirror of
https://github.com/SunNetservers/MiniGames.git
synced 2025-07-29 11:15:28 +02:00
Finishes the changes for parkour arenas, hopefully
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* An abstract representation of a player's entry state
|
||||
*/
|
||||
public abstract class AbstractPlayerEntryState implements PlayerEntryState {
|
||||
|
||||
protected final Player player;
|
||||
private final boolean makePlayerInvisible;
|
||||
private final Location entryLocation;
|
||||
private final boolean originalIsFlying;
|
||||
private final GameMode originalGameMode;
|
||||
private final boolean originalAllowFlight;
|
||||
private final boolean originalInvulnerable;
|
||||
private final boolean originalIsSwimming;
|
||||
private final boolean originalCollideAble;
|
||||
|
||||
/**
|
||||
* Instantiates a new abstract player entry state
|
||||
*
|
||||
* @param player <p>The player whose state this should keep track of</p>
|
||||
* @param makePlayerInvisible <p>Whether players should be made invisible while in the arena</p>
|
||||
*/
|
||||
public AbstractPlayerEntryState(@NotNull Player player, boolean makePlayerInvisible) {
|
||||
this.player = player;
|
||||
this.makePlayerInvisible = makePlayerInvisible;
|
||||
this.entryLocation = player.getLocation().clone();
|
||||
this.originalIsFlying = player.isFlying();
|
||||
this.originalGameMode = player.getGameMode();
|
||||
this.originalAllowFlight = player.getAllowFlight();
|
||||
this.originalInvulnerable = player.isInvulnerable();
|
||||
this.originalIsSwimming = player.isSwimming();
|
||||
this.originalCollideAble = player.isCollidable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArenaState() {
|
||||
if (this.makePlayerInvisible) {
|
||||
this.player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,
|
||||
PotionEffect.INFINITE_DURATION, 3));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restore() {
|
||||
this.player.setFlying(this.originalIsFlying);
|
||||
this.player.setGameMode(this.originalGameMode);
|
||||
this.player.setAllowFlight(this.originalAllowFlight);
|
||||
this.player.setInvulnerable(this.originalInvulnerable);
|
||||
this.player.setSwimming(this.originalIsSwimming);
|
||||
this.player.setCollidable(this.originalCollideAble);
|
||||
if (this.makePlayerInvisible) {
|
||||
this.player.removePotionEffect(PotionEffectType.INVISIBILITY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getEntryLocation() {
|
||||
return this.entryLocation;
|
||||
}
|
||||
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -9,12 +11,19 @@ import java.util.UUID;
|
||||
*/
|
||||
public interface Arena {
|
||||
|
||||
/**
|
||||
* Gets the name of this arena
|
||||
*
|
||||
* @return <p>The name of this arena</p>
|
||||
*/
|
||||
@NotNull String getArenaName();
|
||||
|
||||
/**
|
||||
* Gets the data stored for this arena
|
||||
*
|
||||
* @return <p>The stored data</p>
|
||||
*/
|
||||
ArenaData getData();
|
||||
@NotNull ArenaData getData();
|
||||
|
||||
/**
|
||||
* Gets the id of this arena
|
||||
@@ -44,4 +53,34 @@ public interface Arena {
|
||||
*/
|
||||
boolean saveData();
|
||||
|
||||
/**
|
||||
* Gets whether standing on the given block should cause a win
|
||||
*
|
||||
* @param block <p>The block to check</p>
|
||||
* @return <p>True if standing on the block will cause a win</p>
|
||||
*/
|
||||
boolean willCauseWin(Block block);
|
||||
|
||||
/**
|
||||
* Gets whether standing on the given block should cause a loss
|
||||
*
|
||||
* @param block <p>The block to check</p>
|
||||
* @return <p>True if standing on the block will cause a loss</p>
|
||||
*/
|
||||
boolean willCauseLoss(Block block);
|
||||
|
||||
/**
|
||||
* Gets whether the win location is a solid block
|
||||
*
|
||||
* @return <p>True if the location is a solid block</p>
|
||||
*/
|
||||
boolean winLocationIsSolid();
|
||||
|
||||
/**
|
||||
* Gets the location of this arena's spawn
|
||||
*
|
||||
* @return <p>This arena's spawn location</p>
|
||||
*/
|
||||
@NotNull Location getSpawnLocation();
|
||||
|
||||
}
|
||||
|
@@ -1,8 +1,24 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* An interface describing any arena game-mode
|
||||
*/
|
||||
public interface ArenaGameMode {
|
||||
|
||||
/**
|
||||
* Gets the name of this game-mode
|
||||
*
|
||||
* @return <p>The name of this game-mode</p>
|
||||
*/
|
||||
@NotNull String name();
|
||||
|
||||
/**
|
||||
* Gets a set of all available arena game-modes in the type definition of this game-mode
|
||||
*
|
||||
* @return <p>All game-modes in this game-mode's class</p>
|
||||
*/
|
||||
@NotNull ArenaGameMode[] getValues();
|
||||
|
||||
}
|
||||
|
@@ -14,6 +14,12 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A group containing a list of arenas
|
||||
*
|
||||
* @param <K> <p>The type of arena stored</p>
|
||||
* @param <S> <p>The type of arena group stored in the given arena handler</p>
|
||||
*/
|
||||
public abstract class ArenaGroup<K extends Arena, S extends ArenaGroup<K, S>> implements ConfigurationSerializable {
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,56 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A player's session while in an arena
|
||||
*/
|
||||
public interface ArenaSession {
|
||||
|
||||
/**
|
||||
* Gets the game-mode the player is playing in this session
|
||||
*
|
||||
* @return <p>The game-mode for this session</p>
|
||||
*/
|
||||
@NotNull ArenaGameMode getGameMode();
|
||||
|
||||
/**
|
||||
* Gets the state of the player when they joined the session
|
||||
*
|
||||
* @return <p>The player's entry state</p>
|
||||
*/
|
||||
@NotNull PlayerEntryState getEntryState();
|
||||
|
||||
/**
|
||||
* Triggers a win for the player playing in this session
|
||||
*/
|
||||
void triggerWin();
|
||||
|
||||
/**
|
||||
* Triggers a loss for the player playing in this session
|
||||
*/
|
||||
void triggerLoss();
|
||||
|
||||
/**
|
||||
* Triggers a quit for the player playing in this session
|
||||
*
|
||||
* @param immediately <p>Whether to to the teleportation immediately, not using any timers</p>
|
||||
*/
|
||||
void triggerQuit(boolean immediately);
|
||||
|
||||
/**
|
||||
* Gets the arena this session is being played in
|
||||
*
|
||||
* @return <p>The session's arena</p>
|
||||
*/
|
||||
@NotNull Arena getArena();
|
||||
|
||||
/**
|
||||
* Gets the player playing in this session
|
||||
*
|
||||
* @return <p>This session's player</p>
|
||||
*/
|
||||
@NotNull Player getPlayer();
|
||||
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
/**
|
||||
* The stored state of a player
|
||||
*/
|
||||
public interface PlayerEntryState {
|
||||
|
||||
/**
|
||||
* Sets the state of the stored player to the state used by the arena
|
||||
*/
|
||||
void setArenaState();
|
||||
|
||||
/**
|
||||
* Restores the stored state for the stored player
|
||||
*/
|
||||
void restore();
|
||||
|
||||
/**
|
||||
* Gets the location the player entered from
|
||||
*
|
||||
* @return <p>The location the player entered from</p>
|
||||
*/
|
||||
Location getEntryLocation();
|
||||
|
||||
}
|
@@ -9,6 +9,7 @@ import net.knarcraft.minigames.util.DropperArenaStorageHelper;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -69,6 +70,8 @@ public class DropperArena implements Arena {
|
||||
|
||||
private final DropperArenaHandler dropperArenaHandler;
|
||||
|
||||
private static final DropperConfiguration dropperConfiguration = MiniGames.getInstance().getDropperConfiguration();
|
||||
|
||||
/**
|
||||
* Instantiates a new dropper arena
|
||||
*
|
||||
@@ -127,40 +130,22 @@ public class DropperArena implements Arena {
|
||||
this.dropperArenaHandler = arenaHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this arena's data
|
||||
*
|
||||
* @return <p>This arena's data</p>
|
||||
*/
|
||||
@Override
|
||||
public @NotNull DropperArenaData getData() {
|
||||
return this.dropperArenaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of this arena
|
||||
*
|
||||
* @return <p>This arena's identifier</p>
|
||||
*/
|
||||
@Override
|
||||
public @NotNull UUID getArenaId() {
|
||||
return this.arenaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this arena
|
||||
*
|
||||
* @return <p>The name of this arena</p>
|
||||
*/
|
||||
@Override
|
||||
public @NotNull String getArenaName() {
|
||||
return this.arenaName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this arena's spawn location
|
||||
*
|
||||
* <p>The spawn location is the location every player starts from when entering the dropper.</p>
|
||||
*
|
||||
* @return <p>This arena's spawn location.</p>
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Location getSpawnLocation() {
|
||||
return this.spawnLocation.clone();
|
||||
}
|
||||
@@ -230,6 +215,21 @@ public class DropperArena implements Arena {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willCauseWin(Block block) {
|
||||
return block.getType() == winBlockType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willCauseLoss(Block block) {
|
||||
return !dropperConfiguration.getBlockWhitelist().contains(block.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean winLocationIsSolid() {
|
||||
return winBlockType.isSolid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the spawn location for this arena
|
||||
*
|
||||
|
@@ -64,4 +64,9 @@ public enum DropperArenaGameMode implements ConfigurationSerializable, ArenaGame
|
||||
return DropperArenaGameMode.valueOf((String) data.get("name"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull DropperArenaGameMode[] getValues() {
|
||||
return DropperArenaGameMode.values();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@ package net.knarcraft.minigames.arena.dropper;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import net.knarcraft.minigames.arena.PlayerEntryState;
|
||||
import net.knarcraft.minigames.config.DropperConfiguration;
|
||||
import net.knarcraft.minigames.property.RecordResult;
|
||||
import net.knarcraft.minigames.util.PlayerTeleporter;
|
||||
@@ -14,14 +16,14 @@ import java.util.logging.Level;
|
||||
/**
|
||||
* A representation of a player's current session in a dropper arena
|
||||
*/
|
||||
public class DropperArenaSession {
|
||||
public class DropperArenaSession implements ArenaSession {
|
||||
|
||||
private final @NotNull DropperArena arena;
|
||||
private final @NotNull Player player;
|
||||
private final @NotNull DropperArenaGameMode gameMode;
|
||||
private int deaths;
|
||||
private final long startTime;
|
||||
private final DropperPlayerEntryState entryState;
|
||||
private final PlayerEntryState entryState;
|
||||
|
||||
/**
|
||||
* Instantiates a new dropper arena session
|
||||
@@ -41,9 +43,10 @@ public class DropperArenaSession {
|
||||
DropperConfiguration configuration = MiniGames.getInstance().getDropperConfiguration();
|
||||
boolean makeInvisible = configuration.makePlayersInvisible();
|
||||
boolean disableCollision = configuration.disableHitCollision();
|
||||
this.entryState = new DropperPlayerEntryState(player, gameMode, makeInvisible, disableCollision);
|
||||
this.entryState = new DropperPlayerEntryState(player, gameMode, makeInvisible, disableCollision,
|
||||
dropperArena.getPlayerHorizontalVelocity());
|
||||
// Make the player fly to improve mobility in the air
|
||||
this.entryState.setArenaState(this.arena.getPlayerHorizontalVelocity());
|
||||
this.entryState.setArenaState();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +63,7 @@ public class DropperArenaSession {
|
||||
*
|
||||
* @return <p>The player's entry state</p>
|
||||
*/
|
||||
public @NotNull DropperPlayerEntryState getEntryState() {
|
||||
public @NotNull PlayerEntryState getEntryState() {
|
||||
return this.entryState;
|
||||
}
|
||||
|
||||
@@ -91,6 +94,8 @@ public class DropperArenaSession {
|
||||
|
||||
/**
|
||||
* Teleports the playing player out of the arena
|
||||
*
|
||||
* @param immediately <p>Whether to to the teleportation immediately, not using any timers</p>
|
||||
*/
|
||||
private void teleportToExit(boolean immediately) {
|
||||
// Teleport the player out of the arena
|
||||
@@ -159,11 +164,13 @@ public class DropperArenaSession {
|
||||
this.deaths++;
|
||||
//Teleport the player back to the top
|
||||
PlayerTeleporter.teleportPlayer(this.player, this.arena.getSpawnLocation(), true, false);
|
||||
this.entryState.setArenaState(this.arena.getPlayerHorizontalVelocity());
|
||||
this.entryState.setArenaState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a quit for the player playing in this session
|
||||
*
|
||||
* @param immediately <p>Whether to to the teleportation immediately, not using any timers</p>
|
||||
*/
|
||||
public void triggerQuit(boolean immediately) {
|
||||
// Stop this session
|
||||
|
@@ -1,28 +1,18 @@
|
||||
package net.knarcraft.minigames.arena.dropper;
|
||||
|
||||
import net.knarcraft.minigames.arena.AbstractPlayerEntryState;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* The state of a player before entering a dropper arena
|
||||
*/
|
||||
public class DropperPlayerEntryState {
|
||||
public class DropperPlayerEntryState extends AbstractPlayerEntryState {
|
||||
|
||||
private final Player player;
|
||||
private final Location entryLocation;
|
||||
private final boolean originalIsFlying;
|
||||
private final float originalFlySpeed;
|
||||
private final GameMode originalGameMode;
|
||||
private final boolean originalAllowFlight;
|
||||
private final boolean originalInvulnerable;
|
||||
private final boolean originalIsSwimming;
|
||||
private final boolean originalCollideAble;
|
||||
private final boolean makePlayerInvisible;
|
||||
private final boolean disableHitCollision;
|
||||
private final float horizontalVelocity;
|
||||
private final DropperArenaGameMode arenaGameMode;
|
||||
|
||||
/**
|
||||
@@ -30,28 +20,18 @@ public class DropperPlayerEntryState {
|
||||
*
|
||||
* @param player <p>The player whose state should be stored</p>
|
||||
*/
|
||||
public DropperPlayerEntryState(@NotNull Player player, @NotNull DropperArenaGameMode arenaGameMode, boolean makePlayerInvisible,
|
||||
boolean disableHitCollision) {
|
||||
this.player = player;
|
||||
this.entryLocation = player.getLocation().clone();
|
||||
public DropperPlayerEntryState(@NotNull Player player, @NotNull DropperArenaGameMode arenaGameMode,
|
||||
boolean makePlayerInvisible, boolean disableHitCollision, float horizontalVelocity) {
|
||||
super(player, makePlayerInvisible);
|
||||
this.originalFlySpeed = player.getFlySpeed();
|
||||
this.originalIsFlying = player.isFlying();
|
||||
this.originalGameMode = player.getGameMode();
|
||||
this.originalAllowFlight = player.getAllowFlight();
|
||||
this.originalInvulnerable = player.isInvulnerable();
|
||||
this.originalIsSwimming = player.isSwimming();
|
||||
this.arenaGameMode = arenaGameMode;
|
||||
this.originalCollideAble = player.isCollidable();
|
||||
this.makePlayerInvisible = makePlayerInvisible;
|
||||
this.disableHitCollision = disableHitCollision;
|
||||
this.horizontalVelocity = horizontalVelocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of the stored player to the state used by arenas
|
||||
*
|
||||
* @param horizontalVelocity <p>The horizontal velocity to apply to the player</p>
|
||||
*/
|
||||
public void setArenaState(float horizontalVelocity) {
|
||||
@Override
|
||||
public void setArenaState() {
|
||||
super.setArenaState();
|
||||
this.player.setAllowFlight(true);
|
||||
this.player.setFlying(true);
|
||||
this.player.setGameMode(GameMode.ADVENTURE);
|
||||
@@ -59,44 +39,19 @@ public class DropperPlayerEntryState {
|
||||
if (this.disableHitCollision) {
|
||||
this.player.setCollidable(false);
|
||||
}
|
||||
if (this.makePlayerInvisible) {
|
||||
this.player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,
|
||||
PotionEffect.INFINITE_DURATION, 3));
|
||||
}
|
||||
|
||||
// If playing on the inverted game-mode, negate the horizontal velocity to swap the controls
|
||||
if (arenaGameMode == DropperArenaGameMode.INVERTED) {
|
||||
this.player.setFlySpeed(-horizontalVelocity);
|
||||
if (this.arenaGameMode == DropperArenaGameMode.INVERTED) {
|
||||
this.player.setFlySpeed(-this.horizontalVelocity);
|
||||
} else {
|
||||
this.player.setFlySpeed(horizontalVelocity);
|
||||
this.player.setFlySpeed(this.horizontalVelocity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the stored state for the stored player
|
||||
*/
|
||||
@Override
|
||||
public void restore() {
|
||||
this.player.setFlying(this.originalIsFlying);
|
||||
this.player.setGameMode(this.originalGameMode);
|
||||
this.player.setAllowFlight(this.originalAllowFlight);
|
||||
super.restore();
|
||||
this.player.setFlySpeed(this.originalFlySpeed);
|
||||
this.player.setInvulnerable(this.originalInvulnerable);
|
||||
this.player.setSwimming(this.originalIsSwimming);
|
||||
if (this.disableHitCollision) {
|
||||
this.player.setCollidable(this.originalCollideAble);
|
||||
}
|
||||
if (this.makePlayerInvisible) {
|
||||
this.player.removePotionEffect(PotionEffectType.INVISIBILITY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location the player entered from
|
||||
*
|
||||
* @return <p>The location the player entered from</p>
|
||||
*/
|
||||
public Location getEntryLocation() {
|
||||
return this.entryLocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import net.knarcraft.minigames.util.ParkourArenaStorageHelper;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -72,7 +73,7 @@ public class ParkourArena implements Arena {
|
||||
/**
|
||||
* The checkpoints for this arena. Entering a checkpoint overrides the player's spawn location.
|
||||
*/
|
||||
private @NotNull List<Location> checkpoints;
|
||||
private final @NotNull List<Location> checkpoints;
|
||||
|
||||
/**
|
||||
* The arena data for this arena
|
||||
@@ -141,40 +142,22 @@ public class ParkourArena implements Arena {
|
||||
this.parkourArenaHandler = arenaHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this arena's data
|
||||
*
|
||||
* @return <p>This arena's data</p>
|
||||
*/
|
||||
@Override
|
||||
public @NotNull ParkourArenaData getData() {
|
||||
return this.parkourArenaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of this arena
|
||||
*
|
||||
* @return <p>This arena's identifier</p>
|
||||
*/
|
||||
@Override
|
||||
public @NotNull UUID getArenaId() {
|
||||
return this.arenaId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this arena
|
||||
*
|
||||
* @return <p>The name of this arena</p>
|
||||
*/
|
||||
@Override
|
||||
public @NotNull String getArenaName() {
|
||||
return this.arenaName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this arena's spawn location
|
||||
*
|
||||
* <p>The spawn location is the location every player starts from when entering the parkour arena.</p>
|
||||
*
|
||||
* @return <p>This arena's spawn location.</p>
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Location getSpawnLocation() {
|
||||
return this.spawnLocation;
|
||||
}
|
||||
@@ -213,7 +196,7 @@ public class ParkourArena implements Arena {
|
||||
*
|
||||
* @return <p>The types of blocks that cause a loss</p>
|
||||
*/
|
||||
public Set<Material> getKillPlaneBlocks() {
|
||||
public @NotNull Set<Material> getKillPlaneBlocks() {
|
||||
if (this.killPlaneBlocks != null) {
|
||||
return new HashSet<>(this.killPlaneBlocks);
|
||||
} else {
|
||||
@@ -267,6 +250,23 @@ public class ParkourArena implements Arena {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willCauseWin(Block block) {
|
||||
return (this.winLocation != null && this.winLocation.getBlock().equals(block)) ||
|
||||
this.winBlockType == block.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willCauseLoss(Block block) {
|
||||
return this.getKillPlaneBlocks().contains(block.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean winLocationIsSolid() {
|
||||
return (this.winLocation != null && this.winLocation.getBlock().getType().isSolid()) ||
|
||||
this.winBlockType.isSolid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the spawn location for this arena
|
||||
*
|
||||
@@ -357,26 +357,41 @@ public class ParkourArena implements Arena {
|
||||
*
|
||||
* @param killPlaneBlockNames <p>The names of the blocks that will cause players to lose</p>
|
||||
*/
|
||||
public void setKillPlaneBlocks(@NotNull Set<String> killPlaneBlockNames) {
|
||||
this.killPlaneBlocks = MaterialHelper.loadMaterialList(new ArrayList<>(killPlaneBlockNames));
|
||||
public boolean setKillPlaneBlocks(@NotNull Set<String> killPlaneBlockNames) {
|
||||
if (killPlaneBlockNames.isEmpty()) {
|
||||
this.killPlaneBlocks = null;
|
||||
} else {
|
||||
Set<Material> parsed = MaterialHelper.loadMaterialList(new ArrayList<>(killPlaneBlockNames));
|
||||
if (parsed.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
this.killPlaneBlocks = parsed;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the checkpoints of this arena
|
||||
* Adds a checkpoint to this arena
|
||||
*
|
||||
* @param checkpoints <p>The checkpoints to use</p>
|
||||
* @return <p>True if successfully changed</p>
|
||||
* @param checkpoint <p>The checkpoint to add</p>
|
||||
* @return <p>True if successfully added</p>
|
||||
*/
|
||||
public boolean setCheckpoints(@NotNull List<Location> checkpoints) {
|
||||
List<Location> copy = new ArrayList<>(checkpoints.size());
|
||||
for (Location location : checkpoints) {
|
||||
if (isInvalid(location)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
copy.add(location.clone());
|
||||
public boolean addCheckpoint(@NotNull Location checkpoint) {
|
||||
if (isInvalid(checkpoint)) {
|
||||
return false;
|
||||
}
|
||||
this.checkpoints = copy;
|
||||
|
||||
this.checkpoints.add(checkpoint.clone());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all checkpoints from this arena
|
||||
*
|
||||
* @return <p>True if successfully cleared</p>
|
||||
*/
|
||||
public boolean clearCheckpoints() {
|
||||
this.checkpoints.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,6 @@ import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaData;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.container.SerializableContainer;
|
||||
import net.knarcraft.minigames.container.SerializableUUID;
|
||||
import net.knarcraft.minigames.util.SerializableConverter;
|
||||
@@ -39,10 +38,10 @@ public class ParkourArenaData extends ArenaData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a dropper arena data from the given data
|
||||
* Deserializes a parkour arena data from the given data
|
||||
*
|
||||
* @param data <p>The data to deserialize</p>
|
||||
* @return <p>The deserialized dropper arena data</p>
|
||||
* @return <p>The deserialized parkour arena data</p>
|
||||
*/
|
||||
@SuppressWarnings({"unused", "unchecked"})
|
||||
public static @NotNull ParkourArenaData deserialize(@NotNull Map<String, Object> data) {
|
||||
@@ -64,7 +63,7 @@ public class ParkourArenaData extends ArenaData {
|
||||
|
||||
for (ArenaGameMode arenaGameMode : playersCompletedData.keySet()) {
|
||||
if (!recordsRegistry.containsKey(arenaGameMode) || recordsRegistry.get(arenaGameMode) == null) {
|
||||
recordsRegistry.put(arenaGameMode, new DropperArenaRecordsRegistry(serializableUUID.getRawValue()));
|
||||
recordsRegistry.put(arenaGameMode, new ParkourArenaRecordsRegistry(serializableUUID.getRawValue()));
|
||||
}
|
||||
}
|
||||
return new ParkourArenaData(serializableUUID.getRawValue(), recordsRegistry, allPlayersCompleted);
|
||||
|
@@ -0,0 +1,107 @@
|
||||
package net.knarcraft.minigames.arena.parkour;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* All editable properties of a parkour arena
|
||||
*/
|
||||
public enum ParkourArenaEditableProperty {
|
||||
|
||||
/**
|
||||
* The name of the arena
|
||||
*/
|
||||
NAME("name", ParkourArena::getArenaName),
|
||||
|
||||
/**
|
||||
* The arena's spawn location
|
||||
*/
|
||||
SPAWN_LOCATION("spawnLocation", (arena) -> String.valueOf(arena.getSpawnLocation())),
|
||||
|
||||
/**
|
||||
* The arena's exit location
|
||||
*/
|
||||
EXIT_LOCATION("exitLocation", (arena) -> String.valueOf(arena.getExitLocation())),
|
||||
|
||||
/**
|
||||
* The arena's win block type
|
||||
*/
|
||||
WIN_BLOCK_TYPE("winBlockType", (arena) -> arena.getWinBlockType().toString()),
|
||||
|
||||
/**
|
||||
* The arena's win location (overrides the win block type)
|
||||
*/
|
||||
WIN_LOCATION("winLocation", (arena) -> {
|
||||
if (arena.getWinLocation() != null) {
|
||||
return arena.getWinLocation().toString();
|
||||
} else {
|
||||
return "null";
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* The arena's check points. Specifically used for adding.
|
||||
*/
|
||||
CHECKPOINT_ADD("checkpointAdd", (arena) -> String.valueOf(arena.getCheckpoints())),
|
||||
|
||||
/**
|
||||
* The arena's check points. Specifically used for clearing.
|
||||
*/
|
||||
CHECKPOINT_CLEAR("checkpointClear", (arena) -> String.valueOf(arena.getCheckpoints())),
|
||||
|
||||
/**
|
||||
* The blocks constituting the arena's lethal blocks
|
||||
*/
|
||||
KILL_PLANE_BLOCKS("killPlaneBlocks", (arena) -> String.valueOf(arena.getKillPlaneBlockNames())),
|
||||
;
|
||||
|
||||
private final @NotNull String argumentString;
|
||||
private final Function<ParkourArena, String> currentValueProvider;
|
||||
|
||||
/**
|
||||
* Instantiates a new arena editable property
|
||||
*
|
||||
* @param argumentString <p>The argument string used to specify this property</p>
|
||||
*/
|
||||
ParkourArenaEditableProperty(@NotNull String argumentString, Function<ParkourArena, String> currentValueProvider) {
|
||||
this.argumentString = argumentString;
|
||||
this.currentValueProvider = currentValueProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of this property's current value
|
||||
*
|
||||
* @param arena <p>The arena to check the value for</p>
|
||||
* @return <p>The current value as a string</p>
|
||||
*/
|
||||
public String getCurrentValueAsString(ParkourArena arena) {
|
||||
return this.currentValueProvider.apply(arena);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the argument string used to specify this property
|
||||
*
|
||||
* @return <p>The argument string</p>
|
||||
*/
|
||||
public @NotNull String getArgumentString() {
|
||||
return this.argumentString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the editable property corresponding to the given argument string
|
||||
*
|
||||
* @param argumentString <p>The argument string used to specify an editable property</p>
|
||||
* @return <p>The corresponding editable property, or null if not found</p>
|
||||
*/
|
||||
public static @Nullable ParkourArenaEditableProperty getFromArgumentString(String argumentString) {
|
||||
for (ParkourArenaEditableProperty property : ParkourArenaEditableProperty.values()) {
|
||||
if (property.argumentString.equalsIgnoreCase(argumentString)) {
|
||||
return property;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -47,4 +47,9 @@ public enum ParkourArenaGameMode implements ConfigurationSerializable, ArenaGame
|
||||
return ParkourArenaGameMode.valueOf((String) data.get("name"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ParkourArenaGameMode[] getValues() {
|
||||
return ParkourArenaGameMode.values();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,7 +1,10 @@
|
||||
package net.knarcraft.minigames.arena.parkour;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import net.knarcraft.minigames.arena.PlayerEntryState;
|
||||
import net.knarcraft.minigames.config.ParkourConfiguration;
|
||||
import net.knarcraft.minigames.property.RecordResult;
|
||||
import net.knarcraft.minigames.util.PlayerTeleporter;
|
||||
@@ -14,14 +17,14 @@ import java.util.logging.Level;
|
||||
/**
|
||||
* A representation of a player's current session in a parkour arena
|
||||
*/
|
||||
public class ParkourArenaSession {
|
||||
public class ParkourArenaSession implements ArenaSession {
|
||||
|
||||
private final @NotNull ParkourArena arena;
|
||||
private final @NotNull Player player;
|
||||
private final @NotNull ParkourArenaGameMode gameMode;
|
||||
private int deaths;
|
||||
private final long startTime;
|
||||
private final ParkourPlayerEntryState entryState;
|
||||
private final PlayerEntryState entryState;
|
||||
|
||||
/**
|
||||
* Instantiates a new parkour arena session
|
||||
@@ -45,12 +48,17 @@ public class ParkourArenaSession {
|
||||
this.entryState.setArenaState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ArenaGameMode getGameMode() {
|
||||
return this.gameMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of the player when they joined the session
|
||||
*
|
||||
* @return <p>The player's entry state</p>
|
||||
*/
|
||||
public @NotNull ParkourPlayerEntryState getEntryState() {
|
||||
public @NotNull PlayerEntryState getEntryState() {
|
||||
return this.entryState;
|
||||
}
|
||||
|
||||
@@ -63,7 +71,7 @@ public class ParkourArenaSession {
|
||||
|
||||
// Check for, and display, records
|
||||
MiniGames miniGames = MiniGames.getInstance();
|
||||
boolean ignore = miniGames.getDropperConfiguration().ignoreRecordsUntilGroupBeatenOnce();
|
||||
boolean ignore = miniGames.getParkourConfiguration().ignoreRecordsUntilGroupBeatenOnce();
|
||||
ParkourArenaGroup group = miniGames.getParkourArenaHandler().getGroup(this.arena.getArenaId());
|
||||
if (!ignore || group == null || group.hasBeatenAll(this.gameMode, this.player)) {
|
||||
registerRecord();
|
||||
@@ -98,9 +106,9 @@ public class ParkourArenaSession {
|
||||
*/
|
||||
private void removeSession() {
|
||||
// Remove this session for game sessions to stop listeners from fiddling more with the player
|
||||
boolean removedSession = MiniGames.getInstance().getDropperArenaPlayerRegistry().removePlayer(player.getUniqueId());
|
||||
boolean removedSession = MiniGames.getInstance().getParkourArenaPlayerRegistry().removePlayer(player.getUniqueId());
|
||||
if (!removedSession) {
|
||||
MiniGames.log(Level.SEVERE, "Unable to remove dropper arena session for " + player.getName() + ". " +
|
||||
MiniGames.log(Level.SEVERE, "Unable to remove parkour arena session for " + player.getName() + ". " +
|
||||
"This will have unintended consequences.");
|
||||
}
|
||||
}
|
||||
|
@@ -1,26 +1,14 @@
|
||||
package net.knarcraft.minigames.arena.parkour;
|
||||
|
||||
import net.knarcraft.minigames.arena.AbstractPlayerEntryState;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* The state of a player before entering a dropper arena
|
||||
* The state of a player before entering a parkour arena
|
||||
*/
|
||||
public class ParkourPlayerEntryState {
|
||||
|
||||
private final Player player;
|
||||
private final Location entryLocation;
|
||||
private final boolean originalIsFlying;
|
||||
private final GameMode originalGameMode;
|
||||
private final boolean originalAllowFlight;
|
||||
private final boolean originalInvulnerable;
|
||||
private final boolean originalIsSwimming;
|
||||
private final boolean originalCollideAble;
|
||||
private final boolean makePlayerInvisible;
|
||||
public class ParkourPlayerEntryState extends AbstractPlayerEntryState {
|
||||
|
||||
/**
|
||||
* Instantiates a new player state
|
||||
@@ -28,54 +16,17 @@ public class ParkourPlayerEntryState {
|
||||
* @param player <p>The player whose state should be stored</p>
|
||||
*/
|
||||
public ParkourPlayerEntryState(@NotNull Player player, boolean makePlayerInvisible) {
|
||||
this.player = player;
|
||||
this.entryLocation = player.getLocation().clone();
|
||||
this.originalIsFlying = player.isFlying();
|
||||
this.originalGameMode = player.getGameMode();
|
||||
this.originalAllowFlight = player.getAllowFlight();
|
||||
this.originalInvulnerable = player.isInvulnerable();
|
||||
this.originalIsSwimming = player.isSwimming();
|
||||
this.originalCollideAble = player.isCollidable();
|
||||
this.makePlayerInvisible = makePlayerInvisible;
|
||||
super(player, makePlayerInvisible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of the stored player to the state used by arenas
|
||||
*/
|
||||
@Override
|
||||
public void setArenaState() {
|
||||
super.setArenaState();
|
||||
this.player.setAllowFlight(false);
|
||||
this.player.setFlying(false);
|
||||
this.player.setGameMode(GameMode.ADVENTURE);
|
||||
this.player.setSwimming(false);
|
||||
this.player.setCollidable(false);
|
||||
if (this.makePlayerInvisible) {
|
||||
this.player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,
|
||||
PotionEffect.INFINITE_DURATION, 3));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the stored state for the stored player
|
||||
*/
|
||||
public void restore() {
|
||||
this.player.setFlying(this.originalIsFlying);
|
||||
this.player.setGameMode(this.originalGameMode);
|
||||
this.player.setAllowFlight(this.originalAllowFlight);
|
||||
this.player.setInvulnerable(this.originalInvulnerable);
|
||||
this.player.setSwimming(this.originalIsSwimming);
|
||||
this.player.setCollidable(this.originalCollideAble);
|
||||
if (this.makePlayerInvisible) {
|
||||
this.player.removePotionEffect(PotionEffectType.INVISIBILITY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location the player entered from
|
||||
*
|
||||
* @return <p>The location the player entered from</p>
|
||||
*/
|
||||
public Location getEntryLocation() {
|
||||
return this.entryLocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user