aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranhgelus <anhgelus.morhtuuzh@proton.me>2024-08-21 23:31:37 +0000
committeranhgelus <anhgelus.morhtuuzh@proton.me>2024-08-21 23:31:37 +0000
commit7f09ec7abaa9bb6b8325f56250562c97d7d3a799 (patch)
treeefd5eb8d802ca7f199fd12c994d6dbc473dfe011
parente0a3392795c7abc0c1080d71b6c0d83c8de78a2d (diff)
feat(game): create game and command to manage it
-rw-r--r--src/main/java/world/anhgelus/molehunt/Game.java119
-rw-r--r--src/main/java/world/anhgelus/molehunt/Molehunt.java49
-rw-r--r--src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java53
-rw-r--r--src/main/resources/molehunt.mixins.json1
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