1 Commits

Author SHA1 Message Date
535008a31e startet implementation of buildBattle 2025-04-11 10:21:59 +02:00
36 changed files with 125 additions and 981 deletions

View File

@@ -48,7 +48,7 @@ dependencies {
//Tools //Tools
implementation 'de.articdive:jnoise:3.0.2' implementation 'de.articdive:jnoise:3.0.2'
implementation 'net.md-5:bungeecord-config:1.21-R0.3' implementation 'net.md-5:bungeecord-config:1.19-R0.1-SNAPSHOT'
implementation 'org.apache.commons:commons-text:1.10.0' implementation 'org.apache.commons:commons-text:1.10.0'
implementation 'org.spongepowered:configurate-yaml:4.1.2' implementation 'org.spongepowered:configurate-yaml:4.1.2'
implementation 'com.sparkjava:spark-core:2.9.4' implementation 'com.sparkjava:spark-core:2.9.4'

View File

@@ -2,21 +2,18 @@ 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.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory; 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.bowSpleef.BowSpleefFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle.BuildBattleFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain.AcidRainFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain.AcidRainFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge.FastbridgeFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.highGround.HighGroundFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive.JumpDiveFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive.JumpDiveFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun.MinerunFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun.MinerunFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef.SpleefFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef.SpleefFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight.StickFightFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight.StickFightFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.TetrisFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.TetrisFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.sumo.SumoFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tntrun.TntRunFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.tntrun.TntRunFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.TowerdefenseFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.TowerdefenseFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace.TrafficLightRaceFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace.TrafficLightRaceFactory;
@@ -37,10 +34,7 @@ public enum GameList {
ELYTRARACE(new ElytraRaceFactory(), GameType.PVP), ELYTRARACE(new ElytraRaceFactory(), GameType.PVP),
SPLEEF(new SpleefFactory(), GameType.PVP), SPLEEF(new SpleefFactory(), GameType.PVP),
JUMPDIVE(new JumpDiveFactory(), GameType.JUMPNRUN), JUMPDIVE(new JumpDiveFactory(), GameType.JUMPNRUN),
SUMO(new SumoFactory(), GameType.PVP), BUILDBATTLE(new BuildBattleFactory(), GameType.OTHER);
HIGHGROUND(new HighGroundFactory(), GameType.PVP),
FASTBRIDGE(new FastbridgeFactory(), GameType.OTHER),
BLOCKBREAKRACE(new BlockBreakRaceFactory(), GameType.OTHER);
private final GameFactory factory; private final GameFactory factory;
private final GameType type; private final GameType type;
@@ -53,6 +47,6 @@ public enum GameList {
} }
public GameType getType() { public GameType getType() {
return this.type; return type;
} }
} }

View File

@@ -26,7 +26,7 @@ public class AnvilRunFactory implements GameFactory {
public ConfigManager configuration() { public ConfigManager configuration() {
return new ConfigManager() return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 5, 10, 15, 20, 25, 30)) .addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 5, 10, 15, 20, 25, 30))
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 10, 30, 60, 90, 120)); .addOption(new NumericOption("seconds", Material.STICK, TranslatedComponent.byId("optionCommon#seconds"), 10, 30, 60, 90, 120));
} }
@Override @Override

View File

@@ -1,79 +0,0 @@
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

@@ -1,40 +0,0 @@
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

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

View File

@@ -0,0 +1,13 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.NoScore;
public class BuildBattle extends StatelessGame {
public BuildBattle() {
super(Dimension.OVERWORLD.key, "buildBattle", new NoScore());
}
}

View File

@@ -1,33 +1,21 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge; package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle;
import eu.mhsl.minenet.minigames.instance.game.Game; 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.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option; import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent; import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import net.minestom.server.item.Material;
import java.util.Map; import java.util.Map;
public class FastbridgeFactory implements GameFactory { public class BuildBattleFactory implements GameFactory {
@Override @Override
public TranslatedComponent name() { public TranslatedComponent name() {
return TranslatedComponent.byId("game_Fastbridge#name"); return TranslatedComponent.byId("game_BuildBattle#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_Fastbridge#description");
}
@Override
public Material symbol() {
return Material.WHITE_WOOL;
} }
@Override @Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception { public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new Fastbridge().setParent(parent); return new BuildBattle();
} }
} }

View File

@@ -0,0 +1,12 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.Score;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.world.DimensionType;
class BuilderWorld extends StatelessGame {
public BuilderWorld(DynamicRegistry.Key<DimensionType> dimensionType, String gameName, Score score) {
super(dimensionType, gameName, score);
}
}

View File

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

View File

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

View File

@@ -1,64 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge;
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.PlayerBlockPlaceEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class Fastbridge extends StatelessGame {
private int currentSpawn = 0;
public Fastbridge() {
super(Dimension.OVERWORLD.key, "Fastbridge", new FirstWinsScore());
this.setGenerator(new FastbridgeChunkgenerator());
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player player = playerMoveEvent.getPlayer();
Pos newPos = playerMoveEvent.getNewPosition();
if(this.getScore().hasResult(player)) return;
if(newPos.y() < 0) {
player.teleport(getSpawn());
if(!isBeforeBeginning) this.resetPlayer(player);
}
if(newPos.x() > 53) {
this.getScore().insertResult(player);
player.setGameMode(GameMode.SPECTATOR);
}
}
@Override
protected void onStart() {
getPlayers().forEach(player -> {
player.setGameMode(GameMode.SURVIVAL);
resetPlayer(player);
});
}
@Override
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {
if(isBeforeBeginning) playerBlockPlaceEvent.setCancelled(true);
}
private void resetPlayer(Player player) {
if(isBeforeBeginning) return;
PlayerInventory inventory = player.getInventory();
inventory.clear();
inventory.addItemStack(ItemStack.of(Material.WHITE_WOOL, 64));
}
@Override
public synchronized Pos getSpawn() {
return new Pos(24, 1, currentSpawn++*Chunk.CHUNK_SIZE_Z*2-8, -90, 0);
}
}

