From d9bbaf9865506a8a25ee0118530b1762367b91a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Tue, 3 Oct 2023 22:25:47 +0200 Subject: [PATCH] Added AcidRain game --- .../minigames/instance/game/GameList.java | 2 + .../stateless/types/acidRain/AcidRain.java | 124 ++++++++++++++++++ .../types/acidRain/AcidRainFactory.java | 26 ++++ .../mhsl/minenet/minigames/util/RangeMap.java | 4 +- .../minenet/minigames/util/WeatherUtils.java | 29 ++++ 5 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRain.java create mode 100644 src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRainFactory.java create mode 100644 src/main/java/eu/mhsl/minenet/minigames/util/WeatherUtils.java 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 6e03ed0..dbed6ec 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 @@ -3,6 +3,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.backrooms.BackroomsFactory; 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.deathcube.DeathcubeFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun.MinerunFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef.SpleefFactory; @@ -20,6 +21,7 @@ public enum GameList { BEDWARS(new BedwarsFactory(), GameType.PROTOTYPE), BACKROOMS(new BackroomsFactory(), GameType.PROTOTYPE), TNTRUN(new TntRunFactory(), GameType.OTHER), + BLIZZARD(new AcidRainFactory(), GameType.PVE), SPLEEF(new SpleefFactory(), GameType.PVP); private final GameFactory factory; diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRain.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRain.java new file mode 100644 index 0000000..b36706b --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRain.java @@ -0,0 +1,124 @@ +package eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain; + +import de.articdive.jnoise.JNoise; +import eu.mhsl.minenet.minigames.instance.Dimension; +import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; +import eu.mhsl.minenet.minigames.score.LastWinsScore; +import eu.mhsl.minenet.minigames.util.BatchUtil; +import eu.mhsl.minenet.minigames.util.RangeMap; +import eu.mhsl.minenet.minigames.util.WeatherUtils; +import eu.mhsl.minenet.minigames.world.generator.BlockPallet; +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.GameMode; +import net.minestom.server.entity.Player; +import net.minestom.server.event.player.PlayerMoveEvent; +import net.minestom.server.event.player.PlayerTickEvent; +import net.minestom.server.instance.batch.AbsoluteBlockBatch; +import net.minestom.server.instance.block.Block; +import net.minestom.server.particle.Particle; +import net.minestom.server.particle.ParticleCreator; +import net.minestom.server.timer.ExecutionType; +import net.minestom.server.timer.TaskSchedule; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.CompletableFuture; + + +public class AcidRain extends StatelessGame { + final private int radius = 20; + private int generationOffset = 0; + + final private int roofHeight = 55; + private int difficulty = 0; + final JNoise noise = JNoise.newBuilder() + .fastSimplex() + .setSeed(rnd.nextLong()) + .setFrequency(0.09) + .build(); + public AcidRain() { + super(Dimension.OVERWORLD.DIMENSION, "acidRain", new LastWinsScore()); + setGenerator( + new CircularPlateTerrainGenerator(radius) + .setPlateHeight(50) + .setPlatePallet(BlockPallet.STONE) + ); + + + eventNode().addListener(PlayerTickEvent.class, this::onPlayerTick); + } + + @Override + protected void onLoad(@NotNull CompletableFuture callback) { + this.generatePlatform(0); + callback.complete(null); + } + + @Override + protected void onStart() { + new WeatherUtils().startRain(this.getPlayers()); + + MinecraftServer.getSchedulerManager().submitTask(() -> { + + getPlayers().forEach(player -> { + player.sendPacket(ParticleCreator.createParticlePacket(Particle.SNEEZE, 0, 60, 0, radius, radius, radius, 500)); + player.sendPacket(ParticleCreator.createParticlePacket(Particle.ITEM_SLIME, 0, 60, 0, radius, radius, radius, 500)); + }); + + if(!isRunning) return TaskSchedule.stop(); + return TaskSchedule.millis(100); + }, ExecutionType.ASYNC); + + MinecraftServer.getSchedulerManager().submitTask(() -> { + generationOffset++; + generatePlatform(generationOffset); + + if(!isRunning) return TaskSchedule.stop(); + return TaskSchedule.millis(RangeMap.map(50 - difficulty, 0, 50, 100, 1000)); + }, ExecutionType.ASYNC); + + MinecraftServer.getSchedulerManager().submitTask(() -> { + difficulty++; + + if(difficulty >= 50) return TaskSchedule.stop(); + return TaskSchedule.seconds(3); + }); + } + + @Override + protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { + if(playerMoveEvent.getNewPosition().y() < 50) playerDeath(playerMoveEvent.getPlayer()); + } + + private void onPlayerTick(PlayerTickEvent playerTickEvent) { + if(isBeforeBeginning) return; + if(getBlock(playerTickEvent.getPlayer().getPosition().withY(roofHeight)).isAir()) playerDeath(playerTickEvent.getPlayer()); + } + + private void generatePlatform(long offset) { + int radius = this.radius + 20; + + AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); + for(int x = -radius; x <= radius; x++) { + for(int z = -radius; z <= radius; z++) { + batch.setBlock(x, roofHeight, z, Block.AIR); + if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue; + if(noise.getNoise(x + offset, z + offset) > 0.4) continue; + + batch.setBlock(x, roofHeight, z, Block.OAK_PLANKS); + } + } + BatchUtil.loadAndApplyBatch(batch, this, () -> {}); + } + + private void playerDeath(Player p) { + p.setGameMode(GameMode.SPECTATOR); + getScore().insertResult(p); + } + + @Override + public Pos getSpawn() { + return new Pos(0, 51, 0); + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRainFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRainFactory.java new file mode 100644 index 0000000..5cc0415 --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/acidRain/AcidRainFactory.java @@ -0,0 +1,26 @@ +package eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain; + +import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; +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.message.component.TranslatedComponent; +import net.minestom.server.item.Material; + +import java.util.Map; + +public class AcidRainFactory implements GameFactory { + @Override + public TranslatedComponent name() { + return TranslatedComponent.byId("game_AcidRain#name"); + } + + @Override + public Material symbol() { + return Material.SLIME_BALL; + } + + @Override + public StatelessGame manufacture(Map> configuration) throws Exception { + return new AcidRain(); + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/util/RangeMap.java b/src/main/java/eu/mhsl/minenet/minigames/util/RangeMap.java index d5f48e5..b793f83 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/util/RangeMap.java +++ b/src/main/java/eu/mhsl/minenet/minigames/util/RangeMap.java @@ -1,11 +1,11 @@ package eu.mhsl.minenet.minigames.util; public class RangeMap { - public static double map(double oldValue, double oldMin, double oldMax, double newMin, double newMax) { + public static long map(double oldValue, double oldMin, double oldMax, double newMin, double newMax) { double out = (((oldValue - oldMin) * (newMax - newMin)) / (oldMax - oldMin)) + newMin; if(out > newMax) out = newMax; if(out < newMin) out = newMin; - return out; + return (long) out; } } diff --git a/src/main/java/eu/mhsl/minenet/minigames/util/WeatherUtils.java b/src/main/java/eu/mhsl/minenet/minigames/util/WeatherUtils.java new file mode 100644 index 0000000..d56c62c --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/util/WeatherUtils.java @@ -0,0 +1,29 @@ +package eu.mhsl.minenet.minigames.util; + +import net.minestom.server.MinecraftServer; +import net.minestom.server.entity.Player; +import net.minestom.server.network.packet.server.play.ChangeGameStatePacket; +import net.minestom.server.timer.ExecutionType; +import net.minestom.server.timer.TaskSchedule; + +import java.util.Set; + + +public class WeatherUtils { + private float intensity; + public void startRain(Set players) { + intensity = 0; + players.forEach(p -> p.sendPacket(new ChangeGameStatePacket(ChangeGameStatePacket.Reason.BEGIN_RAINING, 0f))); + + MinecraftServer.getSchedulerManager().submitTask(() -> { + intensity += 0.1f; + players.forEach(p -> p.sendPacket(new ChangeGameStatePacket(ChangeGameStatePacket.Reason.RAIN_LEVEL_CHANGE, intensity))); + System.out.println(intensity); + if(intensity < 1) { + return TaskSchedule.millis(500); + } else { + return TaskSchedule.stop(); + } + }, ExecutionType.ASYNC); + } +}