Skip to content

Commit

Permalink
Merge pull request #11 from BentoBoxWorld/develop
Browse files Browse the repository at this point in the history
Version 1.3.0
  • Loading branch information
tastybento authored Aug 5, 2023
2 parents c5b1f12 + 294357d commit de3fd85
Show file tree
Hide file tree
Showing 34 changed files with 2,883 additions and 336 deletions.
1 change: 1 addition & 0 deletions .github/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/.DS_Store
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ hs_err_pid*
/target/
/.classpath
/.project
/.DS_Store
.DS_Store
/parkour.iml
/.idea/
/.settings/
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ The Parkour addon is a BentoBox addon for Minecraft that allows players to creat
To get started, use the `/pk` or `/parkour` command to access the parkour plugin. This will teleport players to an example parkour course and get them started. Admins can use blueprints to change the default course example or make additional ones.

### Course Creation
1. Enter creative mode. Players will need permission to do this.
2. Use creative mode tools to design your parkour course.
3. Place gold pressure plates at the start and end points of the course.
4. Optionally, add checkpoints throughout the course using blackstone pressure plates.
5. Test your course to ensure it is playable and challenging.
1. Use creative mode tools to design your parkour course.
2. Place gold pressure plates at the start and end points of the course.
3. Optionally, add checkpoints throughout the course using blackstone pressure plates.
4. Test your course to ensure it is playable and challenging.
5. Once it's ready, make your course public by making a warp to it by placing a warped pressure plate or using the `/pk setwarp` command

### Course Gameplay
1. Locate the course you want to play using the `/pk courses` command, or play your own.
Expand All @@ -35,16 +35,18 @@ To get started, use the `/pk` or `/parkour` command to access the parkour plugin
### Team Collaboration
1. Form a team with other players using the team creation commands `pk team invite <player name>`.
2. Collaborate with your team members to design and build parkour courses.
3. When you want to make your course available go to the starting area and set a warp point for visitors using `/pk setwarp`
3. When you want to make your course available go to the starting area and set a warp point for visitors using `/pk setwarp` or place a **warped pressure plate** where you want visitors to arrive
4. Use the `/pk courses` command to view and play each other's courses.
5. Compete within the team to achieve the best times on the courses.

## Commands
- `/pk`: Main command to start a parkour course and teleport to the parkour world.
- `/pk courses`: List all the tracks or courses available and teleport to them.
- `/pk top`: Show the Top Ten.
- `/pk setwarp`: Places the course in the courses menu and sets the warp position visitors will arrive at
- `/pk removewarp`: Makes the course private and removes the visitor's warp
- `/pk setwarp`: Places the course in the courses menu and sets the warp position visitors will arrive at. This can also be done by placing a **warped pressure plate**
- `/pk warp <course owner's name>`: warp to a course
- `/pk warp`: warp to the start of the course you are on
- `/pk removewarp`: Makes the course private and removes the visitor's warp. Or break the **warped pressure plate** if there is one.

## Permissions

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number>
<!-- This allows to change between versions. -->
<build.version>1.2.0</build.version>
<build.version>1.3.0</build.version>
<sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
</properties>
Expand Down
59 changes: 48 additions & 11 deletions src/main/java/world/bentobox/parkour/Parkour.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package world.bentobox.parkour;

import java.util.HashMap;

import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.WorldCreator;
Expand All @@ -14,18 +17,24 @@
import world.bentobox.bentobox.api.commands.island.DefaultPlayerCommand;
import world.bentobox.bentobox.api.configuration.Config;
import world.bentobox.bentobox.api.configuration.WorldSettings;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.parkour.commands.ClearTopCommand;
import world.bentobox.parkour.commands.CoursesCommand;
import world.bentobox.parkour.commands.QuitCommand;
import world.bentobox.parkour.commands.RemoveWarpCommand;
import world.bentobox.parkour.commands.SetWarpCommand;
import world.bentobox.parkour.commands.TopCommand;
import world.bentobox.parkour.commands.WarpCommand;
import world.bentobox.parkour.generators.ChunkGeneratorWorld;
import world.bentobox.parkour.gui.RankingsUI;
import world.bentobox.parkour.listeners.CourseRunnerListener;
import world.bentobox.parkour.listeners.MakeCourseListener;

