Abuses flight mode for better in-air control

This commit is contained in:
Kristian Knarvik 2023-03-24 16:22:52 +01:00
parent eb67705300
commit fba75d2c3f
2 changed files with 69 additions and 41 deletions

View File

@ -21,6 +21,7 @@ public class DropperArenaSession {
private final @NotNull Location entryLocation;
private int deaths;
private final long startTime;
private final float playersOriginalFlySpeed;
/**
* Instantiates a new dropper arena session
@ -37,19 +38,20 @@ public class DropperArenaSession {
this.deaths = 0;
this.startTime = System.currentTimeMillis();
this.entryLocation = player.getLocation();
// Prevent Spigot interference when traveling at high velocities
// Make the player fly to improve mobility in the air
player.setAllowFlight(true);
player.setFlying(true);
this.playersOriginalFlySpeed = player.getFlySpeed();
player.setFlySpeed((float) this.arena.getPlayerVelocity());
}
/**
* Triggers a win for the player playing in this session
*/
public void triggerWin() {
// 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);
// Stop this session
stopSession();
// Check for, and display, records
registerRecord();
@ -57,15 +59,15 @@ public class DropperArenaSession {
//TODO: Give reward?
// Register and announce any cleared stages
Integer arenaStage = arena.getStage();
Integer arenaStage = this.arena.getStage();
if (arenaStage != null) {
boolean clearedNewStage = Dropper.getInstance().getArenaHandler().registerStageCleared(player, arenaStage);
boolean clearedNewStage = Dropper.getInstance().getArenaHandler().registerStageCleared(this.player, arenaStage);
if (clearedNewStage) {
player.sendMessage("You cleared stage " + arenaStage + "!");
this.player.sendMessage("You cleared stage " + arenaStage + "!");
}
}
player.sendMessage("You won!");
this.player.sendMessage("You won!");
// Teleport the player out of the arena
teleportToExit();
@ -77,12 +79,12 @@ public class DropperArenaSession {
private void teleportToExit() {
// Teleport the player out of the arena
Location exitLocation;
if (arena.getExitLocation() != null) {
exitLocation = arena.getExitLocation();
if (this.arena.getExitLocation() != null) {
exitLocation = this.arena.getExitLocation();
} else {
exitLocation = entryLocation;
exitLocation = this.entryLocation;
}
PlayerTeleporter.teleportPlayer(player, exitLocation, true);
PlayerTeleporter.teleportPlayer(this.player, exitLocation, true);
}
/**
@ -101,16 +103,16 @@ public class DropperArenaSession {
* 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);
DropperArenaRecordsRegistry recordsRegistry = this.arena.getRecordsRegistry();
RecordResult recordResult = switch (this.gameMode) {
case LEAST_TIME -> recordsRegistry.registerTimeRecord(this.player,
System.currentTimeMillis() - this.startTime);
case LEAST_DEATHS -> recordsRegistry.registerDeathRecord(this.player, this.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!");
case WORLD_RECORD -> this.player.sendMessage("You just set a new record for this arena!");
case PERSONAL_BEST -> this.player.sendMessage("You just got a new personal record!");
}
}
@ -119,27 +121,38 @@ public class DropperArenaSession {
*/
public void triggerLoss() {
// Add to the death count if playing the least-deaths game-mode
if (gameMode == ArenaGameMode.LEAST_DEATHS) {
deaths++;
if (this.gameMode == ArenaGameMode.LEAST_DEATHS) {
this.deaths++;
}
//Teleport the player back to the top
PlayerTeleporter.teleportPlayer(player, arena.getSpawnLocation(), true);
PlayerTeleporter.teleportPlayer(this.player, this.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);
// Stop this session
stopSession();
// Teleport the player out of the arena
teleportToExit();
player.sendMessage("You quit the arena!");
}
/**
* Stops this session, and disables flight mode
*/
private void stopSession() {
// Remove this session from game sessions to stop listeners from fiddling more with the player
removeSession();
// Remove flight mode
this.player.setFlySpeed(this.playersOriginalFlySpeed);
this.player.setFlying(false);
this.player.setAllowFlight(false);
}
/**
* Gets the arena this session is being played in
*

View File

@ -19,6 +19,11 @@ public class MoveListener implements Listener {
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
// Ignore if no actual movement is happening
if (event.getFrom().equals(event.getTo())) {
return;
}
Player player = event.getPlayer();
DropperArenaPlayerRegistry playerRegistry = Dropper.getInstance().getPlayerRegistry();
DropperArenaSession arenaSession = playerRegistry.getArenaSession(player.getUniqueId());
@ -26,23 +31,33 @@ public class MoveListener implements Listener {
return;
}
Block targetBlock = event.getTo().getBlock();
Material targetBlockType = targetBlock.getType();
// Hitting water is the trigger for winning
if (targetBlockType == Material.WATER) {
arenaSession.triggerWin();
// Prevent the player from flying upwards while in flight mode
if (event.getFrom().getY() < event.getTo().getY()) {
event.setCancelled(true);
return;
}
Location targetLocation = targetBlock.getLocation();
Material beneathPlayerType = targetLocation.getWorld().getBlockAt(targetLocation.add(0, -0.1, 0)).getType();
// Only do block type checking if the block beneath the player changes
if (event.getFrom().getBlock() != event.getTo().getBlock()) {
Block targetBlock = event.getTo().getBlock();
Material targetBlockType = targetBlock.getType();
// If hitting something which is not air or water, it must be a solid block, and would end in a loss
if (!targetBlockType.isAir() || (beneathPlayerType != Material.WATER &&
!beneathPlayerType.isAir())) {
arenaSession.triggerLoss();
return;
// Hitting water is the trigger for winning
if (targetBlockType == Material.WATER) {
arenaSession.triggerWin();
return;
}
Location targetLocation = targetBlock.getLocation();
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 (!targetBlockType.isAir() || (beneathPlayerType != Material.WATER &&
!beneathPlayerType.isAir())) {
arenaSession.triggerLoss();
return;
}
}
//Updates the player's velocity to the one set by the arena