View File

@@ -1,29 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge;
import eu.mhsl.minenet.minigames.world.generator.featureEnriched.ValeGenerator;
import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator;
import net.minestom.server.instance.block.Block;
public class FastbridgeChunkgenerator extends BaseGenerator {
public FastbridgeChunkgenerator() {
this.addMixIn(unit -> {
if (unit.absoluteStart().chunkZ() % 2 == 0) {
unit.modifier().fill(Block.BARRIER);
return;
}
if (unit.absoluteStart().chunkX() != 1 && unit.absoluteStart().chunkX() != 3) return;
for (int x = 5; x <= 10; x++){
for (int z = 5; z <= 10; z++){
unit.modifier().setRelative(x, 64, z, unit.absoluteStart().chunkX() == 3 ? Block.GOLD_BLOCK : Block.GRASS_BLOCK);
}
}
});
ValeGenerator vale = new ValeGenerator();
vale.setXShiftMultiplier(integer -> 0.5d);
vale.setHeightNoiseMultiplier(integer -> 2);
vale.setXShiftOffset(integer -> 40d);
this.addMixIn(vale);
}
}

View File

@@ -1,126 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.highGround;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.PointsWinScore;
import eu.mhsl.minenet.minigames.world.BlockPallet;
import io.github.togar2.pvp.events.EntityKnockbackEvent;
import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.events.PrepareAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.event.instance.InstanceTickEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
class HighGround extends StatelessGame {
private final int radius;
private final int seconds;
private final WeakHashMap<Player, Integer> scoreMap = new WeakHashMap<>();
HighGround(int radius, int seconds) {
super(Dimension.THE_END.key, "highground", new PointsWinScore());
this.radius = radius;
this.seconds = seconds;
this.eventNode().addChild(
CombatFeatures.empty()
.add(CombatFeatures.VANILLA_ATTACK)
.add(CombatFeatures.VANILLA_DAMAGE)
.add(CombatFeatures.VANILLA_KNOCKBACK)
.build()
.createNode()
);
this.eventNode().addListener(
FinalAttackEvent.class,
finalAttackEvent -> finalAttackEvent.setBaseDamage(0)
);
this.eventNode().addListener(PrepareAttackEvent.class, prepareAttackEvent -> {
if(this.isBeforeBeginning){
prepareAttackEvent.setCancelled(true);
}
});
this.eventNode().addListener(
EntityKnockbackEvent.class,
entityKnockbackEvent -> entityKnockbackEvent.setStrength(1.1f)
);
this.eventNode().addListener(InstanceTickEvent.class, instanceTickEvent -> {
if (this.isBeforeBeginning || !this.isRunning) return;
this.getPlayers().forEach(player -> {
if((player.isOnGround() && player.getPosition().y() >= 1) || (!player.isOnGround() && player.getPosition().y() >= 1.5)){
this.scoreMap.put(player, this.scoreMap.get(player) + 1);
player.setLevel(this.scoreMap.get(player) / 20);
player.setExp((this.scoreMap.get(player) % 20) / 20.0f);
}
});
});
}
@Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
for (int y = 0; y >= -3; y--) {
int radius = (Math.abs(y) * 5) + this.radius;
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
double distance = new Pos(x, 0, z).distance(0, 0, 0);
if (distance <= radius) {
this.setBlock(x, y, z, y == 0 ? Block.DIAMOND_BLOCK : Block.GRASS_BLOCK);
Pos featurePosition = new Pos(x, y + 1, z);
if(y >= 0 || this.getBlock(featurePosition).isSolid()) continue;
if (this.rnd.nextDouble() < 0.1){
this.setBlock(featurePosition, Block.SHORT_GRASS);
}
if (this.rnd.nextDouble() < 0.01){
this.setBlock(featurePosition, BlockPallet.FLOWER.rnd());
}
}
}
}
}
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player player = playerMoveEvent.getPlayer();
if(playerMoveEvent.getNewPosition().y() < -10){
player.teleport(this.getSpawn());
}
}
@Override
protected void start() {
this.getPlayers().forEach(player -> this.scoreMap.put(player, 0));
super.start();
}
@Override
protected void onStart() {
this.setTimeLimit(this.seconds);
}
@Override
protected void onStop() {
this.getPlayers().forEach(player -> this.getScore().insertResult(player, this.scoreMap.get(player)));
}
@Override
public Pos getSpawn() {
double theta = this.rnd.nextDouble() * 2 * Math.PI;
double spawnRadius = this.radius + 5;
double x = spawnRadius * Math.cos(theta);
double z = spawnRadius * Math.sin(theta);
return new Pos(x, 0, z).withLookAt(new Pos(0, 0, 0));
}
}

View File