/**
* Main Parkour class
*
* @author tastybento
*/
public class Parkour extends GameModeAddon implements Listener {
Expand All @@ -42,6 +51,20 @@ public class Parkour extends GameModeAddon implements Listener {
private ParkourManager pm;
private RankingsUI rankings;

/**
* Parkour flag that sets which ranks should enter creative mode at the end of the course and
* when entering the island. Visitors never have creative enabled.
*/
public final Flag PARKOUR_CREATIVE = new Flag.Builder("PARKOUR_CREATIVE", Material.LIGHT)
.addon(this)
.type(Flag.Type.PROTECTION)
.defaultRank(RanksManager.MEMBER_RANK)
.setGameMode(this)
.clickHandler(new CycleClick("PARKOUR_CREATIVE", RanksManager.COOP_RANK, RanksManager.OWNER_RANK)) // exclude visitor
.build();

private ParkourRunRecord parkourRunRecord;

@Override
public void onLoad() {
// Save the default config from config.yml
Expand All @@ -51,26 +74,31 @@ public void onLoad() {
// Chunk generator
chunkGenerator = settings.isUseOwnGenerator() ? null : new ChunkGeneratorWorld(this);
// Register commands
playerCommand = new DefaultPlayerCommand(this)

{
playerCommand = new DefaultPlayerCommand(this) {
@Override
public void setup()
{
public void setup() {
super.setup();
new TopCommand(this);
new CoursesCommand(this);
new SetWarpCommand(this);
new WarpCommand(this);
new RemoveWarpCommand(this);
new ClearTopCommand(this);
new QuitCommand(this);
}
};

adminCommand = new DefaultAdminCommand(this) {};
adminCommand = new DefaultAdminCommand(this) {
};

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

registerFlag(PARKOUR_CREATIVE);

// Register listeners
this.registerListener(new MakeCourseListener(this));
this.registerListener(new CourseRunnerListener(this));

}

private boolean loadSettings() {
Expand Down Expand Up @@ -141,8 +169,9 @@ public void createWorlds() {

/**
* Gets a world or generates a new world if it does not exist
* @param worldName2 - the overworld name
* @param env - the environment
*
* @param worldName2 - the overworld name
* @param env - the environment
* @param chunkGenerator2 - the chunk generator. If <tt>null</tt> then the generator will not be specified
* @return world loaded or generated
*/
Expand Down Expand Up @@ -210,17 +239,25 @@ public void allLoaded() {
}

/**
* @return the pm
* @return the ParkourManager
*/
public ParkourManager getPm() {
public ParkourManager getParkourManager() {
return pm;
}

/**
* @return the rankings
* @return the RankingsUI
*/
public RankingsUI getRankings() {
return rankings;
}

/**
* @return the ParkourRunRecord
*/
public ParkourRunRecord getParkourRunRecord() {
return parkourRunRecord;
}


}
57 changes: 55 additions & 2 deletions src/main/java/world/bentobox/parkour/ParkourManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
Expand All @@ -26,12 +27,14 @@ public class ParkourManager {
* A cache of high scores. Key is island UUID
*/
private final Map<String, ParkourData> cache;
private Parkour addon;

/**
* Handles storing a retrieval of score data for islands
* @param addon Parkour addon
*/
public ParkourManager(Parkour addon) {
this.addon = addon;
// Get the BentoBox database
// Set up the database handler to store and retrieve data
// Note that these are saved by the BentoBox database
Expand All @@ -43,6 +46,9 @@ public ParkourManager(Parkour addon) {
}

private ParkourData getIsland(Island island) {
if (!addon.inWorld(island.getWorld())) {
throw new IllegalArgumentException("Island is not in Parkour world: " + island.getWorld());
}
return cache.computeIfAbsent(island.getUniqueId(), k -> getFromDb(island));
}

Expand Down Expand Up @@ -110,10 +116,10 @@ public Map<UUID, Long> getRankings(Island island, long size) {
}

/**
* Get the rank of the player for this island
* Get the rank of the player for this island. If a
* @param island island
* @param uuid player UUID
* @return rank placing - note - placing of 1 means top ranked
* @return rank placing - 1 means top ranked.
*/
public int getRank(Island island, UUID uuid) {
Stream<Entry<UUID, Long>> stream = getIsland(island).getRankings().entrySet().stream()
Expand All @@ -139,33 +145,80 @@ public Collection<ParkourData> getParkourData() {
return cache.values();
}

/**
* Get the end plate position for the course
* @param island island
* @return position or optional empty
*/
public Optional<Location> getStart(Island island) {
return Optional.ofNullable(getIsland(island).getStart());
}

/**
* Get the end plate position for the course
* @param island island
* @return position or optional empty
*/
public Optional<Location> getEnd(Island island) {
return Optional.ofNullable(getIsland(island).getEnd());
}

/**
* Get the warp spot for island
* @param island island
* @return warp spot or optional empty
*/
public Optional<Location> getWarpSpot(Island island) {
return Optional.ofNullable(getIsland(island).getWarpSpot());
}

/**
* Set the start plate position for island
* @param island island
* @param location position
*/
public void setStart(Island island, Location location) {
getIsland(island).setStart(location);
// Save every time right now
saveIsland(island);
}

/**
* Set the end plate position for island
* @param island island
* @param location position
*/
public void setEnd(Island island, Location location) {
getIsland(island).setEnd(location);
// Save every time right now
saveIsland(island);
}

/**
* Set the warp spot for island
* @param island island
* @param location warp spot
*/
public void setWarpSpot(Island island, Location location) {
getIsland(island).setWarpSpot(location);
// Save every time right now
saveIsland(island);
}

/**
* Get a map of warps to courses
* @return map with the key being the name of the island owner and value being the warp location
*/
public Map<String, Location> getWarps() {
Map<String, Location> map = new HashMap<>();
for (ParkourData pd : getParkourData()) {
if (pd.getWarpSpot() == null) continue;
UUID owner = addon.getIslands().getIslandById(pd.getUniqueId()).map(Island::getOwner).orElse(null);
if (owner != null) {
String name = addon.getPlayers().getName(owner);
map.put(name, pd.getWarpSpot());
}
}
return map;
}
}
18 changes: 18 additions & 0 deletions src/main/java/world/bentobox/parkour/ParkourRunRecord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package world.bentobox.parkour;

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

import org.bukkit.Location;

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

}
24 changes: 24 additions & 0 deletions src/main/java/world/bentobox/parkour/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ public class Settings implements WorldSettings {
@ConfigEntry(path = "world.hidden-flags")
private List<String> hiddenFlags = new ArrayList<>();

@ConfigComment("Allowed commands when running a parkour course - all others are banned")
@ConfigComment("Matched by prefix of command, including '/' - if config is '/parkour home',")
@ConfigComment("'/parkour home abc' is allowed, while '/parkour sethome' is not")
@ConfigEntry(path = "world.parkour-allowed-commands")
private List<String> parkourAllowedCommands = new ArrayList<>();

@ConfigComment("Visitor banned commands - Visitors to areas cannot use these commands in this world")
@ConfigEntry(path = "world.visitor-banned-commands")
private List<String> visitorBannedCommands = new ArrayList<>();
Expand Down Expand Up @@ -683,6 +689,15 @@ public List<String> getHiddenFlags() {
return hiddenFlags;
}

/**
* @return the parkourAllowedCommands
*/
public List<String> getParkourAllowedCommands() {
return parkourAllowedCommands;
}



/**
* @return the visitorBannedCommands
*/
Expand Down Expand Up @@ -1087,6 +1102,15 @@ public void setHiddenFlags(List<String> hiddenFlags) {
this.hiddenFlags = hiddenFlags;
}

/**
* @param parkourAllowedCommands the parkourAllowedCommands to set
*/
public void setParkourAllowedCommands(List<String> parkourAllowedCommands) {
this.parkourAllowedCommands = parkourAllowedCommands;
}



/**
* @param visitorBannedCommands the visitorBannedCommands to set
*/
Expand Down
Loading

0 comments on commit de3fd85

Please sign in to comment.