added jumpDive game

This commit is contained in:
Elias Müller 2025-03-03 01:28:29 +01:00
parent 3f2ba1e428
commit 5ca8ad8bd7
7 changed files with 156 additions and 6 deletions

View File

@ -41,7 +41,7 @@ public enum Commands {
static { static {
MinecraftServer.getCommandManager().setUnknownCommandCallback((sender, command) -> { MinecraftServer.getCommandManager().setUnknownCommandCallback((sender, command) -> {
if(command.isBlank()) return; if(command.isBlank()) return;
new ChatMessage(Icon.ERROR).appendStatic("Unknown command").quote(command).send(sender); new ChatMessage(Icon.ERROR).appendStatic("Unknown command: ").quote(command).send(sender);
}); });
} }
} }

View File

@ -51,7 +51,7 @@ public class PlayerLoginHandler implements EventListener<AsyncPlayerConfiguratio
MoveInstance.move(p, Hub.INSTANCE); MoveInstance.move(p, Hub.INSTANCE);
} }
}, },
TaskSchedule.seconds(5), TaskSchedule.seconds(1),
TaskSchedule.stop() TaskSchedule.stop()
); );

View File

@ -8,6 +8,7 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.Backroo
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory; 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.acidRain.AcidRainFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive.JumpDiveFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun.MinerunFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun.MinerunFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef.SpleefFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef.SpleefFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight.StickFightFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight.StickFightFactory;
@ -30,7 +31,8 @@ public enum GameList {
ANVILRUN(new AnvilRunFactory(), GameType.PVE), ANVILRUN(new AnvilRunFactory(), GameType.PVE),
ACIDRAIN(new AcidRainFactory(), GameType.PVE), ACIDRAIN(new AcidRainFactory(), GameType.PVE),
ELYTRARACE(new ElytraRaceFactory(), GameType.PVP), ELYTRARACE(new ElytraRaceFactory(), GameType.PVP),
SPLEEF(new SpleefFactory(), GameType.PVP); SPLEEF(new SpleefFactory(), GameType.PVP),
JUMPDIVE(new JumpDiveFactory(), GameType.JUMPNRUN);
private final GameFactory factory; private final GameFactory factory;
private final GameType type; private final GameType type;

View File

@ -11,6 +11,7 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.registry.DynamicRegistry; import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.timer.ExecutionType; import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.Task;
import net.minestom.server.timer.TaskSchedule; import net.minestom.server.timer.TaskSchedule;
import net.minestom.server.world.DimensionType; import net.minestom.server.world.DimensionType;
@ -20,6 +21,7 @@ import java.util.concurrent.CompletableFuture;
public class StatelessGame extends Game { public class StatelessGame extends Game {
private final String name; private final String name;
private final Score score; private final Score score;
private Task timeLimitTask;
private int timeLimit = 0; private int timeLimit = 0;
private int timePlayed = 0; private int timePlayed = 0;
@ -40,8 +42,12 @@ public class StatelessGame extends Game {
public void setTimeLimit(int limit) { public void setTimeLimit(int limit) {
this.timeLimit = limit; this.timeLimit = limit;
if(timeLimit > 0) { if(this.timeLimitTask != null) {
scheduler().submitTask(() -> { this.timeLimitTask.cancel();
this.timePlayed = 0;
}
if(this.timeLimit > 0) {
this.timeLimitTask = scheduler().submitTask(() -> {
if(!isRunning || timeLimit == 0) return TaskSchedule.stop(); if(!isRunning || timeLimit == 0) return TaskSchedule.stop();
if(timeLimit <= timePlayed) { if(timeLimit <= timePlayed) {
stop(); stop();

View File

@ -0,0 +1,99 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.PointsWinScore;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.world.BlockPallet;
import net.kyori.adventure.sound.Sound;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
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.sound.SoundEvent;
import org.jetbrains.annotations.NotNull;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
public class JumpDive extends StatelessGame {
private final int radius;
private final int height;
private final int timeLimit;
private final WeakHashMap<Player, Integer> scores = new WeakHashMap<>();
public JumpDive(int radius, int height, int timeLimit) {
super(Dimension.OVERWORLD.key, "jumpDive", new PointsWinScore());
this.radius = radius;
this.height = height;
this.timeLimit = timeLimit;
}
@Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = -radius*2; x <= radius*2; x++) {
for(int z = -radius*2; z <= radius*2; z++) {
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) {
batch.setBlock(x, height, z, BlockPallet.STONE.rnd());
} else {
batch.setBlock(x, 0, z, BlockPallet.GROUND.rnd());
batch.setBlock(x, 1, z, Block.WATER);
}
}
}
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
}
@Override
protected void onStart() {
setTimeLimit(timeLimit);
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player p = playerMoveEvent.getPlayer();
if(
p.isOnGround() && playerMoveEvent.getNewPosition().y() < height
|| playerMoveEvent.getNewPosition().y() < 0
|| isBeforeBeginning && playerMoveEvent.getNewPosition().y() < height
) {
p.teleport(getSpawn());
playerMoveEvent.setCancelled(true);
}
if(
playerMoveEvent.getNewPosition().y() <= 1
&& playerMoveEvent.getNewPosition().distance(0, 1, 0) < radius + 0.5
&& !(!isBeforeBeginning && !isRunning)
) {
setBlock(playerMoveEvent.getNewPosition().withY(1), Block.REDSTONE_BLOCK);
scores.merge(p, 1, Integer::sum);
p.teleport(getSpawn());
playerMoveEvent.setCancelled(true);
p.playSound(Sound.sound(SoundEvent.ENTITY_EXPERIENCE_ORB_PICKUP, Sound.Source.PLAYER, 2f, 2f));
}
}
@Override
protected void onStop() {
getPlayers().forEach(player -> getScore().insertResult(player, scores.getOrDefault(player, 0)));
}
@Override
public Pos getSpawn() {
double theta = rnd.nextDouble() * 2 * Math.PI;
double spawnRadius = radius + 2;
double x = spawnRadius * Math.cos(theta);
double z = spawnRadius * Math.sin(theta);
return new Pos(x, height + 2, z).withLookAt(new Pos(0, height, 0));
}
}

View File

@ -0,0 +1,43 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive;
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.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.message.component.TranslatedComponent;
import net.minestom.server.item.Material;
import java.util.Map;
public class JumpDiveFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("gmae_jumpDive#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_Deathcube#description");
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 5, 8, 10, 12, 14, 16))
.addOption(new NumericOption("height", Material.SCAFFOLDING, TranslatedComponent.byId("optionCommon#height"), 30, 60, 90))
.addOption(new NumericOption("timeLimit", Material.CLOCK, TranslatedComponent.byId("optionCommon#timeLimit"), 60, 120, 180, 240, 300));
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new JumpDive(configuration.get("radius").getAsInt(), configuration.get("height").getAsInt(), configuration.get("timeLimit").getAsInt()).setParent(parent);
}
@Override
public Material symbol() {
return Material.WATER_BUCKET;
}
}

View File

@ -20,6 +20,6 @@ public class SkinCache {
MinecraftServer.getSchedulerManager().scheduleTask(() -> { MinecraftServer.getSchedulerManager().scheduleTask(() -> {
p.setSkin(SkinCache.getSkin(p.getUsername())); p.setSkin(SkinCache.getSkin(p.getUsername()));
return TaskSchedule.stop(); return TaskSchedule.stop();
}, TaskSchedule.seconds(3)); }, TaskSchedule.millis(500));
} }
} }