14 Commits

19 changed files with 343 additions and 38 deletions

View File

@@ -2,6 +2,7 @@ package eu.mhsl.minenet.minigames.instance.game;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace.BlockBreakRaceFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
@@ -38,7 +39,8 @@ public enum GameList {
JUMPDIVE(new JumpDiveFactory(), GameType.JUMPNRUN),
SUMO(new SumoFactory(), GameType.PVP),
HIGHGROUND(new HighGroundFactory(), GameType.PVP),
FASTBRIDGE(new FastbridgeFactory(), GameType.OTHER);
FASTBRIDGE(new FastbridgeFactory(), GameType.OTHER),
BLOCKBREAKRACE(new BlockBreakRaceFactory(), GameType.OTHER);
private final GameFactory factory;
private final GameType type;

View File

@@ -0,0 +1,79 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class BlockBreakRace extends StatelessGame {
private int spawnCount = 0;
private final int height;
public BlockBreakRace(int height) {
super(Dimension.OVERWORLD.key, "blockBreakRace", new FirstWinsScore());
this.height = height;
this.setGenerator(new BlockBreakRaceGenerator(height));
}
@Override
protected boolean onPlayerJoin(Player p) {
PlayerInventory inv = p.getInventory();
inv.addItemStack(ItemStack.of(Material.DIAMOND_PICKAXE));
inv.addItemStack(ItemStack.of(Material.DIAMOND_AXE));
inv.addItemStack(ItemStack.of(Material.DIAMOND_SHOVEL));
return super.onPlayerJoin(p);
}
@Override
protected void onStart() {
this.getPlayers().forEach(player -> player.setGameMode(GameMode.SURVIVAL));
}
@Override
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent event) {
List<Material> allowedMaterials = List.of(Material.STONE, Material.OAK_PLANKS, Material.DIRT);
if(!allowedMaterials.contains(event.getBlock().registry().material())) event.setCancelled(true);
if(this.isBeforeBeginning) event.setCancelled(true);
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(this.isBeforeBeginning) return;
if(playerMoveEvent.getNewPosition().y() < BlockBreakRaceGenerator.BOTTOM_Y) {
Player player = playerMoveEvent.getPlayer();
this.getScore().insertResult(player);
player.setGameMode(GameMode.SPECTATOR);
player.getInventory().clear();
}
}
@Override
public Pos getSpawn() {
int idx = this.spawnCount++;
int cols = BlockBreakRaceGenerator.ROW_OFFSETS_X.length;
int rows = BlockBreakRaceGenerator.ROW_OFFSETS_Z.length;
int perChunk = cols * rows;
int zChunk = idx / perChunk;
int gridIndex = idx % perChunk;
int xIndex = gridIndex % cols;
int zIndex = gridIndex / cols;
int localX = BlockBreakRaceGenerator.ROW_OFFSETS_X[xIndex];
int localZ = BlockBreakRaceGenerator.ROW_OFFSETS_Z[zIndex];
int absZ = (zChunk * 16) + localZ;
return new Pos(localX, BlockBreakRaceGenerator.BOTTOM_Y + this.height + 1, absZ).add(0.5);
}
}

View File

@@ -0,0 +1,40 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace;
import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import net.minestom.server.item.Material;
import java.util.Map;
public class BlockBreakRaceFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_BlockBreakRace#name");
}
@Override
public Material symbol() {
return Material.DIAMOND_PICKAXE;
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_BlockBreakRace#description");
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("height", Material.SCAFFOLDING, TranslatedComponent.byId("optionCommon#height"), 20, 30, 40, 50));
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new BlockBreakRace(configuration.get("height").getAsInt()).setParent(parent);
}
}

View File

