diff options
| author | anhgelus <anhgelus.morhtuuzh@proton.me> | 2024-08-21 23:31:37 +0000 |
|---|---|---|
| committer | anhgelus <anhgelus.morhtuuzh@proton.me> | 2024-08-21 23:31:37 +0000 |
| commit | 7f09ec7abaa9bb6b8325f56250562c97d7d3a799 (patch) | |
| tree | efd5eb8d802ca7f199fd12c994d6dbc473dfe011 /src | |
| parent | e0a3392795c7abc0c1080d71b6c0d83c8de78a2d (diff) | |
feat(game): create game and command to manage it
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/java/world/anhgelus/molehunt/Game.java | 119 | ||||
| -rw-r--r-- | src/main/java/world/anhgelus/molehunt/Molehunt.java | 49 | ||||
| -rw-r--r-- | src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java | 53 | ||||
| -rw-r--r-- | src/main/resources/molehunt.mixins.json | 1 |
4 files changed, 217 insertions, 5 deletions
diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index f084bfd..537055c 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -1,2 +1,117 @@ -package world.anhgelus.molehunt;public class Game { -} +package world.anhgelus.molehunt;
+
+import net.minecraft.network.packet.s2c.play.OverlayMessageS2CPacket;
+import net.minecraft.network.packet.s2c.play.SubtitleS2CPacket;
+import net.minecraft.network.packet.s2c.play.TitleFadeS2CPacket;
+import net.minecraft.network.packet.s2c.play.TitleS2CPacket;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.network.ServerPlayerEntity;
+import net.minecraft.text.Text;
+import net.minecraft.world.GameRules;
+import world.anhgelus.molehunt.utils.TimeUtils;
+
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class Game {
+
+ final private Timer timer = new Timer();
+ final public static int DEFAULT_TIME = 90*60; // 1:30
+ private int remaining = DEFAULT_TIME;
+
+ final private MinecraftServer server;
+
+ final private List<ServerPlayerEntity> moles = new ArrayList<>();
+
+ public Game(MinecraftServer server) {
+ this.server = server;
+ }
+
+ public void start() {
+ final int n = (server.getCurrentPlayerCount() - server.getCurrentPlayerCount() % 4)/4;
+ final var playerManager = server.getPlayerManager();
+ final var players = playerManager.getPlayerList();
+ for (int i = 0; i < n; i++) {
+ final var r = ThreadLocalRandom.current().nextInt(0, players.size());
+ final var mole = players.get(r);
+ if (mole == null) throw new IllegalStateException("Mole is null!");
+ moles.add(mole);
+ players.remove(r);
+ }
+
+ server.getGameRules().get(GameRules.SHOW_DEATH_MESSAGES).set(false, server);
+ server.getGameRules().get(GameRules.ANNOUNCE_ADVANCEMENTS).set(false, server);
+
+ final var title = new TitleS2CPacket(Text.of("You are..."));
+ final var timing = new TitleFadeS2CPacket(20, 40, 20);
+ playerManager.getPlayerList().forEach(p -> {
+ p.networkHandler.sendPacket(timing);
+ p.networkHandler.sendPacket(title);
+ });
+ timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ playerManager.getPlayerList().forEach(p -> {
+ p.networkHandler.sendPacket(timing);
+ if (moles.contains(p)) {
+ p.networkHandler.sendPacket(new TitleS2CPacket(Text.of("The Mole!")));
+ p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.of("get the list of moles with /molehunt moles")));
+ } else {
+ p.networkHandler.sendPacket(new TitleS2CPacket(Text.of("Not the Mole!")));
+ }
+ });
+ server.getOverworld().setTimeOfDay(0);
+ timer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ remaining--;
+ playerManager.sendToAll(new OverlayMessageS2CPacket(Text.of(getShortRemainingText())));
+ if (remaining == 0) {
+ end();
+ }
+ }
+ }, 1000L, 1000L);
+ timer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ playerManager.broadcast(getRemainingText(), false);
+ }
+ }, 10*60*1000L, 10*60*1000L);
+ }
+ }, 4*1000);
+ }
+
+ public void stop() {
+ server.getPlayerManager().broadcast(Text.of("Game stopped"), false);
+ end();
+ }
+
+ public void end() {
+ timer.cancel();
+ // affiche les gagnants
+ }
+
+ public int getRemaining() {
+ return remaining;
+ }
+
+ public Text getRemainingText() {
+ return Text.of("Time remaining: "+ TimeUtils.printTime(remaining));
+ }
+
+ public Text getShortRemainingText() {
+ return Text.of("§c" + TimeUtils.printShortTime(remaining));
+ }
+
+ public List<ServerPlayerEntity> getMoles() {
+ return moles;
+ }
+
+ public boolean isAMole(ServerPlayerEntity player) {
+ return moles.contains(player);
+ }
+
+ public boolean gameFinished() {
+ return new HashSet<>(moles).containsAll(server.getPlayerManager().getPlayerList());
+ }
+}
diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index a1333a4..4edaf24 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -1,16 +1,65 @@ package world.anhgelus.molehunt; +import com.mojang.brigadier.Command; +import com.mojang.brigadier.arguments.StringArgumentType; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; +import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Objects; +import java.util.stream.Collectors; + +import static net.minecraft.server.command.CommandManager.literal; + + public class Molehunt implements ModInitializer { public static final String MOD_ID = "molehunt"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + public Game game; @Override public void onInitialize() { LOGGER.info("Initializing Molehunt"); + + final var command = literal("molehunt"); + command.then(literal("start").requires(source -> source.hasPermissionLevel(1)).executes(context -> { + game = new Game(context.getSource().getServer()); + game.start(); + return Command.SINGLE_SUCCESS; + })); + command.then(literal("time").executes(context -> { + context.getSource().sendFeedback(() -> game.getRemainingText(), false); + return Command.SINGLE_SUCCESS; + })); + command.then(literal("moles").requires(source -> { + if (game == null) { + return false; + } + return game.isAMole(source.getPlayer()); + }).executes(context -> { + context.getSource().sendFeedback(() -> Text.literal( + "List of moles: " + game.getMoles().stream().map(ServerPlayerEntity::getDisplayName).filter(Objects::nonNull).map(Text::toString).collect(Collectors.joining(", "))), + false); + return Command.SINGLE_SUCCESS; + })); + command.then(literal("stop").requires(source -> source.hasPermissionLevel(1)).executes(context -> { + game.stop(); + return Command.SINGLE_SUCCESS; + })); + + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(command)); + +// ServerMessageEvents.ALLOW_CHAT_MESSAGE.register((message, sender, params) -> false); + + ServerLivingEntityEvents.AFTER_DEATH.register((entity, damageSource) -> { + if (!(entity instanceof ServerPlayerEntity)) return; + if (game.gameFinished()) game.end(); + }); } } diff --git a/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java b/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java index 8db8eb0..859f574 100644 --- a/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java +++ b/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java @@ -1,2 +1,51 @@ -package world.anhgelus.molehunt.utils;public class TimeUtils { -} +package world.anhgelus.molehunt.utils;
+
+public class TimeUtils {
+
+ private record Time(long hours, long minutes, long seconds) {}
+
+ public static String printTime(long time) {
+ final var pt = generateTime(time);
+
+ StringBuilder sb = new StringBuilder();
+ if (pt.hours != 0) {
+ sb.append(pt.hours).append(" hours ");
+ }
+ if (pt.minutes != 0 || pt.hours != 0) {
+ sb.append(pt.minutes).append(" minutes ");
+ }
+ sb.append(pt.seconds).append(" seconds");
+
+ return sb.toString();
+ }
+
+ public static String printShortTime(long time) {
+ final var pt = generateTime(time);
+
+ return padLeft(pt.hours) + ":" +
+ padLeft(pt.minutes) + ":" +
+ padLeft(pt.seconds);
+ }
+
+ private static Time generateTime(long time) {
+ long hours = 0;
+ if (time > 3600) {
+ hours = Math.floorDiv(time, 3600);
+ }
+ long minutes = 0;
+ if (hours != 0 || time > 60) {
+ minutes = Math.floorDiv(time - hours * 3600, 60);
+ }
+ long seconds = (long) Math.floor(time - hours * 3600 - minutes * 60);
+ return new Time(hours, minutes, seconds);
+ }
+
+ private static String padLeft(long n) {
+ if (n < 10 && n != 0) {
+ return "0" + Math.round(n);
+ } else if (n == 0) {
+ return "00";
+ }
+ return Long.toString(Math.round(n));
+ }
+}
diff --git a/src/main/resources/molehunt.mixins.json b/src/main/resources/molehunt.mixins.json index a691723..5b76af8 100644 --- a/src/main/resources/molehunt.mixins.json +++ b/src/main/resources/molehunt.mixins.json @@ -4,7 +4,6 @@ "package": "world.anhgelus.molehunt.mixin", "compatibilityLevel": "JAVA_21", "mixins": [ - "NoPlayerList" ], "injectors": { "defaultRequire": 1 |
