Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix repeated checkpoint setting + bypass teleport check for back-to-checkpoint teleports + fix replacing checkpoints with the pressure plate #14

Merged
merged 5 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/main/java/world/bentobox/parkour/Parkour.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package world.bentobox.parkour;

import java.util.ArrayList;
import java.util.HashMap;

import org.bukkit.Material;
Expand Down Expand Up @@ -91,7 +92,7 @@ public void setup() {
adminCommand = new DefaultAdminCommand(this) {
};

parkourRunRecord = new ParkourRunRecord(new HashMap<>(), new HashMap<>());
parkourRunRecord = new ParkourRunRecord(new HashMap<>(), new HashMap<>(), new ArrayList<>());

registerFlag(PARKOUR_CREATIVE);

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/world/bentobox/parkour/ParkourRunRecord.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
package world.bentobox.parkour;

import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.bukkit.Location;

public record ParkourRunRecord(Map<UUID, Location> checkpoints, Map<UUID, Long> timers) {
public record ParkourRunRecord(Map<UUID, Location> checkpoints, Map<UUID, Long> timers, List<UUID> currentlyTeleporting) {
/**
* Clears any current times or checkpoints
* @param uuid UUID of runner
*/
public void clear(UUID uuid) {
checkpoints.remove(uuid);
timers.remove(uuid);
currentlyTeleporting.remove(uuid);
}

}
10 changes: 5 additions & 5 deletions src/main/java/world/bentobox/parkour/commands/WarpCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@

/**
* Warps to a
* @author tastybento
*
* @author tastybento
*/
public class WarpCommand extends CompositeCommand {

Expand Down Expand Up @@ -48,7 +48,7 @@ public boolean canExecute(User user, String label, List<String> args) {
}
if (args.isEmpty()) {
Optional<Island> island = getIslands().getIslandAt(user.getLocation());
if (island.isEmpty() || !((Parkour)getAddon()).inWorld(user.getWorld())) {
if (island.isEmpty() || !((Parkour) getAddon()).inWorld(user.getWorld())) {
user.sendMessage("parkour.errors.not-on-island");
this.showHelp(this, user);
return false;
Expand Down Expand Up @@ -81,18 +81,18 @@ public boolean execute(User user, String label, List<String> args) {
// Teleport user
user.getPlayer().playSound(user.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 1F, 1F);
user.getPlayer().playSound(warpSpot, Sound.ENTITY_BAT_TAKEOFF, 1F, 1F);
Util.teleportAsync(user.getPlayer(), warpSpot.clone().add(new Vector(0.5, 0.5, 0.5)), TeleportCause.COMMAND);
Util.teleportAsync(user.getPlayer(), warpSpot, TeleportCause.COMMAND);
return true;
}

@Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
ArrayList<String> options = new ArrayList<>(((Parkour)getAddon()).getParkourManager().getWarps().keySet());
ArrayList<String> options = new ArrayList<>(((Parkour) getAddon()).getParkourManager().getWarps().keySet());
if (options.size() < 10) {
return Optional.of(options);
}
// List is too long; require at least the first letter
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
String lastArg = !args.isEmpty() ? args.get(args.size() - 1) : "";
if (args.isEmpty()) {
return Optional.empty();
}
Expand Down
29 changes: 16 additions & 13 deletions src/main/java/world/bentobox/parkour/gui/CoursesTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

Expand All @@ -25,9 +24,9 @@

/**
* Implements a {@link Tab} that shows course rankings
*
* @author tastybento
* @since 1.0.0
*
*/
public class CoursesTab implements Tab {

Expand All @@ -36,8 +35,9 @@ public class CoursesTab implements Tab {

/**
* Show a tab of settings
*
* @param addon - addon
* @param user - user who is viewing the tab
* @param user - user who is viewing the tab
*/
public CoursesTab(Parkour addon, User user) {
super();
Expand All @@ -47,6 +47,7 @@ public CoursesTab(Parkour addon, User user) {

/**
* Get the icon for this tab
*
* @return panel item
*/
@Override
Expand All @@ -69,6 +70,7 @@ public String getName() {

/**
* Get all the flags as panel items
*
* @return list of all the panel items for this flag type
*/
@Override
Expand All @@ -78,20 +80,21 @@ public String getName() {
List<PanelItem> heads = new ArrayList<>();
// Sort the courses by runs
addon.getParkourManager().getParkourData().stream()
.sorted()
.filter(hs -> Objects.nonNull(hs.getWarpSpot()))
.forEach(hs -> {
UUID owner = addon.getIslands().getIslandById(hs.getUniqueId()).map(Island::getOwner).orElse(null);
if (owner != null) {
heads.add(getHead(hs, owner));
}
});
.sorted()
.filter(hs -> Objects.nonNull(hs.getWarpSpot()))
.forEach(hs -> {
UUID owner = addon.getIslands().getIslandById(hs.getUniqueId()).map(Island::getOwner).orElse(null);
if (owner != null) {
heads.add(getHead(hs, owner));
}
});
return heads;
}

/**
* Get the head panel item
* @param pd - parkour data
*
* @param pd - parkour data
* @param playerUUID - the UUID of the owner
* @return PanelItem
*/
Expand All @@ -115,7 +118,7 @@ private PanelItem getHead(ParkourData pd, UUID playerUUID) {
.clickHandler((panel, user, clickType, slot) -> {
user.sendMessage("parkour.warp.warping");
// Teleport user
Util.teleportAsync(user.getPlayer(), pd.getWarpSpot().clone().add(new Vector(0.5, 1, 0.5)), TeleportCause.COMMAND);
Util.teleportAsync(user.getPlayer(), pd.getWarpSpot(), TeleportCause.COMMAND);
return true;
})
.description(description);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;

import org.bukkit.EntityEffect;
import org.bukkit.GameMode;
Expand Down Expand Up @@ -113,27 +114,32 @@ public void onVisitorFall(EntityDamageEvent e) {
player.playEffect(EntityEffect.ENTITY_POOF);
player.setVelocity(new Vector(0, 0, 0));
player.setFallDistance(0);
player.teleport(parkourRunManager.checkpoints().get(player.getUniqueId()));
Location checkpointLocation = parkourRunManager.checkpoints().get(player.getUniqueId());
checkpointLocation = checkpointLocation.clone().add(0.5, 0, 0.5);
parkourRunManager.currentlyTeleporting().add(player.getUniqueId());
player.teleport(checkpointLocation);
456dev marked this conversation as resolved.
Show resolved Hide resolved
parkourRunManager.currentlyTeleporting().remove(player.getUniqueId());
456dev marked this conversation as resolved.
Show resolved Hide resolved

}

@EventHandler
public void onTeleport(PlayerTeleportEvent e) {
boolean shouldStopRun = switch (e.getCause()) {
case ENDER_PEARL, CHORUS_FRUIT, DISMOUNT, EXIT_BED -> false;
case COMMAND, PLUGIN, NETHER_PORTAL, END_PORTAL, SPECTATE, END_GATEWAY, UNKNOWN -> true;
case ENDER_PEARL, CHORUS_FRUIT, DISMOUNT, EXIT_BED -> false;
case COMMAND, PLUGIN, NETHER_PORTAL, END_PORTAL, SPECTATE, END_GATEWAY, UNKNOWN -> true;
};
if (shouldStopRun && parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) {
User user = User.getInstance(e.getPlayer().getUniqueId());
if (parkourRunManager.checkpoints().containsKey(e.getPlayer().getUniqueId()) && user.isOnline()) {
UUID playerUUID = e.getPlayer().getUniqueId();
if (!parkourRunManager.currentlyTeleporting().contains(playerUUID) && shouldStopRun && parkourRunManager.timers().containsKey(playerUUID)) {
User user = User.getInstance(playerUUID);
if (parkourRunManager.checkpoints().containsKey(playerUUID) && user.isOnline()) {
user.notify("parkour.session-ended");
}
parkourRunManager.clear(e.getPlayer().getUniqueId());
parkourRunManager.clear(playerUUID);
}
// Check world - only apply flag actions to Parkour world and only if player is not actively running the course
if (e.getTo() == null // To can sometimes be null...
|| !addon.inWorld(e.getTo())
|| parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) {
|| parkourRunManager.timers().containsKey(playerUUID)) {
return;
}
// Handle flag action for players who are not running
Expand Down Expand Up @@ -205,44 +211,44 @@ public void onStartEndSet(PlayerInteractEvent e) {
return;
}

Location l = e.getClickedBlock().getLocation();
Location blockLocation = e.getClickedBlock().getLocation();
User user = User.getInstance(e.getPlayer());
addon.getIslands().getProtectedIslandAt(l).ifPresent(island -> {
addon.getIslands().getProtectedIslandAt(blockLocation).ifPresent(island -> {
Optional<Location> start = addon.getParkourManager().getStart(island);
Optional<Location> end = addon.getParkourManager().getEnd(island);

// Check if start and end is set
if (start.filter(startLoc -> isLocEquals(l, startLoc)).isPresent()) {
if (start.filter(startLoc -> isLocEquals(blockLocation, startLoc)).isPresent()) {
// End is not set
if (end.isEmpty()) {
user.sendMessage("parkour.set-the-end");
return;
}
// Start the race!
if (!parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) {
parkourStart(user, l);
parkourStart(user, blockLocation);
}
} else if (end.filter(endLoc -> isLocEquals(l, endLoc)).isPresent()
} else if (end.filter(endLoc -> isLocEquals(blockLocation, endLoc)).isPresent()
&& parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) {
// End the race!
parkourEnd(user, island, l);
parkourEnd(user, island, blockLocation);
}
});
}

void parkourStart(User user, Location l) {
void parkourStart(User user, Location blockLocation) {
user.sendMessage("parkour.start");
user.getPlayer().playSound(l, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F);
user.getPlayer().playSound(blockLocation, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F);
parkourRunManager.timers().put(user.getUniqueId(), System.currentTimeMillis());
parkourRunManager.checkpoints().put(user.getUniqueId(), user.getLocation());
parkourRunManager.checkpoints().put(user.getUniqueId(), blockLocation);
user.setGameMode(GameMode.SURVIVAL);

}

void parkourEnd(User user, Island island, Location l) {
void parkourEnd(User user, Island island, Location blockLocation) {
long duration = (System.currentTimeMillis() - Objects.requireNonNull(parkourRunManager.timers().get(user.getUniqueId())));
user.notify("parkour.end");
user.getPlayer().playSound(l, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F);
user.getPlayer().playSound(blockLocation, Sound.ENTITY_FIREWORK_ROCKET_LAUNCH, 1F, 1F);
user.notify("parkour.you-took", TextVariables.NUMBER, getDuration(user, duration));
parkourRunManager.clear(user.getUniqueId());

Expand Down Expand Up @@ -279,14 +285,18 @@ public void onCheckpoint(PlayerInteractEvent e) {
|| !parkourRunManager.timers().containsKey(e.getPlayer().getUniqueId())) {
return;
}
Location l = e.getClickedBlock().getLocation();
User user = User.getInstance(e.getPlayer());
Vector checkPoint = parkourRunManager.checkpoints().get(e.getPlayer().getUniqueId()).toVector();

if (addon.getIslands().getProtectedIslandAt(l).isPresent() && !l.toVector().equals(checkPoint)) {
user.notify("parkour.checkpoint");
e.getPlayer().playSound(l, Sound.BLOCK_BELL_USE, 1F, 1F);
parkourRunManager.checkpoints().put(user.getUniqueId(), e.getPlayer().getLocation());
Location newCheckpointBlockLocation = e.getClickedBlock().getLocation();
if (addon.getIslands().getProtectedIslandAt(newCheckpointBlockLocation).isPresent()) {
// pressure plate should be a checkpoint
Location currentCheckpointBlockLocation = parkourRunManager.checkpoints().get(e.getPlayer().getUniqueId());
if (!isLocEquals(newCheckpointBlockLocation, currentCheckpointBlockLocation)) {
// new location is different
User user = User.getInstance(e.getPlayer());
user.sendMessage("parkour.checkpoint");
e.getPlayer().playSound(newCheckpointBlockLocation, Sound.BLOCK_BELL_USE, 1F, 1F);
parkourRunManager.checkpoints().put(user.getUniqueId(), newCheckpointBlockLocation);
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ public void onWarpSet(BlockPlaceEvent e) {
Optional<Location> warpSpot = addon.getParkourManager().getWarpSpot(island);
if (warpSpot.isEmpty()) {
user.notify("parkour.warp.set");
addon.getParkourManager().setWarpSpot(island, l);
} else {
user.notify("parkour.warp.replaced");
}
// shift from block to player location
addon.getParkourManager().setWarpSpot(island, l.add(0.5,0,0.5));
456dev marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -109,7 +110,7 @@ public void setUp() throws Exception {
when(ac.getWorld()).thenReturn(world);
when(ac.getAddon()).thenReturn(addon);

prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>());
prm = new ParkourRunRecord(new HashMap<>(), new HashMap<>(), new ArrayList<>());
prm.timers().put(uuid, 20L);
when(addon.getParkourRunRecord()).thenReturn(prm);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ public void setUp() throws Exception {

// Location
when(location.clone()).thenReturn(location);
when(location.add(any(Vector.class))).thenReturn(location);

// Settings
Settings settings = new Settings();
Expand Down Expand Up @@ -267,7 +266,6 @@ public void testExecuteUserStringListOfString() {
verify(user).sendMessage("parkour.warp.warping");
// Teleport user
verify(p, times(2)).playSound(location, Sound.ENTITY_BAT_TAKEOFF, 1F, 1F);
verify(location).add(any(Vector.class));
PowerMockito.verifyStatic(Util.class);
Util.teleportAsync(p, location, TeleportCause.COMMAND);

Expand Down
Loading
Loading