From 7561d42f417f4f4268be243b62a31f2705e1f4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Mon, 29 Nov 2021 22:14:13 +0100 Subject: [PATCH] initial commit --- .idea/.gitignore | 3 + .idea/compiler.xml | 13 ++ .idea/jarRepositories.xml | 30 +++++ .idea/misc.xml | 14 ++ .idea/runConfigurations.xml | 10 ++ .idea/uiDesigner.xml | 124 ++++++++++++++++++ EndlessJumper.iml | 13 ++ pom.xml | 40 ++++++ .../minecraft/endlessjumper/BlockMath.java | 9 ++ .../endlessjumper/EndlessJumper.java | 80 +++++++++++ .../endlessjumper/TerrainGenerator.java | 36 +++++ .../endlessjumper/generator/BlockPalette.java | 24 ++++ .../generator/JumpGenerator.java | 113 ++++++++++++++++ .../minecraft/endlessjumper/BlockMath.class | Bin 0 -> 652 bytes .../endlessjumper/EndlessJumper.class | Bin 0 -> 6446 bytes .../endlessjumper/TerrainGenerator.class | Bin 0 -> 2509 bytes .../generator/BlockPalette.class | Bin 0 -> 1237 bytes .../generator/JumpGenerator.class | Bin 0 -> 6298 bytes 18 files changed, 509 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/runConfigurations.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 EndlessJumper.iml create mode 100644 pom.xml create mode 100644 src/main/java/eu/mhsl/minecraft/endlessjumper/BlockMath.java create mode 100644 src/main/java/eu/mhsl/minecraft/endlessjumper/EndlessJumper.java create mode 100644 src/main/java/eu/mhsl/minecraft/endlessjumper/TerrainGenerator.java create mode 100644 src/main/java/eu/mhsl/minecraft/endlessjumper/generator/BlockPalette.java create mode 100644 src/main/java/eu/mhsl/minecraft/endlessjumper/generator/JumpGenerator.java create mode 100644 target/classes/eu/mhsl/minecraft/endlessjumper/BlockMath.class create mode 100644 target/classes/eu/mhsl/minecraft/endlessjumper/EndlessJumper.class create mode 100644 target/classes/eu/mhsl/minecraft/endlessjumper/TerrainGenerator.class create mode 100644 target/classes/eu/mhsl/minecraft/endlessjumper/generator/BlockPalette.class create mode 100644 target/classes/eu/mhsl/minecraft/endlessjumper/generator/JumpGenerator.class diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..287ab5d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..a008a5e --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..06e8b35 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..797acea --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/EndlessJumper.iml b/EndlessJumper.iml new file mode 100644 index 0000000..eedae82 --- /dev/null +++ b/EndlessJumper.iml @@ -0,0 +1,13 @@ + + + + + + + MIXIN + ADVENTURE + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..497f8df --- /dev/null +++ b/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + + org.example + EndlessJumper + 1.0-SNAPSHOT + + + 17 + 17 + + + + + spongepowered + https://repo.spongepowered.org/maven + + + jitpack + https://jitpack.io + + + + + + com.github.Minestom + Minestom + 484727d02a + + + org.jboss.shrinkwrap.resolver + shrinkwrap-resolver-depchain + + + + + \ No newline at end of file diff --git a/src/main/java/eu/mhsl/minecraft/endlessjumper/BlockMath.java b/src/main/java/eu/mhsl/minecraft/endlessjumper/BlockMath.java new file mode 100644 index 0000000..c7edf7d --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/endlessjumper/BlockMath.java @@ -0,0 +1,9 @@ +package eu.mhsl.minecraft.endlessjumper; + +import net.minestom.server.coordinate.Pos; + +public class BlockMath { + public static Pos roundToBlock(Pos p) { + return new Pos(p.blockX(), p.blockY(), p.blockZ()); + } +} diff --git a/src/main/java/eu/mhsl/minecraft/endlessjumper/EndlessJumper.java b/src/main/java/eu/mhsl/minecraft/endlessjumper/EndlessJumper.java new file mode 100644 index 0000000..7a355ea --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/endlessjumper/EndlessJumper.java @@ -0,0 +1,80 @@ +package eu.mhsl.minecraft.endlessjumper; + +import eu.mhsl.minecraft.endlessjumper.generator.JumpGenerator; +import net.minestom.server.MinecraftServer; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.Player; +import net.minestom.server.entity.PlayerSkin; +import net.minestom.server.event.GlobalEventHandler; +import net.minestom.server.event.player.PlayerDisconnectEvent; +import net.minestom.server.event.player.PlayerLoginEvent; +import net.minestom.server.event.player.PlayerMoveEvent; +import net.minestom.server.instance.InstanceContainer; +import net.minestom.server.instance.InstanceManager; +import net.minestom.server.instance.block.Block; + +import java.util.HashMap; + +public class EndlessJumper { + public static void main(String[] args) { + MinecraftServer server = MinecraftServer.init(); + InstanceManager instanceManager = MinecraftServer.getInstanceManager(); + GlobalEventHandler eventHandler = MinecraftServer.getGlobalEventHandler(); + PlayerSkin skin = PlayerSkin.fromUsername("Notch"); + + HashMap games = new HashMap<>(); + + eventHandler.addListener(PlayerLoginEvent.class, event -> { + final Player p = event.getPlayer(); + p.setRespawnPoint(new Pos(0.5,101.5,0.5)); + + final InstanceContainer world = instanceManager.createInstanceContainer(); + world.setChunkGenerator(new TerrainGenerator()); + + Pos startingAt = new Pos(0,100,0); + world.setBlock(startingAt, Block.DIAMOND_BLOCK); + + world.setTimeRate(0); + world.setTime(18000); + + p.setSkin(skin); + + event.setSpawningInstance(world); + + games.put(p, new JumpGenerator(startingAt, p, world)); + }); + + eventHandler.addListener(PlayerMoveEvent.class, event -> { + Player p = event.getPlayer(); + + if(!games.containsKey(p)) { + event.setCancelled(true); + return; + } + + JumpGenerator generator = games.get(p); + + //reset when falling down + if(p.getPosition().y() < generator.getNextLanding().y()-5 && p.getPosition().y() < generator.getCheckpoint().y()) generator.reset(); + + Pos p1 = BlockMath.roundToBlock(event.getNewPosition().sub(0.0,1.0,0.0)); + Pos p2 = BlockMath.roundToBlock(event.getNewPosition().sub(0.0, 2.0, 0.0)); + + + for(int i = 0; i <= generator.getPreview(); i++) { + Pos target = generator.getBlocks().get(generator.getBlocks().size()-i-1); + if(p1.sameBlock(target) || p2.sameBlock(target)) generator.generateNext(); + } + + + //if(p.getPosition().z() > target.z()+2) generator.highlight(); + }); + + eventHandler.addListener(PlayerDisconnectEvent.class, event -> { + games.remove(event.getPlayer()); + }); + + server.start("0.0.0.0", 25565); + + } +} diff --git a/src/main/java/eu/mhsl/minecraft/endlessjumper/TerrainGenerator.java b/src/main/java/eu/mhsl/minecraft/endlessjumper/TerrainGenerator.java new file mode 100644 index 0000000..9b4c54a --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/endlessjumper/TerrainGenerator.java @@ -0,0 +1,36 @@ +package eu.mhsl.minecraft.endlessjumper; + +import net.minestom.server.instance.Chunk; +import net.minestom.server.instance.ChunkGenerator; +import net.minestom.server.instance.ChunkPopulator; +import net.minestom.server.instance.batch.ChunkBatch; +import net.minestom.server.instance.block.Block; +import net.minestom.server.world.biomes.Biome; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.List; + +public class TerrainGenerator implements ChunkGenerator { + @Override + public void generateChunkData(@NotNull ChunkBatch batch, int chunkX, int chunkZ) { + for(byte x = 0; x < Chunk.CHUNK_SIZE_X; x++) { + for(byte z = 0; z < Chunk.CHUNK_SIZE_Z; z++) { + for(byte y = 0; y < 1; y++) { + batch.setBlock(x, y, z, Block.AIR); + } + } + } + } + + @Override + public void fillBiomes(@NotNull Biome[] biomes, int chunkX, int chunkZ) { + Arrays.fill(biomes, Biome.PLAINS); + } + + @Override + public @Nullable List getPopulators() { + return null; + } +} diff --git a/src/main/java/eu/mhsl/minecraft/endlessjumper/generator/BlockPalette.java b/src/main/java/eu/mhsl/minecraft/endlessjumper/generator/BlockPalette.java new file mode 100644 index 0000000..ef3f685 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/endlessjumper/generator/BlockPalette.java @@ -0,0 +1,24 @@ +package eu.mhsl.minecraft.endlessjumper.generator; + +import net.minestom.server.instance.block.Block; + +import java.util.ArrayList; +import java.util.Random; + +public class BlockPalette { + public static Block getRandom(int seed) { + Random r = new Random(seed); + ArrayList blocks = new ArrayList<>(); + + blocks.add(Block.COPPER_BLOCK); + blocks.add(Block.CUT_COPPER); + blocks.add(Block.WEATHERED_COPPER); + blocks.add(Block.WEATHERED_CUT_COPPER); + blocks.add(Block.OXIDIZED_COPPER); + blocks.add(Block.OXIDIZED_CUT_COPPER); + + + + return blocks.get(r.nextInt(0, blocks.size())); + } +} diff --git a/src/main/java/eu/mhsl/minecraft/endlessjumper/generator/JumpGenerator.java b/src/main/java/eu/mhsl/minecraft/endlessjumper/generator/JumpGenerator.java new file mode 100644 index 0000000..4c946e6 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/endlessjumper/generator/JumpGenerator.java @@ -0,0 +1,113 @@ +package eu.mhsl.minecraft.endlessjumper.generator; + +import net.kyori.adventure.sound.Sound; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.title.Title; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.Player; +import net.minestom.server.instance.InstanceContainer; +import net.minestom.server.instance.block.Block; +import net.minestom.server.particle.Particle; +import net.minestom.server.particle.ParticleCreator; +import net.minestom.server.sound.SoundEvent; + +import java.util.ArrayList; +import java.util.Random; + +public class JumpGenerator { + private Player player; + private InstanceContainer world; + private ArrayList blocks = new ArrayList<>(); + private Pos checkpoint; + private Pos starting; + + private int combo = 0; + + private int preview = 2; + + + public JumpGenerator(Pos starting, Player player, InstanceContainer world) { + this.player = player; + this.world = world; + this.starting = starting; + generateStart(starting); + } + + public void generateNext() { + boolean isTenth = this.blocks.size() % 10 == 0; + boolean standingTenth = (this.blocks.size()-this.preview-1) % 10 == 0; + boolean isHundredth = this.blocks.size() % 100 == 0; + + float pitch = 1 + (combo * 0.025f); + this.player.playSound(Sound.sound(SoundEvent.BLOCK_NOTE_BLOCK_PLING, Sound.Source.MASTER, 0.1f, pitch)); + this.player.showTitle(Title.title(Component.text(""), Component.text((combo)+"", TextColor.color(255, 69, 0)))); + this.player.setLevel((this.blocks.size()-this.preview-1)); + + Random r = new Random(); + Pos target = blocks.get(blocks.size()-1).add(r.nextInt(-1, 2), r.nextInt(this.player.getPosition().y() < 80 ? 0 : -1, this.player.getPosition().y() > 120 ? 1 : 2), r.nextInt(3, 5)); + this.world.setBlock(target, isHundredth ? Block.DIAMOND_BLOCK : isTenth ? Block.GOLD_BLOCK : BlockPalette.getRandom((this.blocks.size() / 10))); + + if(standingTenth) { + Pos current = this.blocks.get(this.blocks.size()-this.preview-1); + this.checkpoint = current; + this.player.playSound(Sound.sound(SoundEvent.ENTITY_PLAYER_LEVELUP, Sound.Source.BLOCK, 0.3f, 1f)); + this.player.showTitle(Title.title(Component.text(""), Component.text("Checkpoint", TextColor.color(0, 255, 0)))); + this.player.sendPacket(ParticleCreator.createParticlePacket(Particle.CRIT, current.x()+0.5, current.y()+0.5, current.z()+0.5, 1.5f, 1.5f, 1.5f, 50)); + } + this.world.setBlock(target.add(0, 1 ,0), Block.LIGHT); + this.blocks.add(target); + this.player.sendPacket(ParticleCreator.createParticlePacket(Particle.CRIT, target.x()+0.5, target.y()+0.5, target.z()+0.5, 1, 1, 1, 10)); + this.player.sendPacket(ParticleCreator.createParticlePacket(Particle.FALLING_NECTAR, target.x()+0.5, target.y()+1.5, target.z()+0.5, 0.3f, 0.1f, 0.3f, 10)); + this.combo++; + } + + public Pos getNextLanding() { + return this.blocks.get(this.blocks.size()-(preview+1)); + } + + + public void generateStart(Pos start) { + this.starting = start; + this.checkpoint = start; + this.blocks.add(this.starting); + this.world.setBlock(this.starting, Block.DIAMOND_BLOCK); + for(int i = 0; i <= preview; i++) generateNext(); + } + + public void reset() { + /* + for(Pos p : this.blocks) { + this.world.setBlock(p, Block.AIR); + } + this.blocks.clear(); + */ + this.player.teleport(this.checkpoint.add(0.5, 1, 0.5)); + this.combo = 0; + this.player.showTitle(Title.title(Component.text(""), Component.text(""))); + + //generateStart(last); + this.player.playSound(Sound.sound(SoundEvent.BLOCK_GLASS_BREAK, Sound.Source.BLOCK, 0.3f, 1f)); + + } + + public Pos getCheckpoint() { + return checkpoint; + } + + public Player getPlayer() { + return player; + } + + public InstanceContainer getWorld() { + return world; + } + + public ArrayList getBlocks() { + return blocks; + } + + public int getPreview() { + return preview; + } +} diff --git a/target/classes/eu/mhsl/minecraft/endlessjumper/BlockMath.class b/target/classes/eu/mhsl/minecraft/endlessjumper/BlockMath.class new file mode 100644 index 0000000000000000000000000000000000000000..3c6db31c4ceb69286232d4e3cdd0ca843e1d8a1e GIT binary patch literal 652 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 literal 0 HcmV?d00001 diff --git a/target/classes/eu/mhsl/minecraft/endlessjumper/TerrainGenerator.class b/target/classes/eu/mhsl/minecraft/endlessjumper/TerrainGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..4e45687d74b841902848890d94efa00ec9d2ee3e GIT binary patch literal 2509 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 literal 0 HcmV?d00001