13 Commits

Author SHA1 Message Date
d98cebd86f added turtleGame playfield and movement 2025-09-02 22:29:47 +02:00
c87d318421 started turtleGame 2025-09-02 18:22:14 +02:00
13cc6c30b5 highground finished 2025-07-26 19:03:48 +02:00
3dd41979f7 WIP: highground 2025-07-25 23:04:03 +02:00
a4c46bc298 sumo renamed 2025-07-25 20:31:50 +02:00
aaad777f9b added Sumo Minigame 2025-07-25 20:22:45 +02:00
c62c7cfd1a added Sumo Minigame 2025-07-19 01:33:37 +02:00
4575164e80 Merge branch 'develop' into develop-hannes
# Conflicts:
#	build.gradle
#	src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java
2025-07-18 21:09:37 +02:00
edf26785a3 removed accidental code change 2025-04-16 23:45:03 +02:00
4d90f5fc28 added missing 'this' qualifier 2025-04-13 12:59:22 +02:00
343decb05a added this qualifier to tetris classes 2025-04-12 23:53:40 +02:00
36c6c93edb started towerdefense path mechanic 2025-04-11 00:51:43 +02:00
cc371a9c12 Test game 2024-11-02 21:53:17 +01:00
22 changed files with 675 additions and 105 deletions

View File

@@ -3,20 +3,22 @@ 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.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.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;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.turtleGame.TurtleGameFactory;
public enum GameList { public enum GameList {
DEATHCUBE(new DeathcubeFactory(), GameType.JUMPNRUN), DEATHCUBE(new DeathcubeFactory(), GameType.JUMPNRUN),
@@ -27,6 +29,7 @@ public enum GameList {
BEDWARS(new BedwarsFactory(), GameType.PROTOTYPE), BEDWARS(new BedwarsFactory(), GameType.PROTOTYPE),
BACKROOMS(new BackroomsFactory(), GameType.PROTOTYPE), BACKROOMS(new BackroomsFactory(), GameType.PROTOTYPE),
BOWSPLEEF(new BowSpleefFactory(), GameType.PROTOTYPE), BOWSPLEEF(new BowSpleefFactory(), GameType.PROTOTYPE),
TURTLEGAME(new TurtleGameFactory(), GameType.PROTOTYPE),
TETRIS(new TetrisFactory(), GameType.OTHER), TETRIS(new TetrisFactory(), GameType.OTHER),
TNTRUN(new TntRunFactory(), GameType.OTHER), TNTRUN(new TntRunFactory(), GameType.OTHER),
ANVILRUN(new AnvilRunFactory(), GameType.PVE), ANVILRUN(new AnvilRunFactory(), GameType.PVE),
@@ -34,7 +37,8 @@ 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),
BUILDBATTLE(new BuildBattleFactory(), GameType.OTHER); SUMO(new SumoFactory(), GameType.PVP),
HIGHGROUND(new HighGroundFactory(), GameType.PVP);
private final GameFactory factory; private final GameFactory factory;
private final GameType type; private final GameType type;
@@ -47,6 +51,6 @@ public enum GameList {
} }
public GameType getType() { public GameType getType() {
return type; return this.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.STICK, TranslatedComponent.byId("optionCommon#seconds"), 10, 30, 60, 90, 120)); .addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 10, 30, 60, 90, 120));
} }
@Override @Override

View File

@@ -1,13 +0,0 @@
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,21 +0,0 @@
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.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import java.util.Map;
public class BuildBattleFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_BuildBattle#name");
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new BuildBattle();
}
}

View File

@@ -1,12 +0,0 @@
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,6 +8,7 @@ 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.Player;
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;

View File

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

@@ -0,0 +1,36 @@
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.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 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);
}
}

View File

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

