diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/Game.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/Game.java index e5db049..dfae886 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/Game.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/Game.java @@ -118,7 +118,6 @@ public abstract class Game extends MineNetInstance implements Spawnable { protected void onStop() {} protected void onUnload() {} - protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { } diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java index 8f9b9d1..0fa51f5 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java @@ -1,6 +1,7 @@ package eu.mhsl.minenet.minigames.instance.game; import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory; +import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory; @@ -22,6 +23,7 @@ public enum GameList { TOWERDEFENSE(new TowerdefenseFactory(), GameType.PROTOTYPE), BEDWARS(new BedwarsFactory(), GameType.PROTOTYPE), BACKROOMS(new BackroomsFactory(), GameType.PROTOTYPE), + ANVILRUN(new AnvilRunFactory(), GameType.PROTOTYPE), TNTRUN(new TntRunFactory(), GameType.OTHER), ACIDRAIN(new AcidRainFactory(), GameType.PVE), ELYTRARACE(new ElytraRaceFactory(), GameType.PVP), diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java index 2855e20..c9efbb0 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/StatelessGame.java @@ -23,6 +23,7 @@ public class StatelessGame extends Game { private int timeLimit = 0; private int timePlayed = 0; + public StatelessGame(DynamicRegistry.Key dimensionType, String gameName, Score score) { super(dimensionType); this.score = score; diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/anvilRun/AnvilRun.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/anvilRun/AnvilRun.java new file mode 100644 index 0000000..1496048 --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/anvilRun/AnvilRun.java @@ -0,0 +1,111 @@ +package eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun; + +import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; +import eu.mhsl.minenet.minigames.score.LastWinsScore; +import eu.mhsl.minenet.minigames.instance.Dimension; +import eu.mhsl.minenet.minigames.util.BatchUtil; +import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; +import net.minestom.server.MinecraftServer; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.Entity; +import net.minestom.server.entity.EntityType; +import net.minestom.server.entity.metadata.other.FallingBlockMeta; +import net.minestom.server.event.entity.EntityTickEvent; +import net.minestom.server.event.player.PlayerMoveEvent; +import net.minestom.server.instance.batch.AbsoluteBlockBatch; +import net.minestom.server.instance.block.Block; +import net.minestom.server.timer.Scheduler; +import net.minestom.server.timer.TaskSchedule; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +class AnvilRun extends StatelessGame { + + final int spawnHeight = 30; + final int radius; + int anvilsPerSecond; + final int seconds; + final int anvilHeight = 200; + final List anvilSpawnPositions = new ArrayList<>(); + + public AnvilRun(int radius, int seconds) { + super(Dimension.OVERWORLD.key, "Anvil Run", new LastWinsScore()); + this.radius = radius; + this.seconds = seconds; + this.setGenerator(new CircularPlateTerrainGenerator(radius)); + + eventNode().addListener(EntityTickEvent.class, this::onEntityTick); + } + + @Override + protected void onLoad(@NotNull CompletableFuture callback) { + AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); + + for(int x = -radius; x <= radius; x++) { + for (int z = -radius; z <= radius; z++) { + if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue; + + anvilSpawnPositions.add(new Pos(x+0.5, anvilHeight, z+0.5)); + + batch.setBlock(x, spawnHeight-1, z, Block.SNOW_BLOCK); + } + } + + this.anvilsPerSecond = anvilSpawnPositions.size() / this.seconds; + Collections.shuffle(anvilSpawnPositions); + + BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null)); + } + + protected void spawnAnvil(Pos spawnPosition) { + Entity anvil = new Entity(EntityType.FALLING_BLOCK); + ((FallingBlockMeta) anvil.getEntityMeta()).setBlock(Block.ANVIL); + anvil.setInstance(this, spawnPosition); + } + + @Override + protected void onStart() { + super.onStart(); + + Scheduler scheduler = MinecraftServer.getSchedulerManager(); + for(int i=0; i spawnAnvil(this.anvilSpawnPositions.get(j)), + TaskSchedule.millis( + (long) Math.floor((double) i/this.anvilsPerSecond * 1000) + ), + TaskSchedule.stop() + ); + } + } + + @Override + protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { + super.onPlayerMove(playerMoveEvent); + if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() < spawnHeight - 2) { + playerMoveEvent.setCancelled(true); + playerMoveEvent.getPlayer().teleport(getSpawn()); + return; + } + if(playerMoveEvent.getNewPosition().y() < spawnHeight - 2) getScore().insertResult(playerMoveEvent.getPlayer()); + } + + protected void onEntityTick(@NotNull EntityTickEvent entityTickEvent) { + if(!entityTickEvent.getEntity().getEntityType().equals(EntityType.FALLING_BLOCK)) return; + Pos anvilPosition = entityTickEvent.getEntity().getPosition(); + if(anvilPosition.y() > spawnHeight + 0.5) return; + if(anvilPosition.y() < spawnHeight - 3) entityTickEvent.getEntity().remove(); + if(this.getBlock(anvilPosition.withY(spawnHeight-1)).isAir()) return; + this.setBlock(anvilPosition.withY(spawnHeight-1), Block.AIR); + } + + @Override + public Pos getSpawn() { + return new Pos(0, spawnHeight, 0); + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/anvilRun/AnvilRunFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/anvilRun/AnvilRunFactory.java new file mode 100644 index 0000000..a2a4b91 --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/anvilRun/AnvilRunFactory.java @@ -0,0 +1,41 @@ +package eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun; + +import eu.mhsl.minenet.minigames.instance.game.Game; +import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory; +import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option; +import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager; +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 AnvilRunFactory implements GameFactory { + @Override + public TranslatedComponent name() { + return TranslatedComponent.byId("game_AnvilRun#name"); + } + + @Override + public TranslatedComponent description() { + return TranslatedComponent.byId("game_AnvilRun#description"); + } + + @Override + public ConfigManager configuration() { + 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("seconds", Material.STICK, TranslatedComponent.byId("game_Deathcube#seconds"), 10, 30, 60, 90, 120)); + } + + @Override + public Game manufacture(Room parent, Map> configuration) { + return new AnvilRun(configuration.get("radius").getAsInt(), configuration.get("seconds").getAsInt()).setParent(parent); + } + + @Override + public Material symbol() { + return Material.ANVIL; + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/deathcube/Deathcube.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/deathcube/Deathcube.java index 9cd601c..fc79e93 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/deathcube/Deathcube.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/deathcube/Deathcube.java @@ -6,9 +6,6 @@ import eu.mhsl.minenet.minigames.util.BatchUtil; import eu.mhsl.minenet.minigames.instance.Dimension; import eu.mhsl.minenet.minigames.world.BlockPallet; import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; -import io.github.togar2.pvp.config.AttackConfig; -import io.github.togar2.pvp.config.DamageConfig; -import io.github.togar2.pvp.config.PvPConfig; import net.minestom.server.coordinate.Pos; import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.instance.batch.AbsoluteBlockBatch; @@ -60,12 +57,20 @@ class Deathcube extends StatelessGame { @Override protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { super.onPlayerMove(playerMoveEvent); - if(isBeforeBeginning) if(playerMoveEvent.getNewPosition().y() > 51.5) playerMoveEvent.setCancelled(true); + if(playerMoveEvent.getNewPosition().y() < 48) { + playerMoveEvent.setCancelled(true); + playerMoveEvent.getPlayer().teleport(getSpawn()); + return; + } + if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() > 51.5) { + playerMoveEvent.setCancelled(true); + return; + } if(playerMoveEvent.getNewPosition().y() > height) getScore().insertResult(playerMoveEvent.getPlayer()); } @Override public Pos getSpawn() { - return new Pos(0, 50, 30); + return new Pos(0, 50, -(radius+5)); } } diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRace.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRace.java index b5fc58c..2206789 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRace.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/elytraRace/ElytraRace.java @@ -105,7 +105,7 @@ public class ElytraRace extends StatelessGame { @Override protected void onLoad(@NotNull CompletableFuture callback) { Point spawnpoint = new Pos(vale.getXShiftAtZ(0), -46, 0); - GeneratorUtils.iterateArea(spawnpoint.sub(2, 0, 2), spawnpoint.add(2, 0, 2), point -> { + GeneratorUtils.iterateArea(spawnpoint.sub(5, 0, 5), spawnpoint.add(5, 0, 5), point -> { setBlock(point, BlockPallet.STREET.rnd()); }); @@ -130,6 +130,11 @@ public class ElytraRace extends StatelessGame { Player player = playerMoveEvent.getPlayer(); Point newPos = playerMoveEvent.getNewPosition(); + if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() < getSpawn().y()) { + player.teleport(getSpawn()); + return; + } + playerCheckpoints.putIfAbsent(player, new CheckPointData(ringSpacing, ringSpacing * 2)); if(newPos.z() > generatedUntil - ringSpacing) { diff --git a/src/main/java/eu/mhsl/minenet/minigames/world/generator/terrain/CircularPlateTerrainGenerator.java b/src/main/java/eu/mhsl/minenet/minigames/world/generator/terrain/CircularPlateTerrainGenerator.java index 6f97ba5..4b82ea7 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/world/generator/terrain/CircularPlateTerrainGenerator.java +++ b/src/main/java/eu/mhsl/minenet/minigames/world/generator/terrain/CircularPlateTerrainGenerator.java @@ -53,7 +53,7 @@ public class CircularPlateTerrainGenerator extends PlateTerrainGenerator { double distance = bottom.distance(new Pos(0, 0, 0)); if(distance <= this.size && generatePlate()) { - unit.modifier().fill(bottom, bottom.add(1, 50, 1), platePallet.rnd()); + unit.modifier().fill(bottom, bottom.add(1, plateHeight, 1), platePallet.rnd()); continue; }