Skip to content

Commit

Permalink
Add leaderboard and fence jumps
Browse files Browse the repository at this point in the history
  • Loading branch information
Efnilite committed Jan 4, 2021
1 parent d497e06 commit 86a15d2
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 20 deletions.
132 changes: 118 additions & 14 deletions src/main/java/dev/efnilite/witp/ParkourPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import dev.efnilite.witp.util.inventory.ItemBuilder;
import dev.efnilite.witp.util.task.Tasks;
import fr.mrmicky.fastboard.FastBoard;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
Expand Down Expand Up @@ -59,7 +61,7 @@ public class ParkourPlayer {
private final Player player;
private final ParkourGenerator generator;
private static final HashMap<Player, ParkourPlayer> players = new HashMap<>();
private static final HashMap<Integer, UUID> highScores = new HashMap<>();
private static HashMap<UUID, Integer> highScores = new LinkedHashMap<>();
private static final Gson gson = new GsonBuilder().disableHtmlEscaping().excludeFieldsWithoutExposeAnnotation().create();

/**
Expand Down Expand Up @@ -103,6 +105,15 @@ public ParkourPlayer(@NotNull Player player, int highScore, String time, String
if (player.isOp() && WITP.isOutdated) {
send("&4&l!!! &fThe WITP plugin version you are using is outdated. Please check the Spigot page for updates.");
}
if (highScores.size() == 0) {
try {
fetchHighScores();
} catch (IOException ex) {
ex.printStackTrace();
Verbose.error("Error while trying to fetch the high scores!");
}
highScores = Util.sortByValue(highScores);
}
}


Expand Down Expand Up @@ -185,7 +196,7 @@ public void setStyle(String style) {
*/
public void setHighScore(int score) {
this.highScore = score;
highScores.put(score, player.getUniqueId());
highScores.put(player.getUniqueId(), score);
saveStats();
}

Expand Down Expand Up @@ -327,6 +338,11 @@ public void menu() {
saveStats();
player.closeInventory();
});
builder.setItem(22, new ItemBuilder(Material.GOLD_BLOCK, "&6&lLeaderboard")
.setLore("&7Your rank: &f#" + getRank(player.getUniqueId()) + " &7(" + highScores.get(player.getUniqueId()) + ")").build(), (t2, e2) -> {
scoreboard(1);
player.closeInventory();
});
builder.setItem(26, new ItemBuilder(Material.BARRIER, "&4&lQuit").build(), (t2, e2) -> {
try {
ParkourPlayer.unregister(this, true);
Expand Down Expand Up @@ -405,6 +421,93 @@ public void send(@NotNull String... messages) {
}
}

/**
* Shows the scoreboard (as a chat message)
*/
public void scoreboard(int page) {
if (highScores.size() == 0) {
try {
fetchHighScores();
} catch (IOException ex) {
ex.printStackTrace();
Verbose.error("Error while trying to fetch the high scores!");
}
}

int lowest = page * 10;
int highest = (page - 1) * 10;
if (page < 1) {
return;
}
if (page > 1 && highest > highScores.size()) {
return;
}

HashMap<UUID, Integer> sorted = Util.sortByValue(highScores);
highScores = sorted;
List<UUID> uuids = new ArrayList<>(sorted.keySet());

send("", "", "", "", "", "", "", "");
send("&7----------------------------------------");
for (int i = highest; i < lowest; i++) {
if (i == uuids.size()) {
break;
}
UUID uuid = uuids.get(i);
if (uuid == null) {
continue;
}
String name = Bukkit.getOfflinePlayer(uuid).getName();
int rank = i + 1;
send("&c#" + rank + ". &7" + name + " &f- " + highScores.get(uuid));
}
send("&7Your rank: &f#" + getRank(player.getUniqueId()) + " &7(" + highScores.get(player.getUniqueId()) + ")");
send("");

int prevPage = page - 1;
int nextPage = page + 1;
BaseComponent[] previous = new ComponentBuilder()
.append("<< Previous page").color(net.md_5.bungee.api.ChatColor.RED)
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/witp leaderboard " + prevPage))
.append(" | ").color(net.md_5.bungee.api.ChatColor.GRAY)
.event((ClickEvent) null)
.append("Next page >>").color(net.md_5.bungee.api.ChatColor.RED)
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/witp leaderboard " + nextPage))
.create();

player.spigot().sendMessage(previous);
send("&7----------------------------------------");
}

/**
* Gets the high score of a player
*
* @param player
* The player
*
* @return the high score of the player
*/
public static int getHighScore(@NotNull UUID player) {
return highScores.get(player);
}

/**
* Gets the player at a certain place
* Note: places are indicated in normal fashion (a.k.a. #1 is the first)
*
* @param place
* The place
*
* @return the player at that place
*/
public static UUID getAtPlace(int place) {
return new ArrayList<>(highScores.keySet()).get(place);
}

private int getRank(UUID player) {
return new ArrayList<>(highScores.keySet()).indexOf(player) + 1;
}

/**
* Registers a player
*
Expand Down Expand Up @@ -463,7 +566,8 @@ public static void fetchHighScores() throws IOException {
for (File file : folder.listFiles()) {
FileReader reader = new FileReader(file);
ParkourPlayer from = gson.fromJson(reader, ParkourPlayer.class);
highScores.put(from.highScore, UUID.fromString(file.getName()));
String name = file.getName();
highScores.put(UUID.fromString(name.substring(0, name.lastIndexOf('.'))), from.highScore);
}
}

Expand Down Expand Up @@ -540,14 +644,6 @@ public static void unregister(@NotNull ParkourPlayer player, boolean sendBack) t
}
}

public HashMap<Integer, ItemStack> getPreviousInventory() {
return previousInventory;
}

public Location getPreviousLocation() {
return previousLocation;
}

/**
* Gets the player's {@link ParkourGenerator}
*
Expand All @@ -565,4 +661,12 @@ public ParkourGenerator getGenerator() {
public @NotNull Player getPlayer() {
return player;
}

public HashMap<Integer, ItemStack> getPreviousInventory() {
return previousInventory;
}

public Location getPreviousLocation() {
return previousLocation;
}
}
10 changes: 9 additions & 1 deletion src/main/java/dev/efnilite/witp/command/MainCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,16 @@ public boolean execute(Player player, String[] args) {
pp.menu();
}
}
} else if (args.length == 2) {
if (args[0].equalsIgnoreCase("leaderboard") && args[1] != null) {
int page = Integer.parseInt(args[1]);
ParkourPlayer pp = ParkourPlayer.getPlayer(player);
if (pp != null) {
pp.scoreboard(page);
}
}
}
return false;
return true;
}

@Override
Expand Down
22 changes: 19 additions & 3 deletions src/main/java/dev/efnilite/witp/generator/ParkourGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.util.*;
Expand Down Expand Up @@ -390,30 +391,43 @@ public void generateNext() {
specialChances.put(index, 2);
index++;
}
for (int i = 0; i < Configurable.SPECIAL_FENCE; i++) {
specialChances.put(index, 3);
index++;
}
}

int spec = specialChances.get(random.nextInt(specialChances.size() - 1));
int spec = specialChances.get(random.nextInt(specialChances.size()));
switch (spec) {
case 0: // ice
material = Material.PACKED_ICE.createBlockData();
gap++;
break;
case 1: // slab
material = Material.SMOOTH_QUARTZ_SLAB.createBlockData();
height = 0; // todo allow multiple heights
height = Math.min(height, 0);
((Slab) material).setType(Slab.Type.BOTTOM);
break;
case 2: // pane
material = Material.GLASS_PANE.createBlockData();
gap -= 0.5;
break;
case 3:
material = Material.OAK_FENCE.createBlockData();
height = Math.min(height, 0);
gap -= 0.5;
break;
}
}

Location local = lastSpawn.clone();
if (local.getBlock().getType() == Material.SMOOTH_QUARTZ_SLAB) {
height = Math.min(height, 0);
}
List<Block> possible = getPossible(gap - height, height);
if (possible.size() == 0) {
lastSpawn = local.clone();
Verbose.error(lastSpawn.toString());
return;
}

Expand Down Expand Up @@ -451,7 +465,7 @@ public void generateNext() {
Location local2 = lastSpawn.clone();
List<Block> possibleStructure = getPossible(gapStructure, 0);
if (possibleStructure.size() == 0) {
lastSpawn = local2;
lastSpawn = local2.clone();
return;
}
Block chosenStructure = possibleStructure.get(random.nextInt(possibleStructure.size()));
Expand Down Expand Up @@ -574,6 +588,7 @@ public static class Configurable {
public static int SPECIAL_ICE;
public static int SPECIAL_SLAB;
public static int SPECIAL_PANE;
public static int SPECIAL_FENCE;

public static int NORMAL_ONE_BLOCK;
public static int NORMAL_TWO_BLOCK;
Expand Down Expand Up @@ -622,6 +637,7 @@ public static void init() {
SPECIAL_ICE = file.getInt("generation.normal-jump.special.ice");
SPECIAL_SLAB = file.getInt("generation.normal-jump.special.slab");
SPECIAL_PANE = file.getInt("generation.normal-jump.special.pane");
SPECIAL_FENCE = file.getInt("generation.normal-jump.special.fence");

NORMAL_ONE_BLOCK = file.getInt("generation.normal-jump.1-block");
NORMAL_TWO_BLOCK = file.getInt("generation.normal-jump.2-block");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ private void fetchPossibleInLayer() {
world.setGameRule(GameRule.DO_TILE_DROPS, false);
world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false);
world.setGameRule(GameRule.DO_WEATHER_CYCLE, false);
world.setGameRule(GameRule.LOG_ADMIN_COMMANDS, false);
world.setWeatherDuration(1000);
world.setDifficulty(Difficulty.PEACEFUL);
world.setAutoSave(false);
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/dev/efnilite/witp/hook/PlaceholderHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import dev.efnilite.witp.ParkourPlayer;
import dev.efnilite.witp.WITP;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -65,6 +67,15 @@ public String onPlaceholderRequest(Player player, @NotNull String params) {
case "time_pref":
case "time_preference":
return pp.time;
case "leader":
case "rank_one":
case "record_player":
return Bukkit.getOfflinePlayer(ParkourPlayer.getAtPlace(1)).getName();
case "leader_score":
case "rank_one_score":
case "record_score":
case "record":
return Integer.toString(ParkourPlayer.getHighScore(ParkourPlayer.getAtPlace(1)));
}

return null;
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/dev/efnilite/witp/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ public class Util {

private static Economy economy;

/**
* Sorts a HashMap by value
* Source: https://stackoverflow.com/questions/109383/sort-a-mapkey-value-by-values
*
* @return a sorted HashMap
*/
public static <K, V extends Comparable<? super V>> HashMap<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
list.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));

HashMap<K, V> result = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}

return result;
}

/**
* Deposits money to a player using Vault
*
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/generation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ generation:
chance: 10

# The type of block
ice: 60
ice: 50
slab: 30 # for bottom-side half slabs
pane: 10 # for glass panes
fence: 10

# The settings for structures
structures:
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: 'WITP'
description: 'Automatically generating, infinitely long parkour plugin. The sky, and your time, is the limit. The further you go, the harder it gets. Should be a walk in the park, right?'
author: Efnilite, Ice_Pancake
version: 1.5a
version: 1.6
api-version: 1.16
main: dev.efnilite.witp.WITP
softdepend: [Vault, PlaceholderAPI]
Expand Down

0 comments on commit 86a15d2

Please sign in to comment.