@@ -0,0 +1,67 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace;
import eu.mhsl.minenet.minigames.world.generator.featureEnriched.ValeGenerator;
import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.generator.GenerationUnit;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public class BlockBreakRaceGenerator extends BaseGenerator {
public static final int BOTTOM_Y = 50;
public final int TOP_Y;
public static final int[] ROW_OFFSETS_X = {4, 8, 12};
public static final int[] ROW_OFFSETS_Z = {4, 8, 12};
private static final Block[] FILL_BLOCKS = {
Block.STONE,
Block.DIRT,
Block.OAK_PLANKS
};
private final Random random = ThreadLocalRandom.current();
public BlockBreakRaceGenerator(int height) {
this.TOP_Y = BOTTOM_Y + height;
ValeGenerator vale = new ValeGenerator();
vale.setXShiftMultiplier(i -> 0.5d);
vale.setHeightNoiseMultiplier(i -> 2);
vale.setXShiftOffset(i -> 40d);
this.addMixIn(vale);
this.addMixIn(unit -> {
if(unit.absoluteStart().chunkX() != 0) return;
for (int localX : ROW_OFFSETS_X) {
for (int localZ : ROW_OFFSETS_Z) {
final int absZ = unit.absoluteStart().blockZ() + localZ;
this.placeTube(unit, localX, absZ);
}
}
});
}
private void placeTube(GenerationUnit unit, int x, int z) {
for (int y = BOTTOM_Y; y < this.TOP_Y; y++) {
Block fill = FILL_BLOCKS[this.random.nextInt(FILL_BLOCKS.length)];
unit.modifier().fill(
new Pos(x, y, z),
new Pos(x, y, z).add(1),
fill
);
}
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
if (dx == 0 && dz == 0) continue; // Zentrum überspringen
unit.modifier().fill(
new Pos(x + dx, BOTTOM_Y, z + dz),
new Pos(x + dx, this.TOP_Y + 3, z + dz).add(1),
Block.BARRIER
);
}
}
}
}

View File

@@ -3,6 +3,8 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef;
import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MinimalPlayeramountGameRestriction;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import net.minestom.server.item.Material;
@@ -29,4 +31,10 @@ public class BowSpleefFactory implements GameFactory {
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new BowSpleef().setParent(parent);
}
@Override
public RestrictionHandler globalRestrictions() {
return new RestrictionHandler()
.addRestriction(new MinimalPlayeramountGameRestriction(2));
}
}

View File

@@ -8,7 +8,7 @@ import eu.mhsl.minenet.minigames.world.BlockPallet;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import io.github.togar2.pvp.feature.CombatFeatures;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.GameMode;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import org.jetbrains.annotations.NotNull;
@@ -69,7 +69,9 @@ class Deathcube extends StatelessGame {
playerMoveEvent.setCancelled(true);
return;
}
if(playerMoveEvent.getNewPosition().y() > height) getScore().insertResult(playerMoveEvent.getPlayer());
if(playerMoveEvent.getNewPosition().y() <= height) return;
getScore().insertResult(playerMoveEvent.getPlayer());
playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
}
@Override

View File

@@ -33,6 +33,7 @@ import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
@@ -183,7 +184,8 @@ public class ElytraRace extends StatelessGame {
}
private Point getRingPositionAtZ(int z) {
return new Pos(vale.getXShiftAtZ(z), -45, z);
Random random = new Random(this.hashCode() + z);
return new Pos(vale.getXShiftAtZ(z), -45 + random.nextInt(-5, 15), z);
}
private CompletableFuture<Void> generateRing(int zPos) {

View File

@@ -5,6 +5,8 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MinimalPlayeramountGameRestriction;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import net.minestom.server.item.Material;
@@ -38,4 +40,10 @@ public class HighGroundFactory implements GameFactory {
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new HighGround(configuration.get("radius").getAsInt(), configuration.get("seconds").getAsInt()).setParent(parent);
}
@Override
public RestrictionHandler globalRestrictions() {
return new RestrictionHandler()
.addRestriction(new MinimalPlayeramountGameRestriction(2));
}
}

View File

