added playerrace and updated to version 26.2 #14
+2
-3
@@ -4,16 +4,15 @@ 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.LastWinsScore;
|
import eu.mhsl.minenet.minigames.score.LastWinsScore;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class PlayerRace extends StatelessGame {
|
public class PlayerRace extends StatelessGame {
|
||||||
public PlayerRace() {
|
public PlayerRace(int obstacleCount) {
|
||||||
super(Dimension.THE_END.key, "PlayerRace", new LastWinsScore());
|
super(Dimension.THE_END.key, "PlayerRace", new LastWinsScore());
|
||||||
this.setGenerator(new PlayerRaceChunkgenerator(64));
|
this.setGenerator(new PlayerRaceChunkgenerator(64, obstacleCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+37
-25
@@ -6,44 +6,56 @@ import eu.mhsl.minenet.minigames.world.BlockPallet;
|
|||||||
import eu.mhsl.minenet.minigames.world.generator.featureEnriched.ValeGenerator;
|
import eu.mhsl.minenet.minigames.world.generator.featureEnriched.ValeGenerator;
|
||||||
import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator;
|
import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
public class PlayerRaceChunkgenerator extends BaseGenerator {
|
public class PlayerRaceChunkgenerator extends BaseGenerator {
|
||||||
public PlayerRaceChunkgenerator(int height) {
|
private static final int START_LENGTH = 16;
|
||||||
|
private static final int GAP_LENGTH = 3;
|
||||||
|
private static final int PERIOD = Obstacle.LENGTH + GAP_LENGTH;
|
||||||
|
|
||||||
|
public PlayerRaceChunkgenerator(int height, int obstacleCount) {
|
||||||
ValeGenerator vale = new ValeGenerator();
|
ValeGenerator vale = new ValeGenerator();
|
||||||
vale.setXShiftMultiplier(integer -> 0.5d);
|
vale.setXShiftMultiplier(integer -> 0.5d);
|
||||||
vale.setHeightNoiseMultiplier(integer -> 2);
|
vale.setHeightNoiseMultiplier(integer -> 2);
|
||||||
this.addMixIn(vale);
|
this.addMixIn(vale);
|
||||||
|
|
||||||
|
int finishStart = START_LENGTH + obstacleCount * PERIOD;
|
||||||
|
int finishEnd = finishStart + 16;
|
||||||
|
|
||||||
this.addMixIn(unit -> {
|
this.addMixIn(unit -> {
|
||||||
if (
|
Point chunkStart = unit.absoluteStart();
|
||||||
unit.absoluteStart().chunkX() != 0 ||
|
if(
|
||||||
unit.absoluteStart().chunkZ() < 0 ||
|
chunkStart.chunkX() != 0 ||
|
||||||
unit.absoluteStart().chunkZ() > 16
|
chunkStart.blockZ() + 16 <= 0 ||
|
||||||
|
chunkStart.blockZ() >= finishEnd
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
Point start = unit.absoluteStart().withY(height);
|
GeneratorUtils.foreachXZ(unit, point -> {
|
||||||
|
Block ground = groundBlockAt(point.blockZ(), finishStart, finishEnd);
|
||||||
|
if(ground != null) unit.modifier().setBlock(point.withY(height), ground);
|
||||||
|
});
|
||||||
|
|
||||||
if(unit.absoluteStart().chunkZ() % 2 == 1) {
|
for(int i = 0; i < obstacleCount; i++) {
|
||||||
Obstacle.getRandomObstacle().generate(unit, start);
|
int obstacleZ = START_LENGTH + i * PERIOD;
|
||||||
return;
|
if(obstacleZ < chunkStart.blockZ() || obstacleZ >= chunkStart.blockZ() + 16) continue;
|
||||||
|
|
||||||
|
GenerationUnit fork = unit.fork(
|
||||||
|
new Vec(chunkStart.blockX(), height - 8, obstacleZ),
|
||||||
|
new Vec(chunkStart.blockX() + 16, height + 16, obstacleZ + Obstacle.LENGTH)
|
||||||
|
);
|
||||||
|
Obstacle.getRandomObstacle().generate(fork, new Vec(chunkStart.blockX(), height, obstacleZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
BiConsumer<Point, Block> setBlock = (Point point, Block block) -> unit.modifier().setBlock(point.withY(height), block);
|
|
||||||
|
|
||||||
if(unit.absoluteStart().chunkZ() == 0) {
|
|
||||||
GeneratorUtils.foreachXZ(unit, point -> setBlock.accept(point, Block.AMETHYST_BLOCK));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(unit.absoluteStart().chunkZ() == 16) {
|
|
||||||
GeneratorUtils.foreachXZ(unit, point -> setBlock.accept(point, Block.DIAMOND_BLOCK));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GeneratorUtils.foreachXZ(unit, point -> setBlock.accept(point, BlockPallet.GROUND.rnd()));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Block groundBlockAt(int z, int finishStart, int finishEnd) {
|
||||||
|
if(z < 0 || z >= finishEnd) return null;
|
||||||
|
if(z < START_LENGTH) return Block.AMETHYST_BLOCK;
|
||||||
|
if(z >= finishStart) return Block.DIAMOND_BLOCK;
|
||||||
|
|
||||||
|
int relative = (z - START_LENGTH) % PERIOD;
|
||||||
|
return relative >= Obstacle.LENGTH ? BlockPallet.GROUND.rnd() : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -1,8 +1,10 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace;
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace;
|
||||||
|
|
||||||
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.ConfigManager;
|
||||||
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.common.NumericOption;
|
||||||
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;
|
||||||
@@ -15,9 +17,15 @@ public class PlayerRaceFactory implements GameFactory {
|
|||||||
return TranslatedComponent.byId("game_PlayerRace#name");
|
return TranslatedComponent.byId("game_PlayerRace#name");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigManager configuration() {
|
||||||
|
return new ConfigManager()
|
||||||
|
.addOption(new NumericOption("length", Material.RAIL, TranslatedComponent.byId("optionCommon#length"), 8, 12, 16, 20));
|
||||||
|
}
|
||||||
|
|
||||||
@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 PlayerRace().setParent(parent);
|
return new PlayerRace(configuration.get("length").getAsInt()).setParent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dichter Bambushain: Die dünnen Halme haben kleine Hitboxen —
|
||||||
|
* wer sich geschickt durchschlängelt, verliert kaum Tempo.
|
||||||
|
*/
|
||||||
|
class BambooThicket extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(3) == 0 ? Block.PODZOL : Block.GRASS_BLOCK);
|
||||||
|
|
||||||
|
int z = relZ(point, start);
|
||||||
|
if(z < 2 || z > 13 || rnd.nextInt(100) >= 45) return;
|
||||||
|
|
||||||
|
int height = 3 + rnd.nextInt(3);
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
String leaves = y == height ? "large" : y == height - 1 ? "small" : "none";
|
||||||
|
unit.modifier().setBlock(
|
||||||
|
point.withY(start.blockY() + y),
|
||||||
|
Block.BAMBOO.withProperty("age", "1").withProperty("leaves", leaves)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basaltdeltas-Säulenfeld: Hohe Basaltsäulen mit Seelenlaternen bilden
|
||||||
|
* einen düsteren Hindernisparcours zum Durchkurven.
|
||||||
|
*/
|
||||||
|
class BasaltPillars extends Obstacle {
|
||||||
|
private final JNoise ground = JNoise.newBuilder()
|
||||||
|
.fastSimplex()
|
||||||
|
.setFrequency(0.13)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
double noise = this.ground.getNoise(point.blockX(), point.blockZ());
|
||||||
|
Block floor = noise > 0.4 ? Block.SOUL_SOIL : noise < -0.4 ? Block.BASALT : Block.BLACKSTONE;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int i = 0; i < 16; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
int height = 2 + rnd.nextInt(3);
|
||||||
|
boolean thick = rnd.nextInt(3) == 0 && x < 15;
|
||||||
|
Block pillar = rnd.nextInt(3) == 0 ? Block.POLISHED_BASALT : Block.BASALT;
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
unit.modifier().setBlock(start.add(x, y, z), pillar);
|
||||||
|
if(thick) {
|
||||||
|
unit.modifier().setBlock(start.add(x + 1, y, z), pillar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(rnd.nextInt(3) == 0) {
|
||||||
|
unit.modifier().setBlock(start.add(x, height + 1, z), Block.SOUL_LANTERN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Süßbeerenfeld: Die Büsche bremsen stark. Ein geschwungener Trampelpfad
|
||||||
|
* führt hindurch, ist aber in der Mitte selbst zugewuchert —
|
||||||
|
* ganz ohne Gestrüpp kommt hier niemand durch.
|
||||||
|
*/
|
||||||
|
class BerryPatch extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int z = relZ(point, start);
|
||||||
|
int pathX = 7 + (int) Math.round(5 * Math.sin(z * Math.PI / 7.5));
|
||||||
|
boolean onPath = relX(point, start) == pathX || relX(point, start) == pathX + 1;
|
||||||
|
boolean overgrown = z == 8;
|
||||||
|
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), onPath ? Block.DIRT_PATH : Block.GRASS_BLOCK);
|
||||||
|
|
||||||
|
boolean bush = onPath ? overgrown : z >= 1 && z <= 14 && rnd.nextInt(100) < 45;
|
||||||
|
if(bush) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.SWEET_BERRY_BUSH.withProperty("age", "3"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ausgetrocknetes Flussbett: Ein zwei Blöcke tiefer Graben quer zur Strecke,
|
||||||
|
* auf dessen Grund bemooste Findlinge liegen. Rein springen, durchkämpfen, rausklettern.
|
||||||
|
*/
|
||||||
|
class BoulderTrench extends Obstacle {
|
||||||
|
private static final int[] DEPTHS = {0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int depth = DEPTHS[relZ(point, start)];
|
||||||
|
for(int y = start.blockY() - 2; y < start.blockY() - depth; y++) {
|
||||||
|
unit.modifier().setBlock(point.withY(y), Block.STONE);
|
||||||
|
}
|
||||||
|
Block floor = depth == 0
|
||||||
|
? Block.GRASS_BLOCK
|
||||||
|
: rnd.nextBoolean() ? Block.COARSE_DIRT : Block.GRAVEL;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - depth), floor);
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int i = 0; i < 10; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 6 + rnd.nextInt(4);
|
||||||
|
unit.modifier().setBlock(start.add(x, -1, z), rnd.nextBoolean() ? Block.MOSSY_COBBLESTONE : Block.COBBLESTONE);
|
||||||
|
if(rnd.nextInt(3) == 0) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 0, z), Block.MOSSY_COBBLESTONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
unit.modifier().setBlock(start.add(rnd.nextInt(16), -1, 6 + rnd.nextInt(4)), Block.COBWEB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End-Ruine: Zwei Endstein-Ziegelmauern (nicht überspringbar) mit versetzten,
|
||||||
|
* schmalen Durchgängen, dazwischen ein dichtes Chorus-Dickicht und
|
||||||
|
* Purpur-Trümmer. Passt zur End-Dimension des Spiels.
|
||||||
|
*/
|
||||||
|
class ChorusGrove extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
Block floor = rnd.nextInt(14) == 0 ? Block.PURPUR_BLOCK : Block.END_STONE;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
});
|
||||||
|
|
||||||
|
int[] rows = {5, 10};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 1 + rnd.nextInt(4) : 10 + rnd.nextInt(4);
|
||||||
|
|
||||||
|
boolean[] hasWall = new boolean[16];
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
hasWall[x] = x < gapStart || x >= gapStart + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(!hasWall[x]) continue;
|
||||||
|
boolean westConnected = x > 0 && hasWall[x - 1];
|
||||||
|
boolean eastConnected = x < 15 && hasWall[x + 1];
|
||||||
|
Block wall = Block.END_STONE_BRICK_WALL
|
||||||
|
.withProperty("west", westConnected ? "low" : "none")
|
||||||
|
.withProperty("east", eastConnected ? "low" : "none")
|
||||||
|
.withProperty("up", String.valueOf(!westConnected || !eastConnected || x % 4 == 0));
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), wall);
|
||||||
|
|
||||||
|
if(rnd.nextInt(6) == 0) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, rows[i]), Block.END_ROD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 15; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
if(z == 5 || z == 10) continue;
|
||||||
|
int height = 1 + rnd.nextInt(3);
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
unit.modifier().setBlock(start.add(x, y, z), Block.CHORUS_PLANT);
|
||||||
|
}
|
||||||
|
unit.modifier().setBlock(start.add(x, height + 1, z), Block.CHORUS_FLOWER.withProperty("age", "5"));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
if(z == 5 || z == 10) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, z), Block.PURPUR_BLOCK);
|
||||||
|
if(rnd.nextBoolean()) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, z), Block.PURPUR_BLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verlassener Fichtenhain: Spinnweben zwischen alten Baumstümpfen
|
||||||
|
* bremsen jeden, der nicht sauber um sie herumläuft.
|
||||||
|
*/
|
||||||
|
class CobwebGrove extends Obstacle {
|
||||||
|
private final JNoise soil = JNoise.newBuilder()
|
||||||
|
.fastSimplex()
|
||||||
|
.setFrequency(0.12)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
Block floor = this.soil.getNoise(point.blockX(), point.blockZ()) > 0 ? Block.PODZOL : Block.COARSE_DIRT;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
|
||||||
|
int z = relZ(point, start);
|
||||||
|
if(z < 2 || z > 13) return;
|
||||||
|
|
||||||
|
int roll = rnd.nextInt(100);
|
||||||
|
if(roll < 28) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.COBWEB);
|
||||||
|
if(roll < 8) unit.modifier().setBlock(point.withY(start.blockY() + 2), Block.COBWEB);
|
||||||
|
} else if(roll < 36) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.FERN);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 3 + rnd.nextInt(10);
|
||||||
|
int height = 1 + rnd.nextInt(2);
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
unit.modifier().setBlock(start.add(x, y, z), Block.SPRUCE_LOG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tropfsteinkamm: Drei Zackenreihen aus Dripstone-Sockeln mit Stalagmiten
|
||||||
|
* obendrauf sind unpassierbar — nur die versetzten Lücken führen hindurch.
|
||||||
|
* Dazwischen ragen weitere Stalagmiten aus dem Boden.
|
||||||
|
*/
|
||||||
|
class DripstoneSpikes extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point ->
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(6) == 0 ? Block.STONE : Block.DRIPSTONE_BLOCK));
|
||||||
|
|
||||||
|
int[] rows = {4, 8, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 2 + rnd.nextInt(4) : 9 + rnd.nextInt(4);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(x >= gapStart && x < gapStart + 2) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), Block.DRIPSTONE_BLOCK);
|
||||||
|
this.placeSpike(unit, start.add(0, 1, 0), x, rows[i], 1 + rnd.nextInt(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 12; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
if(z == 4 || z == 8 || z == 12) continue;
|
||||||
|
this.placeSpike(unit, start, x, z, 1 + rnd.nextInt(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void placeSpike(GenerationUnit unit, Point start, int x, int z, int height) {
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
String thickness = y == height ? "tip" : y == height - 1 ? "frustum" : "base";
|
||||||
|
unit.modifier().setBlock(
|
||||||
|
start.add(x, y, z),
|
||||||
|
Block.POINTED_DRIPSTONE
|
||||||
|
.withProperty("thickness", thickness)
|
||||||
|
.withProperty("vertical_direction", "up")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gläsernes Labyrinth auf Quarzboden: Fast unsichtbare Glasscheiben-Wände
|
||||||
|
* mit versetzten Lücken — wer rast, läuft dagegen.
|
||||||
|
*/
|
||||||
|
class GlassPaneWeave extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point ->
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(5) == 0 ? Block.CALCITE : Block.QUARTZ_BLOCK));
|
||||||
|
|
||||||
|
int[] rows = {4, 8, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 2 + rnd.nextInt(3) : 11 + rnd.nextInt(3);
|
||||||
|
|
||||||
|
boolean[] hasPane = new boolean[16];
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
hasPane[x] = x < gapStart || x >= gapStart + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(!hasPane[x]) continue;
|
||||||
|
Block pane = (rnd.nextInt(6) == 0 ? Block.GRAY_STAINED_GLASS_PANE : Block.WHITE_STAINED_GLASS_PANE)
|
||||||
|
.withProperty("west", String.valueOf(x > 0 && hasPane[x - 1]))
|
||||||
|
.withProperty("east", String.valueOf(x < 15 && hasPane[x + 1]));
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), pane);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, rows[i]), pane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bauernhof-Hürdenlauf: Vier Reihen Strohballen — die flachen müssen ohne
|
||||||
|
* Lücke übersprungen werden, die hohen zwingen durch eine schmale Gasse.
|
||||||
|
*/
|
||||||
|
class HayHurdles extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), Block.GRASS_BLOCK);
|
||||||
|
if(relZ(point, start) % 3 != 0 && rnd.nextInt(8) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.SHORT_GRASS);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int[] rows = {3, 6, 9, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
boolean tall = i % 2 == 1;
|
||||||
|
int gapStart = rnd.nextInt(14);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(tall && (x == gapStart || x == gapStart + 1)) continue;
|
||||||
|
Block block = rnd.nextInt(12) == 0 ? Block.CARVED_PUMPKIN : Block.HAY_BLOCK;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), block);
|
||||||
|
if(tall) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, rows[i]), Block.HAY_BLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Honigwaben-Feld: klebrige Honigflecken im Boden bremsen, zwei Honigwände
|
||||||
|
* mit versetzten Durchlässen zwingen in eine Zickzack-Linie.
|
||||||
|
*/
|
||||||
|
class HoneyField extends Obstacle {
|
||||||
|
private final JNoise sticky = JNoise.newBuilder()
|
||||||
|
.fastSimplex()
|
||||||
|
.setFrequency(0.2)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
boolean stickyFloor = this.sticky.getNoise(point.blockX(), point.blockZ()) > 0.35;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), stickyFloor ? Block.HONEY_BLOCK : Block.HONEYCOMB_BLOCK);
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int wallZ : new int[]{5, 10}) {
|
||||||
|
int gapStart = wallZ == 5 ? 1 + rnd.nextInt(5) : 8 + rnd.nextInt(5);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(x >= gapStart && x < gapStart + 2) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, wallZ), Block.HONEY_BLOCK);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, wallZ), Block.HONEY_BLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spiegelglatte Eisfläche: Blue-Ice-Streifen beschleunigen unkontrolliert,
|
||||||
|
* zwei Eiswände mit versetzten Durchlässen müssen rutschend getroffen werden.
|
||||||
|
*/
|
||||||
|
class IceRink extends Obstacle {
|
||||||
|
private final JNoise streaks = JNoise.newBuilder()
|
||||||
|
.fastSimplex()
|
||||||
|
.setFrequency(0.15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
double noise = this.streaks.getNoise(point.blockX(), point.blockZ());
|
||||||
|
Block floor = noise > 0.45 ? Block.BLUE_ICE : noise < -0.55 ? Block.ICE : Block.PACKED_ICE;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
|
||||||
|
if(relZ(point, start) >= 2 && relZ(point, start) <= 13 && rnd.nextInt(14) == 0) {
|
||||||
|
unit.modifier().setBlock(
|
||||||
|
point.withY(start.blockY() + 1),
|
||||||
|
Block.SNOW.withProperty("layers", String.valueOf(1 + rnd.nextInt(2)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int wallZ : new int[]{5, 10}) {
|
||||||
|
int gapStart = wallZ == 5 ? 1 + rnd.nextInt(4) : 9 + rnd.nextInt(4);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(x >= gapStart && x < gapStart + 3) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, wallZ), Block.PACKED_ICE);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, wallZ), Block.ICE);
|
||||||
|
if(rnd.nextInt(4) == 0) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 3, wallZ), Block.SNOW.withProperty("layers", "1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
if(z == 5 || z == 10) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, z), Block.PACKED_ICE);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, z), Block.SNOW.withProperty("layers", "1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alte Festungsmauer quer über die Strecke: Drei Blöcke hoch, zu hoch zum
|
||||||
|
* Springen — auf beiden Seiten hängen Leitern zum Drüberklettern.
|
||||||
|
*/
|
||||||
|
class LadderWall extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point ->
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), BlockPallet.STONE.rnd()));
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
for(int y = 1; y <= 3; y++) {
|
||||||
|
for(int z = 7; z <= 8; z++) {
|
||||||
|
Block block = rnd.nextInt(3) == 0 ? Block.MOSSY_STONE_BRICKS : Block.STONE_BRICKS;
|
||||||
|
unit.modifier().setBlock(start.add(x, y, z), block);
|
||||||
|
}
|
||||||
|
unit.modifier().setBlock(start.add(x, y, 6), Block.LADDER.withProperty("facing", "north"));
|
||||||
|
unit.modifier().setBlock(start.add(x, y, 9), Block.LADDER.withProperty("facing", "south"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x % 5 == 2) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 4, 7), Block.LANTERN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Heckengarten: Zwei Blöcke hohe Azaleen-Hecken mit versetzten Durchgängen,
|
||||||
|
* dazwischen blühen Blumen — hübsch, aber im Weg.
|
||||||
|
*/
|
||||||
|
class LeafHedges extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), Block.GRASS_BLOCK);
|
||||||
|
int z = relZ(point, start);
|
||||||
|
if(z % 4 != 0 && z >= 1 && z <= 14 && rnd.nextInt(10) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), BlockPallet.FLOWER.rnd());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int[] rows = {4, 8, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 11 + rnd.nextInt(3) : 1 + rnd.nextInt(3);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(x >= gapStart && x < gapStart + 2) continue;
|
||||||
|
Block leaves = (rnd.nextInt(10) < 3 ? Block.FLOWERING_AZALEA_LEAVES : Block.AZALEA_LEAVES)
|
||||||
|
.withProperty("persistent", "true");
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), leaves);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, rows[i]), leaves);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mangroven-Schlammbecken: Die Becken liegen einen Block tief — man fällt in
|
||||||
|
* den zähen Schlamm und muss sich wieder herauskämpfen, während
|
||||||
|
* Mangrovenwurzeln die trockenen Umwege versperren.
|
||||||
|
*/
|
||||||
|
class MudPools extends Obstacle {
|
||||||
|
private final JNoise pools = JNoise.newBuilder()
|
||||||
|
.fastSimplex()
|
||||||
|
.setFrequency(0.11)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int z = relZ(point, start);
|
||||||
|
double noise = this.pools.getNoise(point.blockX(), point.blockZ());
|
||||||
|
boolean pool = z >= 1 && z <= 14 && noise > 0.05;
|
||||||
|
|
||||||
|
if(pool) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - 1), Block.MUD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block floor = noise > -0.3 ? Block.MUDDY_MANGROVE_ROOTS : Block.GRASS_BLOCK;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - 1), Block.MUD);
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
|
||||||
|
if(z >= 2 && z <= 13 && rnd.nextInt(6) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.MANGROVE_ROOTS);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-4
@@ -1,8 +1,6 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
import de.articdive.jnoise.JNoise;
|
import de.articdive.jnoise.JNoise;
|
||||||
import eu.mhsl.minenet.minigames.util.GeneratorUtils;
|
|
||||||
import net.minestom.server.coordinate.CoordConversion;
|
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.instance.generator.GenerationUnit;
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
@@ -15,8 +13,8 @@ class Mudpit extends Obstacle {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(GenerationUnit unit, Point start) {
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
GeneratorUtils.foreachXZ(unit, point -> {
|
forEachColumn(start, point -> {
|
||||||
double relative = CoordConversion.globalToSectionRelative(point.blockZ());
|
double relative = relZ(point, start);
|
||||||
double modifier = -1.5 * Math.cos(relative * Math.PI/7.5) + 1.5;
|
double modifier = -1.5 * Math.cos(relative * Math.PI/7.5) + 1.5;
|
||||||
double heightAtBlock = start.blockY() + this.curves.getNoise(point.blockX(), point.blockZ()) * modifier;
|
double heightAtBlock = start.blockY() + this.curves.getNoise(point.blockX(), point.blockZ()) * modifier;
|
||||||
unit.modifier().setBlock(point.withY(heightAtBlock), Block.SOUL_SAND);
|
unit.modifier().setBlock(point.withY(heightAtBlock), Block.SOUL_SAND);
|
||||||
|
|||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Riesenpilz-Wäldchen auf Myzel: Die breiten Kappen hängen so tief, dass man
|
||||||
|
* darunter nur kriechend durchkommt — oder außen eng um die Stiele kurvt.
|
||||||
|
*/
|
||||||
|
class MushroomRoofs extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), Block.MYCELIUM);
|
||||||
|
int z = relZ(point, start);
|
||||||
|
if(z >= 1 && z <= 14 && rnd.nextInt(20) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), rnd.nextBoolean() ? Block.RED_MUSHROOM : Block.BROWN_MUSHROOM);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int stemZ : new int[]{4, 8, 12}) {
|
||||||
|
int x = 4 + rnd.nextInt(8);
|
||||||
|
Block cap = rnd.nextBoolean() ? Block.RED_MUSHROOM_BLOCK : Block.BROWN_MUSHROOM_BLOCK;
|
||||||
|
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, stemZ), Block.MUSHROOM_STEM);
|
||||||
|
|
||||||
|
for(int capX = x - 3; capX <= x + 3; capX++) {
|
||||||
|
for(int capZ = stemZ - 1; capZ <= stemZ + 1; capZ++) {
|
||||||
|
if(capX < 0 || capX > 15 || capZ < 0 || capZ > 15) continue;
|
||||||
|
if(Math.abs(capX - x) == 3 && Math.abs(capZ - stemZ) == 1) continue;
|
||||||
|
unit.modifier().setBlock(start.add(capX, 2, capZ), cap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+50
-2
@@ -1,18 +1,66 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.util.GeneratorUtils;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
import net.minestom.server.instance.generator.GenerationUnit;
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public abstract class Obstacle {
|
public abstract class Obstacle {
|
||||||
@SuppressWarnings("StaticInitializerReferencesSubClass")
|
public static final int LENGTH = 16;
|
||||||
private static final List<Obstacle> obstacles = List.of(new Mudpit());
|
|
||||||
|
|
||||||
|
@SuppressWarnings("StaticInitializerReferencesSubClass")
|
||||||
|
private static final List<Obstacle> obstacles = List.of(
|
||||||
|
new Mudpit(),
|
||||||
|
new IceRink(),
|
||||||
|
new HoneyField(),
|
||||||
|
new CobwebGrove(),
|
||||||
|
new BerryPatch(),
|
||||||
|
new WaterChannel(),
|
||||||
|
new HayHurdles(),
|
||||||
|
new SlimePatches(),
|
||||||
|
new MudPools(),
|
||||||
|
new PowderSnowField(),
|
||||||
|
new DripstoneSpikes(),
|
||||||
|
new ChorusGrove(),
|
||||||
|
new BasaltPillars(),
|
||||||
|
new WallSlalom(),
|
||||||
|
new LeafHedges(),
|
||||||
|
new MushroomRoofs(),
|
||||||
|
new SandDunes(),
|
||||||
|
new LadderWall(),
|
||||||
|
new GlassPaneWeave(),
|
||||||
|
new BoulderTrench(),
|
||||||
|
new BambooThicket()
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generiert das Hindernis ab {@code start} (16 breit, {@link #LENGTH} lang).
|
||||||
|
* {@code unit} kann ein Fork sein, der über Chunk-Grenzen reicht — daher nie
|
||||||
|
* über die Unit-Bounds iterieren, sondern über {@link #forEachColumn(Point, Consumer)}.
|
||||||
|
*/
|
||||||
public abstract void generate(GenerationUnit unit, Point start);
|
public abstract void generate(GenerationUnit unit, Point start);
|
||||||
|
|
||||||
public static Obstacle getRandomObstacle() {
|
public static Obstacle getRandomObstacle() {
|
||||||
return obstacles.get(ThreadLocalRandom.current().nextInt(obstacles.size()));
|
return obstacles.get(ThreadLocalRandom.current().nextInt(obstacles.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void forEachColumn(Point start, Consumer<Point> callback) {
|
||||||
|
GeneratorUtils.foreachXZ(start, start.add(15, 0, LENGTH - 1), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int relX(Point point, Point start) {
|
||||||
|
return point.blockX() - start.blockX();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int relZ(Point point, Point start) {
|
||||||
|
return point.blockZ() - start.blockZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Random seededRandom(Point start) {
|
||||||
|
return new Random(start.blockX() * 341873128712L + start.blockZ() * 132897987541L);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verschneites Feld voller Pulverschnee-Verwehungen: Sie liegen auf dem Boden
|
||||||
|
* statt darunter — man watet stark gebremst hindurch, bleibt aber nie stecken
|
||||||
|
* (aus einer Grube käme man ohne Lederstiefel nicht mehr heraus).
|
||||||
|
* Die geschwungene Packeis-Spur ist schnell, aber rutschig — und selbst dort
|
||||||
|
* lauern vereinzelte Verwehungen.
|
||||||
|
*/
|
||||||
|
class PowderSnowField extends Obstacle {
|
||||||
|
private final JNoise drifts = JNoise.newBuilder()
|
||||||
|
.fastSimplex()
|
||||||
|
.setFrequency(0.14)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int z = relZ(point, start);
|
||||||
|
int laneX = 7 + (int) Math.round(3 * Math.sin(z * Math.PI / 7.5));
|
||||||
|
boolean onLane = relX(point, start) == laneX || relX(point, start) == laneX + 1;
|
||||||
|
double noise = this.drifts.getNoise(point.blockX(), point.blockZ());
|
||||||
|
boolean drift = z >= 2 && z <= 13 && noise > (onLane ? 0.45 : 0.0);
|
||||||
|
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), onLane ? Block.PACKED_ICE : Block.SNOW_BLOCK);
|
||||||
|
|
||||||
|
if(drift) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.POWDER_SNOW);
|
||||||
|
if(noise > 0.6) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 2), Block.POWDER_SNOW);
|
||||||
|
}
|
||||||
|
} else if(!onLane && rnd.nextInt(6) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.SNOW.withProperty("layers", "1"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wüstendünen: Sanfte Sandhügel kosten beim Rauflaufen Sprungkraft und Tempo,
|
||||||
|
* vertrocknete Büsche krönen die Kämme. An den Chunk-Rändern flacht das Feld ab.
|
||||||
|
*/
|
||||||
|
class SandDunes extends Obstacle {
|
||||||
|
private final JNoise dunes = JNoise.newBuilder()
|
||||||
|
.fastSimplex()
|
||||||
|
.setFrequency(0.08)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
double taper = -1.25 * Math.cos(relZ(point, start) * Math.PI / 7.5) + 1.25;
|
||||||
|
double noise = (this.dunes.getNoise(point.blockX(), point.blockZ()) + 1) / 2;
|
||||||
|
int top = start.blockY() + (int) Math.round(noise * taper);
|
||||||
|
|
||||||
|
for(int y = start.blockY() - 1; y < top; y++) {
|
||||||
|
unit.modifier().setBlock(point.withY(y), Block.SANDSTONE);
|
||||||
|
}
|
||||||
|
unit.modifier().setBlock(point.withY(top), Block.SAND);
|
||||||
|
|
||||||
|
if(top > start.blockY() + 1 && rnd.nextInt(14) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(top + 1), Block.DEAD_BUSH);
|
||||||
|
} else if(top == start.blockY() && relZ(point, start) >= 2 && relZ(point, start) <= 13 && rnd.nextInt(22) == 0) {
|
||||||
|
int cactusHeight = 1 + rnd.nextInt(2);
|
||||||
|
for(int y = 1; y <= cactusHeight; y++) {
|
||||||
|
unit.modifier().setBlock(point.withY(top + y), Block.CACTUS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schleimmorast: Der Großteil des Bodens ist Slime — bremst stark und lässt
|
||||||
|
* Springer unkontrolliert abprallen. Nur schmale Moos-Inseln bieten Halt.
|
||||||
|
*/
|
||||||
|
class SlimePatches extends Obstacle {
|
||||||
|
private final JNoise blobs = JNoise.newBuilder()
|
||||||
|
.fastSimplex()
|
||||||
|
.setFrequency(0.18)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int z = relZ(point, start);
|
||||||
|
boolean slime = z >= 1 && z <= 14 && this.blobs.getNoise(point.blockX(), point.blockZ()) > -0.2;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), slime ? Block.SLIME_BLOCK : Block.MOSS_BLOCK);
|
||||||
|
|
||||||
|
if(!slime && z >= 2 && z <= 13 && rnd.nextInt(18) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.AZALEA);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mauer-Slalom: Steinmauern sind zu hoch zum Überspringen, die Durchgänge
|
||||||
|
* liegen abwechselnd links und rechts — volle Breite Zickzack.
|
||||||
|
*/
|
||||||
|
class WallSlalom extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point ->
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(4) == 0 ? Block.ANDESITE : Block.STONE));
|
||||||
|
|
||||||
|
int[] rows = {4, 8, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 1 + rnd.nextInt(3) : 10 + rnd.nextInt(3);
|
||||||
|
|
||||||
|
boolean[] hasWall = new boolean[16];
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
hasWall[x] = x < gapStart || x >= gapStart + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(!hasWall[x]) continue;
|
||||||
|
boolean westConnected = x > 0 && hasWall[x - 1];
|
||||||
|
boolean eastConnected = x < 15 && hasWall[x + 1];
|
||||||
|
Block wall = Block.STONE_BRICK_WALL
|
||||||
|
.withProperty("west", westConnected ? "low" : "none")
|
||||||
|
.withProperty("east", eastConnected ? "low" : "none")
|
||||||
|
.withProperty("up", String.valueOf(!westConnected || !eastConnected || x % 4 == 0));
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), wall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breiter Wassergraben mit schmalen Sandufern: Fast der ganze Chunk muss
|
||||||
|
* durchschwommen werden, nur vereinzelte Seerosenblätter helfen Mutigen.
|
||||||
|
*/
|
||||||
|
class WaterChannel extends Obstacle {
|
||||||
|
private static final int[] DEPTHS = {0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, 0};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int depth = DEPTHS[relZ(point, start)];
|
||||||
|
if(depth == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(3) == 0 ? Block.SMOOTH_SANDSTONE : Block.SAND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block bottom = rnd.nextInt(5) == 0 ? Block.DARK_PRISMARINE : Block.PRISMARINE;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - depth), bottom);
|
||||||
|
for(int y = start.blockY() - depth + 1; y <= start.blockY(); y++) {
|
||||||
|
unit.modifier().setBlock(point.withY(y), Block.WATER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(depth >= 2 && rnd.nextInt(4) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - depth + 1), Block.SEAGRASS);
|
||||||
|
}
|
||||||
|
if(rnd.nextInt(20) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.LILY_PAD);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user