@@ -1,49 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.highGround;
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.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;
import java.util.Map;
public class HighGroundFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_Highground#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_Highground#description");
}
@Override
public Material symbol() {
return Material.GOLDEN_HELMET;
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 3, 5, 7, 10))
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 30, 60, 90, 120));
}
@Override
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,7 +9,6 @@ import eu.mhsl.minenet.minigames.world.BlockPallet;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode; 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.PlayerMoveEvent;
import net.minestom.server.event.player.PlayerStartDiggingEvent; import net.minestom.server.event.player.PlayerStartDiggingEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch; import net.minestom.server.instance.batch.AbsoluteBlockBatch;
@@ -78,15 +77,6 @@ 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) { private void destroyBlock(PlayerStartDiggingEvent event) {
if(!isRunning) return; if(!isRunning) return;
setBlock(event.getBlockPosition(), Block.AIR); 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.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.LowestPointsWinScore; import eu.mhsl.minenet.minigames.score.LastWinsScore;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import io.github.togar2.pvp.events.FinalAttackEvent; import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures; import io.github.togar2.pvp.feature.CombatFeatures;
@@ -13,17 +13,15 @@ import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class Stickfight extends StatelessGame { public class Stickfight extends StatelessGame {
private final double radius = 20; private final double radius = 20;
private final WeakHashMap<Player, Pos> spawnPoints = new WeakHashMap<>(); private final WeakHashMap<Player, Pos> spawnPoints = new WeakHashMap<>();
private final Map<Player, Integer> scoreMap = new WeakHashMap<>();
public Stickfight() { public Stickfight() {
super(Dimension.OVERWORLD.key, "Stickfight", new LowestPointsWinScore()); super(Dimension.OVERWORLD.key, "Stickfight", new LastWinsScore());
eventNode().addChild( eventNode().addChild(
CombatFeatures.empty() CombatFeatures.empty()
@@ -68,11 +66,6 @@ public class Stickfight extends StatelessGame {
super.start(); super.start();
} }
@Override
protected void onStop() {
this.scoreMap.forEach((player, score) -> getScore().insertResult(player, score));
}
private void generateBridge(int startX, int startY, int startZ) { private void generateBridge(int startX, int startY, int startZ) {
int steps = (int) (radius * 1.5); int steps = (int) (radius * 1.5);
for (int i = 0; i < steps; i++) { for (int i = 0; i < steps; i++) {
@@ -85,22 +78,19 @@ public class Stickfight extends StatelessGame {
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player player = playerMoveEvent.getPlayer(); if(!spawnPoints.containsKey(playerMoveEvent.getPlayer())) {
if(!spawnPoints.containsKey(player)) {
playerMoveEvent.setCancelled(true); playerMoveEvent.setCancelled(true);
return; return;
} }
if(isBeforeBeginning) { if(isBeforeBeginning) {
if(spawnPoints.get(player).distance(playerMoveEvent.getNewPosition()) < 1) return; if(spawnPoints.get(playerMoveEvent.getPlayer()).distance(playerMoveEvent.getNewPosition()) < 1) return;
playerMoveEvent.setCancelled(true); playerMoveEvent.setCancelled(true);
player.teleport(spawnPoints.get(player)); playerMoveEvent.getPlayer().teleport(spawnPoints.get(playerMoveEvent.getPlayer()));
} }
if(playerMoveEvent.getNewPosition().y() < 40) { if(playerMoveEvent.getNewPosition().y() < 40) {
player.teleport(spawnPoints.get(player)); playerMoveEvent.getPlayer().teleport(spawnPoints.get(playerMoveEvent.getPlayer()));
this.scoreMap.putIfAbsent(player, 0);
this.scoreMap.put(player, this.scoreMap.get(player) + 1);
} }
} }

View File

@@ -1,129 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.sumo;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.LastWinsScore;
import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.events.PrepareAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.timer.TaskSchedule;
import org.jetbrains.annotations.NotNull;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
public class Sumo extends StatelessGame {
int radius;
int health;
int seconds;
int originalRadius;
int timer;
WeakHashMap<Player, Integer> healthMap = new WeakHashMap<>();
public Sumo(int radius, int health, int seconds) {
super(Dimension.OVERWORLD.key, "Sumo", new LastWinsScore());
this.getScore().setIgnoreLastPlayers(1);
this.setTime(6000);
this.setTimeRate(0);
this.radius = radius;
this.health = health;
this.seconds = seconds;
this.originalRadius = radius;
this.timer = seconds;
this.eventNode().addChild(
CombatFeatures.empty()
.add(CombatFeatures.VANILLA_ATTACK)
.add(CombatFeatures.VANILLA_DAMAGE)
.add(CombatFeatures.VANILLA_KNOCKBACK)
.build()
.createNode()
);
this.eventNode().addListener(PrepareAttackEvent.class, prepareAttackEvent -> {
if (this.isBeforeBeginning)
prepareAttackEvent.setCancelled(true);
});
this.eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
finalAttackEvent.setBaseDamage(0);
((Player) finalAttackEvent.getTarget()).setHealth(20);
});
}
@Override
protected void start() {
this.getPlayers().forEach(player -> {
this.healthMap.put(player, this.health);
player.setLevel(this.healthMap.get(player));
});
MinecraftServer.getSchedulerManager().scheduleTask(
() -> {
if(this.isBeforeBeginning) return TaskSchedule.seconds(1);
this.timer--;
double percent = (double) this.timer / this.seconds;
int radius = (int) (this.originalRadius * percent);
if (this.radius >= 5) {
this.radius = radius;
this.generatePlatform();
return TaskSchedule.seconds(1);
}
return TaskSchedule.stop();
},
TaskSchedule.seconds(1)
);
super.start();
}
@Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
this.generatePlatform();
}
private void generatePlatform() {
int buffer = 5;
for(int x = -this.radius - buffer; x <= this.radius + buffer; x++) {
for(int z = -this.radius - buffer; z <= this.radius + buffer; z++) {
double distance = new Pos(x, 0, z).distance(new Pos(0, 0, 0));
if(distance <= this.radius) {
boolean isEdge = this.radius - 1 < distance;
this.setBlock(x, 0, z, isEdge ? Block.RED_CONCRETE : Block.WHITE_CONCRETE);
} else {
this.setBlock(x, 0, z, Block.AIR);
}
}
}
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player player = playerMoveEvent.getPlayer();
if(playerMoveEvent.getNewPosition().y() < -10) {
player.teleport(this.getSpawn());
this.healthMap.put(player, this.healthMap.get(player) - 1);
player.setLevel(this.healthMap.get(player));
if (this.healthMap.get(player) == 0) {
this.getScore().insertResult(player);
player.setGameMode(GameMode.SPECTATOR);
}
}
}
@Override
public Pos getSpawn() {
return new Pos(0, 2, 0);
}
}

View File

@@ -1,49 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.sumo;
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.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;
import java.util.Map;
public class SumoFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_Sumo#name");
}
public TranslatedComponent description() {
return TranslatedComponent.byId("game_Sumo#description");
}
@Override
public Material symbol() {
return Material.SLIME_BALL;
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 10, 20, 30))
.addOption(new NumericOption("health", Material.GOLDEN_APPLE, TranslatedComponent.byId("game_Sumo#lives"), 1, 2, 3, 4, 5))
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 30, 60, 90, 120));
}
@Override
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

@@ -28,7 +28,7 @@ class Tetris extends StatelessGame {
public Tetris(int nextTetrominoesCount, boolean isFast, boolean hasCombat) { public Tetris(int nextTetrominoesCount, boolean isFast, boolean hasCombat) {
super(Dimension.THE_END.key, "Tetris", new PointsWinScore()); super(Dimension.THE_END.key, "Tetris", new PointsWinScore());
this.eventNode() eventNode()
.addListener(PlayerUseItemEvent.class, this::onPlayerInteract) .addListener(PlayerUseItemEvent.class, this::onPlayerInteract)
.addListener(PlayerHandAnimationEvent.class, this::onPlayerAttack) .addListener(PlayerHandAnimationEvent.class, this::onPlayerAttack)
.addListener(PlayerTickEvent.class, this::onPlayerTick); .addListener(PlayerTickEvent.class, this::onPlayerTick);
@@ -58,7 +58,7 @@ class Tetris extends StatelessGame {
protected void onStop() { protected void onStop() {
this.tetrisGames.forEach((player, tetrisGame) -> { this.tetrisGames.forEach((player, tetrisGame) -> {
tetrisGame.loose(); tetrisGame.loose();
this.getScore().insertResult(player, tetrisGame.getScore()); getScore().insertResult(player, tetrisGame.getScore());
tetrisGame.sidebar.removeViewer(player); tetrisGame.sidebar.removeViewer(player);
}); });
} }
@@ -106,25 +106,23 @@ class Tetris extends StatelessGame {
TetrisGame tetrisGame = this.tetrisGames.get(player); TetrisGame tetrisGame = this.tetrisGames.get(player);
if(tetrisGame == null) return; if(tetrisGame == null) return;
if(tetrisGame.lost && player.getGameMode() != GameMode.SPECTATOR) { if(tetrisGame.lost && player.getGameMode() != GameMode.SPECTATOR) {
this.letPlayerLoose(player); letPlayerLoose(player);
} }
} }
private void letPlayerLoose(Player player) { private void letPlayerLoose(Player player) {
TetrisGame tetrisGame = this.tetrisGames.get(player); TetrisGame tetrisGame = this.tetrisGames.get(player);
if(!this.getScore().hasResult(player)) { player.setGameMode(GameMode.SPECTATOR);
player.setGameMode(GameMode.SPECTATOR); player.setInvisible(true);
player.setInvisible(true); getScore().insertResult(player, tetrisGame.getScore());
this.getScore().insertResult(player, tetrisGame.getScore());
}
boolean allGamesLost = this.tetrisGames.values().stream() boolean allGamesLost = this.tetrisGames.values().stream()
.filter(game -> !game.lost) .filter(game -> !game.lost)
.toList() .toList()
.isEmpty(); .isEmpty();
if(!this.setTimeLimit && !allGamesLost) { if(!setTimeLimit && !allGamesLost) {
this.setTimeLimit(90); this.setTimeLimit(90);
this.setTimeLimit = true; setTimeLimit = true;
} }
} }
@@ -136,7 +134,7 @@ class Tetris extends StatelessGame {
if(this.tetrisGames.get(p) == null) { if(this.tetrisGames.get(p) == null) {
this.tetrisGames.put(p, new TetrisGame( this.tetrisGames.put(p, new TetrisGame(
this, this,
this.getSpawn().sub(6, 8, 15).add(this.tetrisGames.size()*30, 0, 0), getSpawn().sub(6, 8, 15).add(this.tetrisGames.size()*30, 0, 0),
Tetromino.Shape.J, Tetromino.Shape.J,
this.nextTetrominoesCount, this.nextTetrominoesCount,
this.isFast, this.isFast,

View File

@@ -74,10 +74,10 @@ public class Playfield {
} }
} }
batch.setBlock(this.getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE); batch.setBlock(getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE);
batch.setBlock(this.getPlayerSpawnPosition().sub(1, 1, 0), Block.STONE); batch.setBlock(getPlayerSpawnPosition().sub(1, 1, 0), Block.STONE);
batch.setBlock(this.getPlayerSpawnPosition().sub(1, 1, 1), Block.STONE); batch.setBlock(getPlayerSpawnPosition().sub(1, 1, 1), Block.STONE);
batch.setBlock(this.getPlayerSpawnPosition().sub(0, 1, 1), Block.STONE); batch.setBlock(getPlayerSpawnPosition().sub(0, 1, 1), Block.STONE);
BatchUtil.loadAndApplyBatch(batch, this.instance, () -> {}); BatchUtil.loadAndApplyBatch(batch, this.instance, () -> {});
} }
@@ -90,7 +90,7 @@ public class Playfield {
if(this.instance.getBlock(this.lowerLeftCorner.add(x, y, 1)) == Block.AIR) isFullLine = false; if(this.instance.getBlock(this.lowerLeftCorner.add(x, y, 1)) == Block.AIR) isFullLine = false;
} }
if(isFullLine) { if(isFullLine) {
this.removeFullLine(y); removeFullLine(y);
removedLinesCounter += 1; removedLinesCounter += 1;
y -= 1; y -= 1;
} }
@@ -99,10 +99,10 @@ public class Playfield {
} }
public void addLines(int lines) { public void addLines(int lines) {
int xPosMissing = this.random.nextInt(1, 10); int xPosMissing = random.nextInt(1, 10);
for (int i = 0; i < lines; i++) { for (int i = 0; i < lines; i++) {
this.moveAllLinesUp(); moveAllLinesUp();
for (int x = 1; x < 11; x++) { for (int x = 1; x < 11; x++) {
if(x != xPosMissing) { if(x != xPosMissing) {
this.instance.setBlock(this.lowerLeftCorner.add(x, 1, 1), Block.LIGHT_GRAY_CONCRETE); this.instance.setBlock(this.lowerLeftCorner.add(x, 1, 1), Block.LIGHT_GRAY_CONCRETE);

View File

@@ -121,8 +121,8 @@ public class TetrisGame {
public void tick() { public void tick() {
if(this.lost || this.paused) return; if(this.lost || this.paused) return;
if(!this.currentTetromino.moveDown()) { if(!currentTetromino.moveDown()) {
this.setActiveTetrominoDown(); setActiveTetrominoDown();
} }
} }
@@ -176,7 +176,7 @@ public class TetrisGame {
} }
private boolean switchHold() { private boolean switchHold() {
if(!this.holdPossible) return false; if(!holdPossible) return false;
Tetromino newCurrentTetromino; Tetromino newCurrentTetromino;
if(this.holdTetromino == null) { if(this.holdTetromino == null) {
@@ -194,7 +194,7 @@ public class TetrisGame {
this.currentTetromino.setPosition(this.tetrominoSpawnPosition); this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
this.currentTetromino.draw(); this.currentTetromino.draw();
if(!this.currentTetromino.moveDown()) this.loose(); if(!this.currentTetromino.moveDown()) loose();
double xChange = this.holdTetromino.getXChange(); double xChange = this.holdTetromino.getXChange();
this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0)); this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0));
@@ -312,7 +312,7 @@ public class TetrisGame {
this.currentTetromino.setPosition(this.tetrominoSpawnPosition); this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
this.currentTetromino.draw(); this.currentTetromino.draw();
if(!this.currentTetromino.moveDown()) { if(!this.currentTetromino.moveDown()) {
this.loose(); loose();
} }
} }
} }

View File

@@ -38,13 +38,13 @@ public class Tetromino {
this.uuid = UUID.randomUUID(); this.uuid = UUID.randomUUID();
switch (this.shape) { switch (this.shape) {
case I -> this.shapeArray = new int[][]{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}; case I -> shapeArray = new int[][]{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}};
case J -> this.shapeArray = new int[][]{{1,0,0}, {1,1,1}, {0,0,0}}; case J -> shapeArray = new int[][]{{1,0,0}, {1,1,1}, {0,0,0}};
case L -> this.shapeArray = new int[][]{{0,0,1}, {1,1,1}, {0,0,0}}; case L -> shapeArray = new int[][]{{0,0,1}, {1,1,1}, {0,0,0}};
case O -> this.shapeArray = new int[][]{{1,1}, {1,1}}; case O -> shapeArray = new int[][]{{1,1}, {1,1}};
case S -> this.shapeArray = new int[][]{{0,1,1}, {1,1,0}, {0,0,0}}; case S -> shapeArray = new int[][]{{0,1,1}, {1,1,0}, {0,0,0}};
case T -> this.shapeArray = new int[][]{{0,1,0}, {1,1,1}, {0,0,0}}; case T -> shapeArray = new int[][]{{0,1,0}, {1,1,1}, {0,0,0}};
case Z -> this.shapeArray = new int[][]{{1,1,0}, {0,1,1}, {0,0,0}}; case Z -> shapeArray = new int[][]{{1,1,0}, {0,1,1}, {0,0,0}};
} }
} }
@@ -58,22 +58,22 @@ public class Tetromino {
public boolean rotate(boolean clockwise) { public boolean rotate(boolean clockwise) {
int[][] newShapeArray = this.getTurnedShapeArray(clockwise); int[][] newShapeArray = this.getTurnedShapeArray(clockwise);
return this.checkCollisionAndMove(this.position, newShapeArray); return checkCollisionAndMove(this.position, newShapeArray);
} }
public boolean moveDown() { public boolean moveDown() {
Pos newPosition = this.position.sub(0, 1, 0); Pos newPosition = this.position.sub(0, 1, 0);
return this.checkCollisionAndMove(newPosition, this.shapeArray); return checkCollisionAndMove(newPosition, this.shapeArray);
} }
public boolean moveLeft() { public boolean moveLeft() {
Pos newPosition = this.position.sub(1, 0, 0); Pos newPosition = this.position.sub(1, 0, 0);
return this.checkCollisionAndMove(newPosition, this.shapeArray); return checkCollisionAndMove(newPosition, this.shapeArray);
} }
public boolean moveRight() { public boolean moveRight() {
Pos newPosition = this.position.add(1, 0, 0); Pos newPosition = this.position.add(1, 0, 0);
return this.checkCollisionAndMove(newPosition, this.shapeArray); return checkCollisionAndMove(newPosition, this.shapeArray);
} }
public void draw() { public void draw() {
@@ -83,11 +83,11 @@ public class Tetromino {
public void draw(boolean withGhost) { public void draw(boolean withGhost) {
if(withGhost) { if(withGhost) {
Pos ghostPos = this.position; Pos ghostPos = this.position;
while (!this.checkCollision(ghostPos.sub(0, 1, 0), this.shapeArray)) { while (!checkCollision(ghostPos.sub(0, 1, 0), this.shapeArray)) {
ghostPos = ghostPos.sub(0, 1, 0); ghostPos = ghostPos.sub(0, 1, 0);
} }
Pos positionChange = this.position.sub(ghostPos); Pos positionChange = this.position.sub(ghostPos);
this.getBlockPositions().forEach(pos -> { getBlockPositions().forEach(pos -> {
Entity ghostBlock = new Entity(ghostEntityType); Entity ghostBlock = new Entity(ghostEntityType);
((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getGhostBlock()); ((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getGhostBlock());
ghostBlock.setNoGravity(true); ghostBlock.setNoGravity(true);
@@ -97,11 +97,11 @@ public class Tetromino {
}); });
} }
this.getBlockPositions().forEach(pos -> this.instance.setBlock(pos, this.getColoredBlock())); getBlockPositions().forEach(pos -> this.instance.setBlock(pos, this.getColoredBlock()));
} }
public void drawAsEntities() { public void drawAsEntities() {
this.getBlockPositions().forEach(pos -> { getBlockPositions().forEach(pos -> {
Entity ghostBlock = new Entity(ghostEntityType); Entity ghostBlock = new Entity(ghostEntityType);
((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getColoredBlock()); ((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getColoredBlock());
ghostBlock.setNoGravity(true); ghostBlock.setNoGravity(true);
@@ -222,10 +222,10 @@ public class Tetromino {
} }
private boolean checkCollision(Pos newPosition, int[][] newShapeArray) { private boolean checkCollision(Pos newPosition, int[][] newShapeArray) {
List<Pos> newBlockPositions = this.getBlockPositions(newPosition, newShapeArray); List<Pos> newBlockPositions = getBlockPositions(newPosition, newShapeArray);
for(Pos pos : newBlockPositions) { for(Pos pos : newBlockPositions) {
if(this.isPartOfTetromino(pos)) continue; if(isPartOfTetromino(pos)) continue;
if(this.instance.getBlock(pos) == this.getGhostBlock()) continue; if(this.instance.getBlock(pos) == this.getGhostBlock()) continue;
if(this.instance.getBlock(pos) != Block.AIR) return true; if(this.instance.getBlock(pos) != Block.AIR) return true;
} }
@@ -234,7 +234,7 @@ public class Tetromino {
} }
private boolean checkCollisionAndMove(Pos newPosition, int[][] newShapeArray) { private boolean checkCollisionAndMove(Pos newPosition, int[][] newShapeArray) {
if(!this.checkCollision(newPosition, newShapeArray)) { if(!checkCollision(newPosition, newShapeArray)) {
this.remove(); this.remove();
this.shapeArray = Arrays.stream(newShapeArray).map(int[]::clone).toArray(int[][]::new); this.shapeArray = Arrays.stream(newShapeArray).map(int[]::clone).toArray(int[][]::new);
this.setPosition(newPosition); this.setPosition(newPosition);

View File

@@ -3,74 +3,23 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense;
import eu.mhsl.minenet.minigames.instance.Dimension; import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.generator.MazeGenerator; import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.generator.MazeGenerator;
import eu.mhsl.minenet.minigames.score.LastWinsScore; import eu.mhsl.minenet.minigames.score.NoScore;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.instance.batch.AbsoluteBlockBatch; import net.minestom.server.item.ItemStack;
import net.minestom.server.instance.block.Block; import net.minestom.server.item.Material;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Towerdefense extends StatelessGame { public class Towerdefense extends StatelessGame {
private final Random random = new Random();
private final AbsoluteBlockBatch mazeBatch = new AbsoluteBlockBatch();
private final List<Pos> mazePath = new ArrayList<>();
private List<TowerdefenseRoom> instances = new ArrayList<>();
public Towerdefense() { public Towerdefense() {
super(Dimension.NETHER.key, "Towerdefense", new LastWinsScore()); super(Dimension.NETHER.key, "Towerdefense", new NoScore());
setGenerator(new MazeGenerator()); setGenerator(new MazeGenerator());
this.generateMaze();
}
private void generateMaze() {
Pos position = new Pos(0, 0, 0);
this.addMazePosition(position, Block.GREEN_WOOL);
List<Integer> previousDirections = new ArrayList<>();
int direction = 1; // 0 -> right; 1 -> straight; 2 -> left
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 3; j++) {
position = position.add(direction-1,0,direction%2);
this.addMazePosition(position, Block.WHITE_WOOL);
}
int origin = 0;
int bound = 3;
long rightLeftDifference = previousDirections.stream().filter(integer -> integer == 0).count() - previousDirections.stream().filter(integer -> integer == 2).count();
if(rightLeftDifference >= 2 || direction == 2) origin = 1;
if(rightLeftDifference <= -2 || direction == 0) bound = 2;
direction = this.random.nextInt(origin, bound);
previousDirections.add(direction);
}
this.addMazePosition(position, Block.WHITE_WOOL);
this.addMazePosition(position.add(0,0,1), Block.WHITE_WOOL);
this.addMazePosition(position.add(0,0,2), Block.RED_WOOL);
}
private void addMazePosition(Pos position, Block pathBlock) {
this.mazeBatch.setBlock(position, pathBlock);
this.mazePath.add(position.add(0.5,1,0.5));
}
public AbsoluteBlockBatch getMazeBatch() {
return this.mazeBatch;
}
public List<Pos> getMazePath() {
return this.mazePath;
} }
@Override @Override
protected boolean onPlayerJoin(Player p) { protected boolean onPlayerJoin(Player p) {
TowerdefenseRoom newRoom = new TowerdefenseRoom(p, this); p.getInventory().setItemStack(1, ItemStack.of(Material.ARMOR_STAND));
this.instances.add(newRoom);
p.setInstance(newRoom);
newRoom.startWave(List.of(EntityType.ENDERMAN, EntityType.BLAZE, EntityType.PLAYER, EntityType.HORSE, EntityType.ARMOR_STAND, EntityType.SKELETON));
return false; return false;
} }
} }

View File

@@ -1,58 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.generator.MazeGenerator;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.*;
import net.minestom.server.entity.attribute.Attribute;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.timer.TaskSchedule;
import java.util.List;
import java.util.UUID;
public class TowerdefenseRoom extends InstanceContainer {
private final Player player;
private final Towerdefense game;
public TowerdefenseRoom(Player player, Towerdefense game) {
super(UUID.randomUUID(), Dimension.OVERWORLD.key);
MinecraftServer.getInstanceManager().registerInstance(this);
this.player = player;
this.game = game;
this.player.setGameMode(GameMode.ADVENTURE);
this.player.setAllowFlying(true);
this.player.getInventory().setItemStack(0, ItemStack.of(Material.ARMOR_STAND));
setGenerator(new MazeGenerator());
BatchUtil.loadAndApplyBatch(this.game.getMazeBatch(), this, () -> {});
}
public void startWave(List<EntityType> entities) {
int counter = 0;
for(EntityType entityType : entities) {
MinecraftServer.getSchedulerManager().scheduleTask(() -> {
this.addEntity(new EntityCreature(entityType));
return TaskSchedule.stop();
}, TaskSchedule.millis(800L*counter));
counter++;
}
}
private void addEntity(EntityCreature entity) {
entity.setInstance(this, this.game.getMazePath().getFirst());
entity.getAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.15);
entity.getNavigator().setPathTo(this.game.getMazePath().get(1), 0.7, () -> changeEntityGoal(entity, 1));
}
private void changeEntityGoal(EntityCreature entity, int positionIndex) {
if(positionIndex == this.game.getMazePath().size()-1) {
return;
}
entity.getNavigator().setPathTo(this.game.getMazePath().get(positionIndex+1), 0.7, () -> changeEntityGoal(entity, positionIndex+1));
}
}

View File

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

View File

@@ -66,8 +66,6 @@ public class Room extends MineNetInstance implements Spawnable {
p.getInventory().clear(); p.getInventory().clear();
p.setGameMode(GameMode.ADVENTURE); p.setGameMode(GameMode.ADVENTURE);
p.setInvisible(false); p.setInvisible(false);
p.setExp(0);
p.setLevel(0);
rooms.add(room); rooms.add(room);
players.put(p, room); players.put(p, room);
MoveInstance.move(p, room); MoveInstance.move(p, room);
@@ -90,29 +88,29 @@ public class Room extends MineNetInstance implements Spawnable {
private Room(Player owner) { private Room(Player owner) {
super(Dimension.THE_END.key); super(Dimension.THE_END.key);
this.apiDriven = false; this.apiDriven = false;
this.construct(); construct();
this.setOwner(owner); setOwner(owner);
} }
protected Room() { protected Room() {
super(Dimension.THE_END.key); super(Dimension.THE_END.key);
this.apiDriven = true; this.apiDriven = true;
this.construct(); construct();
} }
private void construct() { private void construct() {
MinecraftServer.getInstanceManager().registerInstance(this); MinecraftServer.getInstanceManager().registerInstance(this);
this.setChunkLoader(new AnvilLoader(Resource.LOBBY_MAP.getPath())); setChunkLoader(new AnvilLoader(Resource.LOBBY_MAP.getPath()));
this.gameSelector = new GameSelector(); this.gameSelector = new GameSelector();
this.gameSelector.setInstance(this, new Pos(0.5, 50, 19.5)); this.gameSelector.setInstance(this, new Pos(0.5, 50, 19.5));
this.eventNode().addListener(PlayerBlockBreakEvent.class, CommonEventHandles::cancel); eventNode().addListener(PlayerBlockBreakEvent.class, CommonEventHandles::cancel);
this.eventNode().addListener(PlayerDisconnectEvent.class, playerDisconnectEvent -> unsetRoom(playerDisconnectEvent.getPlayer())); eventNode().addListener(PlayerDisconnectEvent.class, playerDisconnectEvent -> unsetRoom(playerDisconnectEvent.getPlayer()));
} }
public Player getOwner() { public Player getOwner() {
return this.owner; return owner;
} }
public void setOwner(Player newOwner) { public void setOwner(Player newOwner) {
@@ -125,7 +123,7 @@ public class Room extends MineNetInstance implements Spawnable {
if(p != this.owner) return; if(p != this.owner) return;
this.getAllMembers().stream() getAllMembers().stream()
.filter(player -> player != p) // exclude the current leaving owner .filter(player -> player != p) // exclude the current leaving owner
.findFirst() .findFirst()
.ifPresentOrElse( .ifPresentOrElse(
@@ -135,8 +133,8 @@ public class Room extends MineNetInstance implements Spawnable {
Room.unsetRoom(p); Room.unsetRoom(p);
new ChatMessage(Icon.ERROR).appendStatic("The room leader left!").send(this.getAllMembers()); new ChatMessage(Icon.ERROR).appendStatic("The room leader left!").send(getAllMembers());
new ChatMessage(Icon.SCIENCE).appendStatic(this.owner.getUsername()).appendStatic(" is the new Leader!").send(this.getAllMembers().stream().filter(player -> player != this.owner).collect(Collectors.toSet())); new ChatMessage(Icon.SCIENCE).appendStatic(this.owner.getUsername()).appendStatic(" is the new Leader!").send(getAllMembers().stream().filter(player -> player != this.owner).collect(Collectors.toSet()));
new ChatMessage(Icon.SUCCESS).appendStatic("You are now the leader.").send(this.owner); new ChatMessage(Icon.SUCCESS).appendStatic("You are now the leader.").send(this.owner);
}); });
} }

View File

@@ -1,29 +0,0 @@
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,21 +12,11 @@ import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class PointsWinScore extends Score { public class PointsWinScore extends Score {
Map<Set<Player>, Integer> scoreOrder = new HashMap<>(); private Map<Set<Player>, Integer> scoreOrder = new HashMap<>();
@Override @Override
protected void insertResultImplementation(Set<Player> p, int currentPoints) { protected void insertResultImplementation(Set<Player> p, int currentPoints) {
Set<Player> combined = scoreOrder.entrySet().stream() this.scoreOrder.put(p, currentPoints);
.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); this.scoreOrder = MapUtil.sortByValue(this.scoreOrder);
getScores().clear(); getScores().clear();
this.scoreOrder.forEach((player, integer) -> getScores().addFirst(player)); this.scoreOrder.forEach((player, integer) -> getScores().addFirst(player));
@@ -52,12 +42,13 @@ public class PointsWinScore extends Score {
.filter(player -> !player.getUsername().isBlank()) .filter(player -> !player.getUsername().isBlank())
.toList() .toList()
.isEmpty()) .isEmpty())
.map(players -> players.stream() .map(players -> players
.map(Player::getUsername) .stream()
.sorted() .filter(player -> scoreOrder.get(Set.of(player)) != null)
.collect(Collectors.joining(", ")) .map(player -> player.getUsername()+" : "+scoreOrder.get(Set.of(player)).toString())
+ " : " + scoreOrder.get(players) .collect(Collectors.joining(", "))
).toList() )
.toList()
) )
.undent() .undent()
.newLine() .newLine()

View File

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

View File

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

View File

@@ -1,6 +1,9 @@
package eu.mhsl.minenet.minigames.util; package eu.mhsl.minenet.minigames.util;
import java.util.*; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class MapUtil { public class MapUtil {
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) { public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
@@ -14,16 +17,4 @@ public class MapUtil {
return result; 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

@@ -12,7 +12,7 @@ public enum BlockPallet {
STONE(new Block[] {Block.CHISELED_STONE_BRICKS, Block.STONE_BRICKS, Block.POLISHED_ANDESITE, Block.POLISHED_BLACKSTONE, Block.POLISHED_DIORITE}), STONE(new Block[] {Block.CHISELED_STONE_BRICKS, Block.STONE_BRICKS, Block.POLISHED_ANDESITE, Block.POLISHED_BLACKSTONE, Block.POLISHED_DIORITE}),
WINTER(new Block[] {Block.SNOW_BLOCK, Block.ICE, Block.PACKED_ICE, Block.BLUE_CONCRETE, Block.SEA_LANTERN}), WINTER(new Block[] {Block.SNOW_BLOCK, Block.ICE, Block.PACKED_ICE, Block.BLUE_CONCRETE, Block.SEA_LANTERN}),
STREET(new Block[] {Block.BLACK_CONCRETE_POWDER, Block.GRAY_CONCRETE_POWDER, Block.GRAVEL, Block.BLACK_CONCRETE, Block.GRAY_CONCRETE}), STREET(new Block[] {Block.BLACK_CONCRETE_POWDER, Block.GRAY_CONCRETE_POWDER, Block.GRAVEL, Block.BLACK_CONCRETE, Block.GRAY_CONCRETE}),
FLOWER(new Block[] {Block.ORANGE_TULIP, Block.PINK_TULIP, Block.RED_TULIP, Block.WHITE_TULIP}),
PRESSURE_PLATES(new Block[] {Block.ACACIA_PRESSURE_PLATE, Block.BIRCH_PRESSURE_PLATE, Block.CRIMSON_PRESSURE_PLATE, Block.JUNGLE_PRESSURE_PLATE, Block.OAK_PRESSURE_PLATE, Block.DARK_OAK_PRESSURE_PLATE, Block.HEAVY_WEIGHTED_PRESSURE_PLATE, Block.HEAVY_WEIGHTED_PRESSURE_PLATE, Block.POLISHED_BLACKSTONE_PRESSURE_PLATE, Block.SPRUCE_PRESSURE_PLATE, Block.STONE_PRESSURE_PLATE, Block.WARPED_PRESSURE_PLATE}); PRESSURE_PLATES(new Block[] {Block.ACACIA_PRESSURE_PLATE, Block.BIRCH_PRESSURE_PLATE, Block.CRIMSON_PRESSURE_PLATE, Block.JUNGLE_PRESSURE_PLATE, Block.OAK_PRESSURE_PLATE, Block.DARK_OAK_PRESSURE_PLATE, Block.HEAVY_WEIGHTED_PRESSURE_PLATE, Block.HEAVY_WEIGHTED_PRESSURE_PLATE, Block.POLISHED_BLACKSTONE_PRESSURE_PLATE, Block.SPRUCE_PRESSURE_PLATE, Block.STONE_PRESSURE_PLATE, Block.WARPED_PRESSURE_PLATE});
final List<Block> list; final List<Block> list;

View File

@@ -21,7 +21,6 @@ public class ValeGenerator extends HeightTerrainGenerator {
.build(); .build();
private Function<Integer, Double> xShiftMultiplier = multiplier -> 1d; private Function<Integer, Double> xShiftMultiplier = multiplier -> 1d;
private Function<Integer, Double> xShiftOffset = z -> 0d;
public ValeGenerator() { public ValeGenerator() {
setCalculateHeight(this::calculateY); setCalculateHeight(this::calculateY);
@@ -33,14 +32,10 @@ public class ValeGenerator extends HeightTerrainGenerator {
} }
public int getXShiftAtZ(int z) { public int getXShiftAtZ(int z) {
return (int) ((curves.getNoise(z) * 32 + largeCurves.getNoise(z) * 64) * xShiftMultiplier.apply(z) + xShiftOffset.apply(z)); return (int) ((curves.getNoise(z) * 32 + largeCurves.getNoise(z) * 64) * xShiftMultiplier.apply(z));
} }
public void setXShiftMultiplier(Function<Integer, Double> xShiftMultiplier) { public void setXShiftMultiplier(Function<Integer, Double> xShiftMultiplier) {
this.xShiftMultiplier = xShiftMultiplier; this.xShiftMultiplier = xShiftMultiplier;
} }
public void setXShiftOffset(Function<Integer, Double> xShiftOffset) {
this.xShiftOffset = xShiftOffset;
}
} }

View File

@@ -130,21 +130,3 @@ description;Run away from falling anvils;Renne von fallenden Ambossen davon
ns:game_jumpDive#;; ns:game_jumpDive#;;
name;Jump dive;Wassersprung name;Jump dive;Wassersprung
description;Jump into the water, avoiding already used spots!;Springe ins wasser an stellen, in denen noch niemand zuvor gelandet ist! description;Jump into the water, avoiding already used spots!;Springe ins wasser an stellen, in denen noch niemand zuvor gelandet ist!
;;
ns:game_Sumo#;;
name;Sumo;Sumo
lives;Lives;Leben
description;Knock your enemies off and stay on top!;Versuche deinen Gegner von der Plattform zu schubsen!
;;
ns:game_Highground#;;
name;Highground;Hochburg
description;Stay on the high ground to win!;Bleibe solange wie möglich auf der Hochburg, um zu gewinnen!
;;
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
130 ns:game_jumpDive#
131 name Jump dive Wassersprung
132 description Jump into the water, avoiding already used spots! Springe ins wasser an stellen, in denen noch niemand zuvor gelandet ist!
ns:game_Sumo#
name Sumo Sumo
lives Lives Leben
description Knock your enemies off and stay on top! Versuche deinen Gegner von der Plattform zu schubsen!
ns:game_Highground#
name Highground Hochburg
description Stay on the high ground to win! Bleibe solange wie möglich auf der Hochburg, um zu gewinnen!
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!