mirror of
https://github.com/SunNetservers/MiniGames.git
synced 2024-12-05 00:43:15 +01:00
Adds code for winning and losing
Adds methods for triggering a win, a loss and a quit Calls the win, lose and quit methods as necessay in the listeners Makes DropperArenaHandler store arena sessions and cleared stages
This commit is contained in:
parent
62450e8764
commit
ee8f232b0b
@ -81,6 +81,15 @@ public class DropperArena {
|
||||
this.recordsRegistry = new DropperArenaRecordsRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the registry keeping track of this arena's records
|
||||
*
|
||||
* @return <p>This arena's record registry</p>
|
||||
*/
|
||||
public @NotNull DropperArenaRecordsRegistry getRecordsRegistry() {
|
||||
return this.recordsRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this arena
|
||||
*
|
||||
|
@ -2,12 +2,17 @@ package net.knarcraft.dropper.arena;
|
||||
|
||||
import net.knarcraft.dropper.Dropper;
|
||||
import net.knarcraft.dropper.util.ArenaStorageHelper;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
@ -18,6 +23,44 @@ public class DropperArenaHandler {
|
||||
private static final File arenaFile = new File(Dropper.getInstance().getDataFolder(), "arenas.yml");
|
||||
|
||||
private List<DropperArena> arenas = new ArrayList<>();
|
||||
private final Set<DropperArenaSession> activeSessions = new HashSet<>();
|
||||
private final Map<Player, Integer> stagesCleared = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Registers the given arena session to known active arena sessions
|
||||
*
|
||||
* @param session <p>The arena session to register</p>
|
||||
*/
|
||||
public void registerArenaSession(@NotNull DropperArenaSession session) {
|
||||
this.activeSessions.add(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the given arena session from known active arena sessions
|
||||
*
|
||||
* @param session <p>The session to remove</p>
|
||||
* @return <p>True if the session was removed</p>
|
||||
*/
|
||||
public boolean unregisterArenaSession(@NotNull DropperArenaSession session) {
|
||||
return this.activeSessions.remove(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to register the given stage as cleared
|
||||
*
|
||||
* @param player <p>The player that cleared a stage</p>
|
||||
* @param stage <p>The stage the player cleared</p>
|
||||
* @return <p>True if the player cleared a new stage</p>
|
||||
*/
|
||||
public boolean registerStageCleared(@NotNull Player player, int stage) {
|
||||
if ((!stagesCleared.containsKey(player) && stage == 1) || (stagesCleared.containsKey(player) &&
|
||||
stage == stagesCleared.get(player) + 1)) {
|
||||
stagesCleared.put(player, stage);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new arena
|
||||
|
@ -1,15 +1,25 @@
|
||||
package net.knarcraft.dropper.arena;
|
||||
|
||||
import net.knarcraft.dropper.Dropper;
|
||||
import net.knarcraft.dropper.property.ArenaGameMode;
|
||||
import net.knarcraft.dropper.property.RecordResult;
|
||||
import net.knarcraft.dropper.util.PlayerTeleporter;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A representation of a player's current session in a dropper arena
|
||||
*/
|
||||
public class DropperArenaSession {
|
||||
|
||||
private final DropperArena arena;
|
||||
private final Player player;
|
||||
private final ArenaGameMode gameMode;
|
||||
private final int deaths;
|
||||
private final @NotNull DropperArena arena;
|
||||
private final @NotNull Player player;
|
||||
private final @NotNull ArenaGameMode gameMode;
|
||||
private final @NotNull Location entryLocation;
|
||||
private int deaths;
|
||||
private final long startTime;
|
||||
|
||||
/**
|
||||
@ -26,27 +36,122 @@ public class DropperArenaSession {
|
||||
this.gameMode = gameMode;
|
||||
this.deaths = 0;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
this.entryLocation = player.getLocation();
|
||||
// Prevent Spigot interference when traveling at high velocities
|
||||
player.setAllowFlight(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a win for the player playing in this session
|
||||
*/
|
||||
public void triggerWin() {
|
||||
//TODO: Kick the player from the arena
|
||||
//TODO: Register the player's record, if applicable, and announce the result
|
||||
// Remove this session from game sessions to stop listeners from fiddling more with the player
|
||||
removeSession();
|
||||
|
||||
// No longer allow the player to avoid fly checks
|
||||
player.setAllowFlight(false);
|
||||
|
||||
// Check for, and display, records
|
||||
registerRecord();
|
||||
|
||||
//TODO: Give reward?
|
||||
//TODO: If a staged arena, register the stage as cleared
|
||||
//TODO: Teleport the player out of the dropper arena
|
||||
|
||||
// Register and announce any cleared stages
|
||||
Integer arenaStage = arena.getStage();
|
||||
if (arenaStage != null) {
|
||||
boolean clearedNewStage = Dropper.getInstance().getArenaHandler().registerStageCleared(player, arenaStage);
|
||||
if (clearedNewStage) {
|
||||
player.sendMessage("You cleared stage " + arenaStage + "!");
|
||||
}
|
||||
}
|
||||
|
||||
// Teleport the player out of the arena
|
||||
teleportToExit();
|
||||
}
|
||||
|
||||
public void triggerLoss() {
|
||||
switch (gameMode) {
|
||||
case DEFAULT:
|
||||
//TODO: Kick the player, and teleport the player away
|
||||
break;
|
||||
case LEAST_TIME:
|
||||
//TODO: Teleport the player back to the top
|
||||
break;
|
||||
case LEAST_DEATHS:
|
||||
//TODO: Add 1 to the death count, and teleport the player back to the top
|
||||
/**
|
||||
* Teleports the playing player out of the arena
|
||||
*/
|
||||
private void teleportToExit() {
|
||||
// Teleport the player out of the arena
|
||||
Location exitLocation;
|
||||
if (arena.getExitLocation() != null) {
|
||||
exitLocation = arena.getExitLocation();
|
||||
} else {
|
||||
exitLocation = entryLocation;
|
||||
}
|
||||
PlayerTeleporter.teleportPlayer(player, exitLocation, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes this session from current sessions
|
||||
*/
|
||||
private void removeSession() {
|
||||
// Remove this session for game sessions to stop listeners from fiddling more with the player
|
||||
boolean removedSession = Dropper.getInstance().getArenaHandler().unregisterArenaSession(this);
|
||||
if (!removedSession) {
|
||||
Dropper.getInstance().getLogger().log(Level.SEVERE, "Unable to remove dropper arena session for " +
|
||||
player.getName() + ". This will have unintended consequences.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the player's record if necessary, and prints record information to the player
|
||||
*/
|
||||
private void registerRecord() {
|
||||
DropperArenaRecordsRegistry recordsRegistry = arena.getRecordsRegistry();
|
||||
RecordResult recordResult = switch (gameMode) {
|
||||
case LEAST_TIME -> recordsRegistry.registerTimeRecord(player,
|
||||
System.currentTimeMillis() - startTime);
|
||||
case LEAST_DEATHS -> recordsRegistry.registerDeathRecord(player, deaths);
|
||||
case DEFAULT -> RecordResult.NONE;
|
||||
};
|
||||
switch (recordResult) {
|
||||
case WORLD_RECORD -> player.sendMessage("You just set a new record for this arena!");
|
||||
case PERSONAL_BEST -> player.sendMessage("You just got a new personal record!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a loss for the player playing in this session
|
||||
*/
|
||||
public void triggerLoss() {
|
||||
// Add to the death count if playing the least-deaths game-mode
|
||||
if (gameMode == ArenaGameMode.LEAST_DEATHS) {
|
||||
deaths++;
|
||||
}
|
||||
//Teleport the player back to the top
|
||||
PlayerTeleporter.teleportPlayer(player, arena.getSpawnLocation(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a quit for the player playing in this session
|
||||
*/
|
||||
public void triggerQuit() {
|
||||
// Remove this session from game sessions to stop listeners from fiddling more with the player
|
||||
removeSession();
|
||||
// No longer allow the player to avoid fly checks
|
||||
player.setAllowFlight(false);
|
||||
// Teleport the player out of the arena
|
||||
teleportToExit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the arena this session is being played in
|
||||
*
|
||||
* @return <p>The session's arena</p>
|
||||
*/
|
||||
public @NotNull DropperArena getArena() {
|
||||
return this.arena;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player playing in this session
|
||||
*
|
||||
* @return <p>This session's player</p>
|
||||
*/
|
||||
public @NotNull Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.dropper.listener;
|
||||
|
||||
import net.knarcraft.dropper.Dropper;
|
||||
import net.knarcraft.dropper.arena.DropperArenaSession;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -22,15 +23,14 @@ public class DamageListener implements Listener {
|
||||
Player player = (Player) event.getEntity();
|
||||
|
||||
// We don't care about damage outside arenas
|
||||
if (!Dropper.getInstance().getPlayerRegistry().isInArena(player)) {
|
||||
DropperArenaSession arenaSession = Dropper.getInstance().getPlayerRegistry().getArenaSession(player);
|
||||
if (arenaSession == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
//TODO: Kick the player from the arena
|
||||
//TODO: Teleport the player to the location they entered the arena from, or to the spawn
|
||||
//TODO: Do whatever else should be done for losing players (sending a message?)
|
||||
arenaSession.triggerLoss();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,40 +1,71 @@
|
||||
package net.knarcraft.dropper.listener;
|
||||
|
||||
import net.knarcraft.dropper.Dropper;
|
||||
import net.knarcraft.dropper.arena.DropperArenaPlayerRegistry;
|
||||
import net.knarcraft.dropper.arena.DropperArenaSession;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* A listener for players moving inside a dropper arena
|
||||
*/
|
||||
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) {
|
||||
if (!Dropper.getInstance().getPlayerRegistry().isInArena(event.getPlayer())) {
|
||||
Player player = event.getPlayer();
|
||||
DropperArenaPlayerRegistry playerRegistry = Dropper.getInstance().getPlayerRegistry();
|
||||
DropperArenaSession arenaSession = playerRegistry.getArenaSession(player);
|
||||
if (arenaSession == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Block targetBlock = event.getTo().getBlock();
|
||||
Material targetBlockType = targetBlock.getType();
|
||||
|
||||
// Hitting water is the trigger for winning
|
||||
if (targetBlock.getType() == Material.WATER) {
|
||||
//TODO: Register the win, and teleport the player out
|
||||
if (targetBlockType == Material.WATER) {
|
||||
arenaSession.triggerWin();
|
||||
return;
|
||||
}
|
||||
|
||||
Location targetLocation = targetBlock.getLocation();
|
||||
Block beneathPlayer = targetLocation.getWorld().getBlockAt(targetLocation.add(0, -0.1, 0));
|
||||
Material beneathPlayerType = targetLocation.getWorld().getBlockAt(targetLocation.add(0, -0.1, 0)).getType();
|
||||
|
||||
// If hitting something which is not air or water, it must be a solid block, and would end in a loss
|
||||
if (!targetBlock.getType().isAir() || (beneathPlayer.getType() != Material.WATER &&
|
||||
!beneathPlayer.getType().isAir())) {
|
||||
//TODO: This that the same as @see{DamageListener#onPlayerDamage}
|
||||
if (!targetBlockType.isAir() || (beneathPlayerType != Material.WATER &&
|
||||
!beneathPlayerType.isAir())) {
|
||||
arenaSession.triggerLoss();
|
||||
return;
|
||||
}
|
||||
|
||||
//Updates the player's velocity to the one set by the arena
|
||||
updatePlayerVelocity(arenaSession);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the velocity of the player in the given session
|
||||
*
|
||||
* @param session <p>The session to update the velocity for</p>
|
||||
*/
|
||||
private void updatePlayerVelocity(DropperArenaSession session) {
|
||||
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());
|
||||
player.setVelocity(newVelocity);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,31 +1,43 @@
|
||||
package net.knarcraft.dropper.listener;
|
||||
|
||||
import net.knarcraft.dropper.Dropper;
|
||||
import net.knarcraft.dropper.arena.DropperArenaSession;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
/**
|
||||
* A listener for players leaving the server or the arena
|
||||
*/
|
||||
public class PlayerLeaveListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerLeave(PlayerQuitEvent event) {
|
||||
if (!Dropper.getInstance().getPlayerRegistry().isInArena(event.getPlayer())) {
|
||||
return;
|
||||
}
|
||||
//TODO: If in an arena, kick the player.
|
||||
//TODO: Teleport the player away from the arena. It might only be possible to teleport the player when they join
|
||||
// again.
|
||||
triggerQuit(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
if (!Dropper.getInstance().getPlayerRegistry().isInArena(event.getPlayer())) {
|
||||
triggerQuit(event.getPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the given player to quit their current arena
|
||||
*
|
||||
* @param player <p>The player to trigger a quit for</p>
|
||||
*/
|
||||
private void triggerQuit(Player player) {
|
||||
DropperArenaSession arenaSession = Dropper.getInstance().getPlayerRegistry().getArenaSession(player);
|
||||
if (arenaSession == null) {
|
||||
return;
|
||||
}
|
||||
//TODO: Treat this the same as onPlayerLeave if the player is in an arena. If the player doesn't change worlds,
|
||||
// it should be safe to immediately teleport the player to the arena's exit.
|
||||
//TODO: Because of this, make sure to remove the player from the arena before teleporting the player out
|
||||
|
||||
arenaSession.triggerQuit();
|
||||
|
||||
//TODO: It might not be possible to alter the player's location here. It might be necessary to move them once
|
||||
// they join again
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user