Merge pull request 'develop-anvilRun' (#1) from develop-anvilRun into develop

Reviewed-on: #1
This commit is contained in:
Lars Neuhaus 2024-10-19 14:35:16 +00:00
commit 21ab8c4bd3
8 changed files with 172 additions and 8 deletions

View File

@ -118,7 +118,6 @@ public abstract class Game extends MineNetInstance implements Spawnable {
protected void onStop() {} protected void onStop() {}
protected void onUnload() {} protected void onUnload() {}
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
} }

View File

@ -1,6 +1,7 @@
package eu.mhsl.minenet.minigames.instance.game; 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.bowSpleef.BowSpleefFactory; 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.elytraRace.ElytraRaceFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
@ -22,6 +23,7 @@ public enum GameList {
TOWERDEFENSE(new TowerdefenseFactory(), GameType.PROTOTYPE), TOWERDEFENSE(new TowerdefenseFactory(), GameType.PROTOTYPE),
BEDWARS(new BedwarsFactory(), GameType.PROTOTYPE), BEDWARS(new BedwarsFactory(), GameType.PROTOTYPE),
BACKROOMS(new BackroomsFactory(), GameType.PROTOTYPE), BACKROOMS(new BackroomsFactory(), GameType.PROTOTYPE),
ANVILRUN(new AnvilRunFactory(), GameType.PROTOTYPE),
TNTRUN(new TntRunFactory(), GameType.OTHER), TNTRUN(new TntRunFactory(), GameType.OTHER),
ACIDRAIN(new AcidRainFactory(), GameType.PVE), ACIDRAIN(new AcidRainFactory(), GameType.PVE),
ELYTRARACE(new ElytraRaceFactory(), GameType.PVP), ELYTRARACE(new ElytraRaceFactory(), GameType.PVP),

View File

@ -23,6 +23,7 @@ public class StatelessGame extends Game {
private int timeLimit = 0; private int timeLimit = 0;
private int timePlayed = 0; private int timePlayed = 0;
public StatelessGame(DynamicRegistry.Key<DimensionType> dimensionType, String gameName, Score score) { public StatelessGame(DynamicRegistry.Key<DimensionType> dimensionType, String gameName, Score score) {
super(dimensionType); super(dimensionType);
this.score = score; this.score = score;

View File

@ -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<Pos> 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<Void> 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<this.anvilSpawnPositions.size(); i++) {
final int j = i;
scheduler.scheduleTask(
() -> 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);
}
}

View File

@ -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<String, Option<?>> configuration) {
return new AnvilRun(configuration.get("radius").getAsInt(), configuration.get("seconds").getAsInt()).setParent(parent);
}
@Override
public Material symbol() {
return Material.ANVIL;
}
}

View File

@ -6,9 +6,6 @@ import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.instance.Dimension; import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.world.BlockPallet; 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.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.coordinate.Pos;
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;
@ -60,12 +57,20 @@ class Deathcube extends StatelessGame {
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
super.onPlayerMove(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()); if(playerMoveEvent.getNewPosition().y() > height) getScore().insertResult(playerMoveEvent.getPlayer());
} }
@Override @Override
public Pos getSpawn() { public Pos getSpawn() {
return new Pos(0, 50, 30); return new Pos(0, 50, -(radius+5));
} }
} }

View File

@ -105,7 +105,7 @@ public class ElytraRace extends StatelessGame {
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
Point spawnpoint = new Pos(vale.getXShiftAtZ(0), -46, 0); 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()); setBlock(point, BlockPallet.STREET.rnd());
}); });
@ -130,6 +130,11 @@ public class ElytraRace extends StatelessGame {
Player player = playerMoveEvent.getPlayer(); Player player = playerMoveEvent.getPlayer();
Point newPos = playerMoveEvent.getNewPosition(); Point newPos = playerMoveEvent.getNewPosition();
if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() < getSpawn().y()) {
player.teleport(getSpawn());
return;
}
playerCheckpoints.putIfAbsent(player, new CheckPointData(ringSpacing, ringSpacing * 2)); playerCheckpoints.putIfAbsent(player, new CheckPointData(ringSpacing, ringSpacing * 2));
if(newPos.z() > generatedUntil - ringSpacing) { if(newPos.z() > generatedUntil - ringSpacing) {

View File

@ -53,7 +53,7 @@ public class CircularPlateTerrainGenerator extends PlateTerrainGenerator {
double distance = bottom.distance(new Pos(0, 0, 0)); double distance = bottom.distance(new Pos(0, 0, 0));
if(distance <= this.size && generatePlate()) { 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; continue;
} }