@@ -0,0 +1,36 @@
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.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 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);
}
}

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());
eventNode() this.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();
getScore().insertResult(player, tetrisGame.getScore()); this.getScore().insertResult(player, tetrisGame.getScore());
tetrisGame.sidebar.removeViewer(player); tetrisGame.sidebar.removeViewer(player);
}); });
} }
@@ -106,7 +106,7 @@ 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) {
letPlayerLoose(player); this.letPlayerLoose(player);
} }
} }
@@ -114,15 +114,15 @@ class Tetris extends StatelessGame {
TetrisGame tetrisGame = this.tetrisGames.get(player); TetrisGame tetrisGame = this.tetrisGames.get(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(!setTimeLimit && !allGamesLost) { if(!this.setTimeLimit && !allGamesLost) {
this.setTimeLimit(90); this.setTimeLimit(90);
setTimeLimit = true; this.setTimeLimit = true;
} }
} }
@@ -134,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,
getSpawn().sub(6, 8, 15).add(this.tetrisGames.size()*30, 0, 0), this.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(getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE); batch.setBlock(this.getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE);
batch.setBlock(getPlayerSpawnPosition().sub(1, 1, 0), Block.STONE); batch.setBlock(this.getPlayerSpawnPosition().sub(1, 1, 0), Block.STONE);
batch.setBlock(getPlayerSpawnPosition().sub(1, 1, 1), Block.STONE); batch.setBlock(this.getPlayerSpawnPosition().sub(1, 1, 1), Block.STONE);
batch.setBlock(getPlayerSpawnPosition().sub(0, 1, 1), Block.STONE); batch.setBlock(this.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) {
removeFullLine(y); this.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 = random.nextInt(1, 10); int xPosMissing = this.random.nextInt(1, 10);
for (int i = 0; i < lines; i++) { for (int i = 0; i < lines; i++) {
moveAllLinesUp(); this.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(!currentTetromino.moveDown()) { if(!this.currentTetromino.moveDown()) {
setActiveTetrominoDown(); this.setActiveTetrominoDown();
} }
} }
@@ -176,7 +176,7 @@ public class TetrisGame {
} }
private boolean switchHold() { private boolean switchHold() {
if(!holdPossible) return false; if(!this.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()) loose(); if(!this.currentTetromino.moveDown()) this.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()) {
loose(); this.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 -> shapeArray = new int[][]{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}; case I -> this.shapeArray = new int[][]{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}};
case J -> shapeArray = new int[][]{{1,0,0}, {1,1,1}, {0,0,0}}; case J -> this.shapeArray = new int[][]{{1,0,0}, {1,1,1}, {0,0,0}};
case L -> shapeArray = new int[][]{{0,0,1}, {1,1,1}, {0,0,0}}; case L -> this.shapeArray = new int[][]{{0,0,1}, {1,1,1}, {0,0,0}};
case O -> shapeArray = new int[][]{{1,1}, {1,1}}; case O -> this.shapeArray = new int[][]{{1,1}, {1,1}};
case S -> shapeArray = new int[][]{{0,1,1}, {1,1,0}, {0,0,0}}; case S -> this.shapeArray = new int[][]{{0,1,1}, {1,1,0}, {0,0,0}};
case T -> shapeArray = new int[][]{{0,1,0}, {1,1,1}, {0,0,0}}; case T -> this.shapeArray = new int[][]{{0,1,0}, {1,1,1}, {0,0,0}};
case Z -> shapeArray = new int[][]{{1,1,0}, {0,1,1}, {0,0,0}}; case Z -> this.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 checkCollisionAndMove(this.position, newShapeArray); return this.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 checkCollisionAndMove(newPosition, this.shapeArray); return this.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 checkCollisionAndMove(newPosition, this.shapeArray); return this.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 checkCollisionAndMove(newPosition, this.shapeArray); return this.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 (!checkCollision(ghostPos.sub(0, 1, 0), this.shapeArray)) { while (!this.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);
getBlockPositions().forEach(pos -> { this.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 {
}); });
} }
getBlockPositions().forEach(pos -> this.instance.setBlock(pos, this.getColoredBlock())); this.getBlockPositions().forEach(pos -> this.instance.setBlock(pos, this.getColoredBlock()));
} }
public void drawAsEntities() { public void drawAsEntities() {
getBlockPositions().forEach(pos -> { this.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 = getBlockPositions(newPosition, newShapeArray); List<Pos> newBlockPositions = this.getBlockPositions(newPosition, newShapeArray);
for(Pos pos : newBlockPositions) { for(Pos pos : newBlockPositions) {
if(isPartOfTetromino(pos)) continue; if(this.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(!checkCollision(newPosition, newShapeArray)) { if(!this.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,23 +3,74 @@ 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.NoScore; import eu.mhsl.minenet.minigames.score.LastWinsScore;
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.item.ItemStack; import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.item.Material; import net.minestom.server.instance.block.Block;
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 NoScore()); super(Dimension.NETHER.key, "Towerdefense", new LastWinsScore());
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) {
p.getInventory().setItemStack(1, ItemStack.of(Material.ARMOR_STAND)); TowerdefenseRoom newRoom = new TowerdefenseRoom(p, this);
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

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

@@ -0,0 +1,70 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.turtleGame;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.turtleGame.game.TurtleGameInstance;
import eu.mhsl.minenet.minigames.score.PointsWinScore;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.attribute.Attribute;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.WeakHashMap;
class TurtleGame extends StatelessGame {
private final boolean firstPerson;
private final Map<Player, TurtleGameInstance> gameInstances = new WeakHashMap<>();
public TurtleGame(boolean firstPerson) {
super(Dimension.OVERWORLD.key, "Tetris", new PointsWinScore());
this.firstPerson = firstPerson;
this.eventNode()
.addListener(PlayerMoveEvent.class, this::onPlayerMove);
}
protected void onPlayerMove(@NotNull PlayerMoveEvent event) {
TurtleGameInstance gameInstance = this.gameInstances.get(event.getPlayer());
gameInstance.getTurtle().setView(event.getPlayer().getPosition().yaw(), gameInstance.getTurtle().getPosition().pitch());
if(this.isRunning()) gameInstance.moveTurtle(event.getPlayer().getPosition().direction());
}
@Override
protected boolean onPlayerJoin(Player p) {
p.getInventory().setItemStack(0, ItemStack.builder(Material.BARRIER).customName(Component.text("Reset")).build());
if(this.gameInstances.get(p) == null) {
this.gameInstances.put(p, new TurtleGameInstance(
this,
this.getSpawn().sub(6, 8, 15).add(this.gameInstances.size()*50, 0, 0)
));
this.gameInstances.get(p).generate();
}
TurtleGameInstance gameInstance = this.gameInstances.get(p);
p.teleport(gameInstance.getPlayerSpawnPosition());
EntityCreature turtle = gameInstance.getTurtle();
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> {
turtle.setInstance(this);
turtle.teleport(gameInstance.getPlayerSpawnPosition());
turtle.addPassenger(p);
turtle.getAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.15);
});
return super.onPlayerJoin(p);
}
@Override
protected void onStart() {
this.gameInstances.forEach(((player, gameInstance) -> gameInstance.moveTurtle(player.getPosition().direction())));
// this.gameInstances.forEach(((player, turtleGameInstance) -> turtleGameInstance.start()));
}
}

View File

@@ -0,0 +1,41 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.turtleGame;
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.BoolOption;
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 TurtleGameFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_TurtleGame#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_TurtleGame#description");
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new BoolOption("firstPerson", Material.SPYGLASS, TranslatedComponent.byId("game_TurtleGame#firstPerson")));
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new TurtleGame(configuration.get("firstPerson").getAsBoolean());
}
@Override
public Material symbol() {
return Material.TURTLE_EGG;
}
}

View File

@@ -0,0 +1,53 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.turtleGame.game;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.EntityType;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block;
import java.awt.*;
public class TurtleGameInstance {
private final StatelessGame instance;
private final Pos startPosition;
private final EntityCreature turtle = new EntityCreature(EntityType.TURTLE);
public TurtleGameInstance(StatelessGame instance, Pos startPosition) {
this.instance = instance;
this.startPosition = startPosition;
}
public void moveTurtle(Vec direction) {
Vec targetDirection = direction.withY(0).normalize().mul(100);
Pos targetPosition = this.turtle.getPosition().add(targetDirection);
this.turtle.getNavigator().setPathTo(targetPosition);
}
public void generate() {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for (int z = -1; z < 66; z++) {
for (int x = -1; x < 44; x++) {
if(z < 0 || z >= 65 || x < 0 || x >= 43) {
batch.setBlock(this.startPosition.add(x, 1, z), Block.STONE);
batch.setBlock(this.startPosition.add(x, 2, z), Block.STONE_SLAB);
}
batch.setBlock(this.startPosition.add(x, 0, z), Block.SAND);
}
}
BatchUtil.loadAndApplyBatch(batch, this.instance, () -> {});
}
public Pos getPlayerSpawnPosition() {
return this.startPosition.add(20, 1, 30);
}
public EntityCreature getTurtle() {
return this.turtle;
}
}

View File

@@ -66,6 +66,8 @@ 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);
@@ -88,29 +90,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;
construct(); this.construct();
setOwner(owner); this.setOwner(owner);
} }
protected Room() { protected Room() {
super(Dimension.THE_END.key); super(Dimension.THE_END.key);
this.apiDriven = true; this.apiDriven = true;
construct(); this.construct();
} }
private void construct() { private void construct() {
MinecraftServer.getInstanceManager().registerInstance(this); MinecraftServer.getInstanceManager().registerInstance(this);
setChunkLoader(new AnvilLoader(Resource.LOBBY_MAP.getPath())); this.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));
eventNode().addListener(PlayerBlockBreakEvent.class, CommonEventHandles::cancel); this.eventNode().addListener(PlayerBlockBreakEvent.class, CommonEventHandles::cancel);
eventNode().addListener(PlayerDisconnectEvent.class, playerDisconnectEvent -> unsetRoom(playerDisconnectEvent.getPlayer())); this.eventNode().addListener(PlayerDisconnectEvent.class, playerDisconnectEvent -> unsetRoom(playerDisconnectEvent.getPlayer()));
} }
public Player getOwner() { public Player getOwner() {
return owner; return this.owner;
} }
public void setOwner(Player newOwner) { public void setOwner(Player newOwner) {
@@ -123,7 +125,7 @@ public class Room extends MineNetInstance implements Spawnable {
if(p != this.owner) return; if(p != this.owner) return;
getAllMembers().stream() this.getAllMembers().stream()
.filter(player -> player != p) // exclude the current leaving owner .filter(player -> player != p) // exclude the current leaving owner
.findFirst() .findFirst()
.ifPresentOrElse( .ifPresentOrElse(
@@ -133,8 +135,8 @@ public class Room extends MineNetInstance implements Spawnable {
Room.unsetRoom(p); Room.unsetRoom(p);
new ChatMessage(Icon.ERROR).appendStatic("The room leader left!").send(getAllMembers()); new ChatMessage(Icon.ERROR).appendStatic("The room leader left!").send(this.getAllMembers());
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.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.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

@@ -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

@@ -130,3 +130,12 @@ 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!
Can't render this file because it has a wrong number of fields in line 114.