@@ -9,6 +9,7 @@ import eu.mhsl.minenet.minigames.world.BlockPallet;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.event.player.PlayerStartDiggingEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
@@ -77,6 +78,15 @@ public class Spleef extends StatelessGame {
}
}
@Override
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent event) {
if(!isRunning) {
event.setCancelled(true);
return;
}
setBlock(event.getBlockPosition(), Block.AIR);
}
private void destroyBlock(PlayerStartDiggingEvent event) {
if(!isRunning) return;
setBlock(event.getBlockPosition(), Block.AIR);

View File

@@ -2,7 +2,7 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.LastWinsScore;
import eu.mhsl.minenet.minigames.score.LowestPointsWinScore;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures;
@@ -13,15 +13,17 @@ import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
public class Stickfight extends StatelessGame {
private final double radius = 20;
private final WeakHashMap<Player, Pos> spawnPoints = new WeakHashMap<>();
private final Map<Player, Integer> scoreMap = new WeakHashMap<>();
public Stickfight() {
super(Dimension.OVERWORLD.key, "Stickfight", new LastWinsScore());
super(Dimension.OVERWORLD.key, "Stickfight", new LowestPointsWinScore());
eventNode().addChild(
CombatFeatures.empty()
@@ -66,6 +68,11 @@ public class Stickfight extends StatelessGame {
super.start();
}
@Override
protected void onStop() {
this.scoreMap.forEach((player, score) -> getScore().insertResult(player, score));
}
private void generateBridge(int startX, int startY, int startZ) {
int steps = (int) (radius * 1.5);
for (int i = 0; i < steps; i++) {
@@ -78,19 +85,22 @@ public class Stickfight extends StatelessGame {
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(!spawnPoints.containsKey(playerMoveEvent.getPlayer())) {
Player player = playerMoveEvent.getPlayer();
if(!spawnPoints.containsKey(player)) {
playerMoveEvent.setCancelled(true);
return;
}
if(isBeforeBeginning) {
if(spawnPoints.get(playerMoveEvent.getPlayer()).distance(playerMoveEvent.getNewPosition()) < 1) return;
if(spawnPoints.get(player).distance(playerMoveEvent.getNewPosition()) < 1) return;
playerMoveEvent.setCancelled(true);
playerMoveEvent.getPlayer().teleport(spawnPoints.get(playerMoveEvent.getPlayer()));
player.teleport(spawnPoints.get(player));
}
if(playerMoveEvent.getNewPosition().y() < 40) {
playerMoveEvent.getPlayer().teleport(spawnPoints.get(playerMoveEvent.getPlayer()));
player.teleport(spawnPoints.get(player));
this.scoreMap.putIfAbsent(player, 0);
this.scoreMap.put(player, this.scoreMap.get(player) + 1);
}
}

View File

@@ -5,6 +5,8 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MinimalPlayeramountGameRestriction;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import net.minestom.server.item.Material;
@@ -38,4 +40,10 @@ public class SumoFactory implements GameFactory {
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new Sumo(configuration.get("radius").getAsInt(), configuration.get("health").getAsInt(), configuration.get("seconds").getAsInt()).setParent(parent);
}
@Override
public RestrictionHandler globalRestrictions() {
return new RestrictionHandler()
.addRestriction(new MinimalPlayeramountGameRestriction(2));
}
}

View File

@@ -112,9 +112,11 @@ class Tetris extends StatelessGame {
private void letPlayerLoose(Player player) {
TetrisGame tetrisGame = this.tetrisGames.get(player);
if(!this.getScore().hasResult(player)) {
player.setGameMode(GameMode.SPECTATOR);
player.setInvisible(true);
this.getScore().insertResult(player, tetrisGame.getScore());
}
boolean allGamesLost = this.tetrisGames.values().stream()
.filter(game -> !game.lost)

View File

@@ -156,6 +156,7 @@ class TrafficLightRace extends StatelessGame {
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(isBeforeBeginning) return;
if(getScore().hasResult(playerMoveEvent.getPlayer())) return;
if(phase.equals(LightPhase.RED) && playerMoveEvent.getNewPosition().z()-0.01 > playerMoveEvent.getPlayer().getPosition().z()) {
playerMoveEvent.getPlayer().setVelocity(new Vec(0, 8, -15));

View File

@@ -0,0 +1,29 @@
package eu.mhsl.minenet.minigames.score;
import eu.mhsl.minenet.minigames.util.MapUtil;
import net.minestom.server.entity.Player;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public class LowestPointsWinScore extends PointsWinScore {
@Override
protected void insertResultImplementation(Set<Player> p, int currentPoints) {
Set<Player> combined = scoreOrder.entrySet().stream()
.filter(entrySet -> Objects.equals(entrySet.getValue(), currentPoints))
.map(Map.Entry::getKey)
.findFirst()
.orElseGet(() -> {
Set<Player> s = new HashSet<>();
scoreOrder.put(s, currentPoints);
return s;
});
combined.addAll(p);
this.scoreOrder = MapUtil.sortReversedByValue(this.scoreOrder);
getScores().clear();
this.scoreOrder.forEach((player, integer) -> getScores().addFirst(player));
}
}

View File

@@ -12,11 +12,21 @@ import java.util.*;
import java.util.stream.Collectors;
public class PointsWinScore extends Score {
private Map<Set<Player>, Integer> scoreOrder = new HashMap<>();
Map<Set<Player>, Integer> scoreOrder = new HashMap<>();
@Override
protected void insertResultImplementation(Set<Player> p, int currentPoints) {
this.scoreOrder.put(p, currentPoints);
Set<Player> combined = scoreOrder.entrySet().stream()
.filter(entrySet -> Objects.equals(entrySet.getValue(), currentPoints))
.map(Map.Entry::getKey)
.findFirst()
.orElseGet(() -> {
Set<Player> s = new HashSet<>();
scoreOrder.put(s, currentPoints);
return s;
});
combined.addAll(p);
this.scoreOrder = MapUtil.sortByValue(this.scoreOrder);
getScores().clear();
this.scoreOrder.forEach((player, integer) -> getScores().addFirst(player));
@@ -42,13 +52,12 @@ public class PointsWinScore extends Score {
.filter(player -> !player.getUsername().isBlank())
.toList()
.isEmpty())
.map(players -> players
.stream()
.filter(player -> scoreOrder.get(Set.of(player)) != null)
.map(player -> player.getUsername()+" : "+scoreOrder.get(Set.of(player)).toString())
.map(players -> players.stream()
.map(Player::getUsername)
.sorted()
.collect(Collectors.joining(", "))
)
.toList()
+ " : " + scoreOrder.get(players)
).toList()
)
.undent()
.newLine()

View File

@@ -4,6 +4,7 @@ import eu.mhsl.minenet.minigames.score.Score;
import net.minestom.server.entity.Player;
import java.util.*;
import java.util.stream.Collectors;
public class Tournament {
private final List<Score> gameScores = new ArrayList<>();
@@ -43,9 +44,11 @@ public class Tournament {
public Rewards getRewards() {
Map<UUID, Integer> itemCount = new HashMap<>();
int count = 0;
for (Player player : getPlaces()) {
for (Set<Player> players : getPlaces()) {
if(count >= this.rewardConfiguration.rewardCount().size()) break;
for(Player player : players) {
itemCount.put(player.getUuid(), this.rewardConfiguration.rewardCount().get(count));
}
count++;
}
@@ -53,18 +56,21 @@ public class Tournament {
this.memorialConfiguration.memorialMaterial().namespace().value(),
this.memorialConfiguration.memorialTitle(),
this.memorialConfiguration.memorialLore(),
getPlaces().stream().map(Player::getUuid).toList(),
getGameScores().keySet().stream().map(Player::getUuid).toList(),
this.rewardConfiguration.item().namespace().value(),
itemCount
);
}
public List<Player> getPlaces() {
List<Player> players = new ArrayList<>(
public List<Set<Player>> getPlaces() {
List<Set<Player>> players = new ArrayList<>(
getGameScores().entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.toList()
.collect(
Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toSet())
)
).values()
);
Collections.reverse(players);

View File

@@ -12,10 +12,12 @@ import net.minestom.server.entity.*;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.anvil.AnvilLoader;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
public class TournamentDisplay extends MineNetInstance implements Spawnable {
private final List<Player> places;
private final List<Set<Player>> places;
private final Tournament tournament;
private final Pos[] placePositions = new Pos[] {
@@ -30,7 +32,7 @@ public class TournamentDisplay extends MineNetInstance implements Spawnable {
this.places = tournament.getPlaces();
this.tournament = tournament;
this.places.forEach(player -> player.setGameMode(GameMode.ADVENTURE));
this.places.forEach(players -> players.forEach(player -> player.setGameMode(GameMode.ADVENTURE)));
eventNode().addListener(PlayerMoveEvent.class, playerMoveEvent -> {
if(isOnDisplay(playerMoveEvent.getPlayer()) && !playerMoveEvent.getNewPosition().sameBlock(placePositions[getRankPosition(playerMoveEvent.getPlayer())])) {
@@ -45,7 +47,10 @@ public class TournamentDisplay extends MineNetInstance implements Spawnable {
}
private int getRankPosition(Player player) {
return this.places.indexOf(player);
for (int i = 0; i < places.size(); i++) {
if (places.get(i).contains(player)) return i;
}
return -1;
}
@Override
@@ -56,8 +61,11 @@ public class TournamentDisplay extends MineNetInstance implements Spawnable {
p.teleport(placePositions[getRankPosition(p)]);
}
});
List<Player> players = this.places.stream()
.flatMap(s -> s.stream().sorted(Comparator.comparing(Player::getUsername)))
.toList();
new ChatMessage(Icon.STAR)
.numberedList(this.places.stream().map(player -> String.format("%s - %s Punkte", player.getUsername(), tournament.getGameScores().get(player))).toList())
.list(players.stream().map(player -> String.format("%d. %s - %s Punkte", this.getRankPosition(player)+1, player.getUsername(), tournament.getGameScores().get(player))).toList())
.send(p);
return false;
}

View File

@@ -1,9 +1,6 @@
package eu.mhsl.minenet.minigames.util;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class MapUtil {
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
@@ -17,4 +14,16 @@ public class MapUtil {
return result;
}
public static <K, V extends Comparable<? super V>> Map<K, V> sortReversedByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
list.sort(Map.Entry.<K, V>comparingByValue().reversed());
Map<K, V> result = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
}

View File

@@ -143,3 +143,8 @@ description;Stay on the high ground to win!;Bleibe solange wie möglich auf der
ns:game_Fastbridge#;;
name;Fastbridge;Fastbridge
description;Speedbridge to the other platform. The first one there wins!;Baue dich so schnell wie möglich zur anderen Plattform. Wer zuerst dort ist, gewinnt!
;;
ns:game_BlockBreakRace#;;
name;Block Break Race;Blockbruch-Rennen
description;Dig down through the tubes using the right tools. The first player to reach the bottom wins!;Grabe dich durch die Röhren nach unten und verwende dabei das richtige Werkzeug. Wer zuerst unten ankommt, gewinnt!
;;
1 map en_us de_de
143 ns:game_Fastbridge#
144 name Fastbridge Fastbridge
145 description Speedbridge to the other platform. The first one there wins! Baue dich so schnell wie möglich zur anderen Plattform. Wer zuerst dort ist, gewinnt!
146
147 ns:game_BlockBreakRace#
148 name Block Break Race Blockbruch-Rennen
149 description Dig down through the tubes using the right tools. The first player to reach the bottom wins! Grabe dich durch die Röhren nach unten und verwende dabei das richtige Werkzeug. Wer zuerst unten ankommt, gewinnt!
150