From b17543370153fb68e3000dce609d5f6622a58281 Mon Sep 17 00:00:00 2001 From: jannis Date: Mon, 10 Aug 2026 13:41:35 +0200 Subject: [PATCH 1/6] fixed issues after ending in colorjump --- .../instance/game/stateless/types/colorJump/ColorJump.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/colorJump/ColorJump.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/colorJump/ColorJump.java index 6a14bf7..cff28fd 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/colorJump/ColorJump.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/colorJump/ColorJump.java @@ -38,6 +38,7 @@ public class ColorJump extends StatelessGame { private Block blockLastRound; private double roundTime = 5; private final double multiplierNextRoundTime = 0.9; + private boolean isAfterRunning = false; public ColorJump() { super(Dimension.THE_END.key, "ColorJump", new LastWinsScore()); @@ -63,6 +64,7 @@ public class ColorJump extends StatelessGame { @Override protected void onStart() { + this.isAfterRunning = true; this.nextRound(); } @@ -172,5 +174,9 @@ public class ColorJump extends StatelessGame { this.getScore().insertResult(player); player.setGameMode(GameMode.SPECTATOR); } + if(this.isAfterRunning && !this.isRunning) { + player.setGameMode(GameMode.SPECTATOR); + player.teleport(this.getSpawn()); + } } } -- 2.47.3 From 103bd23bf44a34ccd9ff63e0896498cc4c0e346b Mon Sep 17 00:00:00 2001 From: jannis Date: Mon, 10 Aug 2026 18:16:03 +0200 Subject: [PATCH 2/6] fixed issues after ending in colorjump --- .../instance/game/stateless/types/colorJump/ColorJump.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/colorJump/ColorJump.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/colorJump/ColorJump.java index cff28fd..0e6c79d 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/colorJump/ColorJump.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/colorJump/ColorJump.java @@ -38,7 +38,6 @@ public class ColorJump extends StatelessGame { private Block blockLastRound; private double roundTime = 5; private final double multiplierNextRoundTime = 0.9; - private boolean isAfterRunning = false; public ColorJump() { super(Dimension.THE_END.key, "ColorJump", new LastWinsScore()); @@ -64,7 +63,6 @@ public class ColorJump extends StatelessGame { @Override protected void onStart() { - this.isAfterRunning = true; this.nextRound(); } @@ -174,7 +172,7 @@ public class ColorJump extends StatelessGame { this.getScore().insertResult(player); player.setGameMode(GameMode.SPECTATOR); } - if(this.isAfterRunning && !this.isRunning) { + if(!this.isBeforeBeginning && !this.isRunning) { player.setGameMode(GameMode.SPECTATOR); player.teleport(this.getSpawn()); } -- 2.47.3 From 096b03550312fe47dc6e4af11bc74fe3aafcd40f Mon Sep 17 00:00:00 2001 From: jannis Date: Fri, 21 Aug 2026 09:22:19 +0200 Subject: [PATCH 3/6] fixed one issue in block battle --- .../instance/game/stateless/types/blockBattle/BlockBattle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattle.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattle.java index 11018d6..e005442 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattle.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/blockBattle/BlockBattle.java @@ -43,7 +43,7 @@ public class BlockBattle extends StatelessGame { ); this.eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> { - if(this.isBeforeBeginning) finalAttackEvent.setCancelled(true); + if(!this.isRunning) finalAttackEvent.setCancelled(true); finalAttackEvent.setBaseDamage(0); ((Player) finalAttackEvent.getTarget()).setHealth(20); }); -- 2.47.3 From 7e0c126a0d79fe80f883404c9c27996d2798a8f2 Mon Sep 17 00:00:00 2001 From: jannis Date: Wed, 14 Oct 2026 23:00:56 +0200 Subject: [PATCH 4/6] added BuildBattle --- .../minigames/instance/game/GameList.java | 4 +- .../types/buildBattle/BuildBattle.java | 205 ++++++++++++++++++ .../BuildBattleChunkgenerator.java | 50 +++++ .../types/buildBattle/BuildBattleFactory.java | 40 ++++ src/main/resources/lang/locales.map.csv | 7 +- 5 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java create mode 100644 src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleChunkgenerator.java create mode 100644 src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleFactory.java diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java index 504a143..d75ff9b 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/GameList.java @@ -9,6 +9,7 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle.Block import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace.BlockBreakRaceFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace.BoatRaceFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory; +import eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle.BuildBattleFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.colorJump.ColorJumpFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory; @@ -54,7 +55,8 @@ public enum GameList { PILLARS(new PillarsFactory(), GameType.PROTOTYPE), BLOCKBATTLE(new BlockBattleFactory(), GameType.PVP), COLORJUMP(new ColorJumpFactory(), GameType.JUMPNRUN), - PLAYERRACE(new PlayerRaceFactory(), GameType.JUMPNRUN); + PLAYERRACE(new PlayerRaceFactory(), GameType.JUMPNRUN), + BUILDBATTLE(new BuildBattleFactory(), GameType.PROTOTYPE); private final GameFactory factory; private final GameType type; diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java new file mode 100644 index 0000000..f316a9c --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java @@ -0,0 +1,205 @@ +package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle; + +import eu.mhsl.minenet.minigames.instance.Dimension; +import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; +import eu.mhsl.minenet.minigames.score.PointsWinScore; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.title.Title; +import net.minestom.server.MinecraftServer; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.GameMode; +import net.minestom.server.entity.Player; +import net.minestom.server.event.player.PlayerBlockBreakEvent; +import net.minestom.server.event.player.PlayerBlockPlaceEvent; +import net.minestom.server.event.player.PlayerUseItemEvent; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.minestom.server.timer.TaskSchedule; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + + +public class BuildBattle extends StatelessGame { + private static final int height = 100; + private int spawnPosx = 0; + private int spawnPosz = 0; + private final int spacing = 39; + private final int rowCount = 5; + private Map spawnPositions = new WeakHashMap<>(); + private int seconds; + private static final int ratingSeconds = 15; + private final Map scores = new HashMap<>(); + private final Map currentVotes = new HashMap<>(); + private Player currentOwner = null; + private boolean listenerRegistered = false; + private static final List themes = List.of( + "Burg", "Raumschiff", "Unterwasserwelt", "Pizzeria", "Spukhaus", + "Bauernhof", "Dschungel", "Zukunftsstadt", "Piratenschiff", "Vulkan", + "Freizeitpark", "Leuchtturm", "Wikingerdorf", "Weihnachtsmarkt", + "Schloss", "Strand", "Berghütte", "Bahnhof", "Zoo", "Schule", + "Zeitreise", "Ein Haus, das auf dem Kopf steht", "Eine Stadt auf dem Rücken eines Riesen", + "Wohnen in einer Schneekugel", "Alles ist aus Süßigkeiten", "Ein Schiff in der Luft", + "Das Museum der Zukunft", "Das letzte Haus vor dem Weltuntergang", + "Wenn Schweine fliegen könnten", "Das Gefängnis für Creeper", "Die Wohnung von Herobrine", + "Ein Dönerladen im Weltall", "Ein Spa für Enderman", "Der Käse-Palast", + "Mein Zimmer nach 3 Wochen ohne Aufräumen", "Die Hüpfburg des Todes" + ); + private String theme = ""; + + public BuildBattle(int seconds) { + super(Dimension.THE_END.key, "BluidBattle", new PointsWinScore()); + this.seconds = seconds; + this.setGenerator(new BuildBattleChunkgenerator(height)); + } + + @Override + protected void onStart() { + this.theme = themes.get(this.rnd.nextInt(themes.size())); + + Title title = Title.title( + Component.text("Thema", NamedTextColor.GOLD), + Component.text(this.theme, NamedTextColor.YELLOW) + ); + this.getPlayers().forEach(player -> { + player.showTitle(title); + player.sendMessage(Component.text("Euer Thema: ", NamedTextColor.GRAY) + .append(Component.text(this.theme, NamedTextColor.YELLOW))); + }); + + this.getPlayers().forEach(player -> player.setGameMode(GameMode.CREATIVE)); + + MinecraftServer.getSchedulerManager() + .buildTask(() -> { + this.getPlayers().forEach(player -> player.sendMessage("Die Bauzeit ist beendet!")); + this.getPlayers().forEach(p -> { + p.setGameMode(GameMode.ADVENTURE); + p.setAllowFlying(true); + p.setFlying(true); + this.scores.put(p, 0); + }); + MinecraftServer.getSchedulerManager() + .buildTask(() -> { + this.rating(); + }).delay(TaskSchedule.seconds(3)).schedule(); + }).delay(TaskSchedule.seconds(this.seconds)).schedule(); + } + + @Override + protected boolean onPlayerJoin(Player player) { + Pos spawnPos = new Pos(this.spawnPosx * this.spacing, height, this.spawnPosz * this.spacing); + this.spawnPositions.put(player, spawnPos.add(16, 0, 16)); + + if(this.spawnPosx >= this.rowCount) { + this.spawnPosx = 0; + this.spawnPosz++; + } + this.spawnPosx++; + player.setGameMode(GameMode.ADVENTURE); + MinecraftServer.getSchedulerManager().scheduleNextTick(() -> + player.teleport(spawnPos.add(16, 1.5, 16))); + return super.onPlayerJoin(player); + } + + @Override + protected void onBlockBreak(@NotNull PlayerBlockBreakEvent event) { + var player = event.getPlayer(); + Pos blockPos = event.getBlockPosition().asPos(); + event.setCancelled(!this.isInArea(blockPos, player)); + } + + @Override + protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent event) { + var player = event.getPlayer(); + Pos blockPos = event.getBlockPosition().asPos(); + event.setCancelled(!this.isInArea(blockPos, player)); + } + + private void rating() { + List owners = new ArrayList<>(this.getPlayers()); + this.registerRatingListener(); + + AtomicInteger index = new AtomicInteger(0); + MinecraftServer.getSchedulerManager().submitTask(() -> { + if (this.currentOwner != null) this.finishRound(); + + Player next = null; + while (index.get() < owners.size()) { + Player candidate = owners.get(index.getAndIncrement()); + if (candidate.isOnline() && this.spawnPositions.containsKey(candidate)) { + next = candidate; + break; + } + } + + if (next == null) { + return TaskSchedule.stop(); + } + + this.startRound(next); + return TaskSchedule.seconds(ratingSeconds); + }); + } + + private void startRound(Player owner) { + this.currentOwner = owner; + this.currentVotes.clear(); + + Pos plot = this.spawnPositions.get(owner).add(0, 1.5, 0); + this.getPlayers().forEach(p -> { + p.teleport(plot); + p.sendMessage(Component.text("Bewerte das Grundstück von " + owner.getUsername() + "!")); + if (p != owner) this.giveRatingItems(p); + else p.getInventory().clear(); + }); + } + + private void giveRatingItems(Player player) { + Material[] materials = { + Material.RED_CONCRETE, Material.ORANGE_CONCRETE, Material.YELLOW_CONCRETE, + Material.LIME_CONCRETE, Material.GREEN_CONCRETE + }; + player.getInventory().clear(); + for (int i = 0; i < materials.length; i++) { + player.getInventory().setItemStack(i, ItemStack.builder(materials[i]) + .customName(Component.text((i + 1) + " Punkte")) + .build()); + } + } + + private void registerRatingListener() { + if (this.listenerRegistered) return; + this.listenerRegistered = true; + + this.eventNode().addListener(PlayerUseItemEvent.class, event -> { + Player voter = event.getPlayer(); + if (this.currentOwner == null || voter == this.currentOwner) return; + + int slot = voter.getHeldSlot(); + if (slot > 4) return; + + event.setCancelled(true); + this.currentVotes.put(voter, slot + 1); + voter.sendMessage(Component.text("Du hast " + (slot + 1) + " Punkte vergeben.")); + }); + } + + private void finishRound() { + int sum = this.currentVotes.values().stream().mapToInt(Integer::intValue).sum(); + this.getPlayers().forEach(p -> p.getInventory().clear()); + + Player owner = this.currentOwner; + this.currentOwner = null; + this.getScore().insertResult(owner, sum); + } + + private boolean isInArea(Pos blockToCheck, Player player) { + Pos pos1 = this.spawnPositions.get(player).add(15, 1, 15); + Pos pos2 = this.spawnPositions.get(player).add(-16, 300, -16); + return blockToCheck.x() >= Math.min(pos1.x(), pos2.x()) && blockToCheck.x() <= Math.max(pos1.x(), pos2.x()) + && blockToCheck.y() >= Math.min(pos1.y(), pos2.y()) && blockToCheck.y() <= Math.max(pos1.y(), pos2.y()) + && blockToCheck.z() >= Math.min(pos1.z(), pos2.z()) && blockToCheck.z() <= Math.max(pos1.z(), pos2.z()); + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleChunkgenerator.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleChunkgenerator.java new file mode 100644 index 0000000..1db44ef --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleChunkgenerator.java @@ -0,0 +1,50 @@ +package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle; + +import eu.mhsl.minenet.minigames.util.GeneratorUtils; +import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator; +import net.minestom.server.instance.block.Block; + +public class BuildBattleChunkgenerator extends BaseGenerator { + private static final int inner = 32; + private static final int ring = 3; + private static final int wall = 1; + private static final int wallHeight = 200; + + + private static final int period = wall + ring + inner + ring; + + private static final int offset = wall + ring; + + private static final Block middleBlocks = Block.QUARTZ_BLOCK; + private static final Block outerBlocks = Block.STONE_BRICKS; + private static final Block wallBlocks = Block.POLISHED_DEEPSLATE; + + public BuildBattleChunkgenerator(int height) { + this.addMixIn(unit -> { + GeneratorUtils.foreachXZ(unit, point -> { + int lx = Math.floorMod(point.blockX() + offset, period); + int lz = Math.floorMod(point.blockZ() + offset, period); + + boolean isWall = lx < wall || lz < wall; + if (isWall) { + for (int y = 0; y <= wallHeight; y++) { + unit.modifier().setBlock(point.withY(height + y), wallBlocks); + } + return; + } + + unit.modifier().setBlock(point.withY(height), floorBlock(lx, lz)); + }); + }); + } + + private static Block floorBlock(int lx, int lz) { + int innerStart = wall + ring; + int innerEnd = innerStart + inner; + + boolean inInner = lx >= innerStart && lx < innerEnd + && lz >= innerStart && lz < innerEnd; + + return inInner ? middleBlocks : outerBlocks; + } +} diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleFactory.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleFactory.java new file mode 100644 index 0000000..cc89fe1 --- /dev/null +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleFactory.java @@ -0,0 +1,40 @@ +package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle; + +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 BuildBattleFactory implements GameFactory { + @Override + public TranslatedComponent name() { + return TranslatedComponent.byId("game_BuildBattle#name"); + } + + @Override + public ConfigManager configuration() { + return new ConfigManager() + .addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("game_BuildBattle#seconds"), 60, 120, 300, 600)); + } + + @Override + public Game manufacture(Room parent, Map> configuration) throws Exception { + return new BuildBattle(configuration.get("seconds").getAsInt()).setParent(parent); + } + + @Override + public Material symbol() { + return Material.SANDSTONE; + } + + @Override + public TranslatedComponent description() { + return TranslatedComponent.byId("game_BuildBattle#description"); + } +} diff --git a/src/main/resources/lang/locales.map.csv b/src/main/resources/lang/locales.map.csv index a28ce57..9e66330 100644 --- a/src/main/resources/lang/locales.map.csv +++ b/src/main/resources/lang/locales.map.csv @@ -190,4 +190,9 @@ description;Jump on the right color!;Springe auf die richtige Farbe! ;; ns:game_PlayerRace#;; name;Player Race;Wettrennen -description;Get to the other side as quickly as possible!;Komme so schnell wie möglich auf die andere Seite! \ No newline at end of file +description;Get to the other side as quickly as possible!;Komme so schnell wie möglich auf die andere Seite! +;; +ns:game_BuildBattle#;; +name;Build Battle;Bauwettbewerb +description;Build the best creation for the given theme before time runs out and win through the other players’ ratings.;Baue in der Zeit das beste Bauwerk zum Thema und gewinne durch die Bewertung der anderen Spieler. +seconds;Build Time;Bauzeit \ No newline at end of file -- 2.47.3 From 53b13b656098ea3ed0613e14f9cec80b996f0731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Thu, 15 Oct 2026 01:25:59 +0200 Subject: [PATCH 5/6] "Refactored BuildBattle game logic and chunk generator: optimized code structure, improved plot assignment, and enhanced rating system." --- .../types/buildBattle/BuildBattle.java | 169 ++++++++---------- .../BuildBattleChunkgenerator.java | 33 ++-- 2 files changed, 86 insertions(+), 116 deletions(-) diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java index f316a9c..95ce16c 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java @@ -6,7 +6,7 @@ import eu.mhsl.minenet.minigames.score.PointsWinScore; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.title.Title; -import net.minestom.server.MinecraftServer; +import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.GameMode; import net.minestom.server.entity.Player; @@ -19,22 +19,23 @@ import net.minestom.server.timer.TaskSchedule; import org.jetbrains.annotations.NotNull; import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.IntStream; public class BuildBattle extends StatelessGame { private static final int height = 100; - private int spawnPosx = 0; - private int spawnPosz = 0; - private final int spacing = 39; - private final int rowCount = 5; - private Map spawnPositions = new WeakHashMap<>(); - private int seconds; + private static final int plotHalf = BuildBattleChunkgenerator.inner / 2; + private static final int rowCount = 5; private static final int ratingSeconds = 15; - private final Map scores = new HashMap<>(); - private final Map currentVotes = new HashMap<>(); - private Player currentOwner = null; - private boolean listenerRegistered = false; + private static final List ratingMaterials = List.of( + Material.RED_CONCRETE, Material.ORANGE_CONCRETE, Material.YELLOW_CONCRETE, + Material.LIME_CONCRETE, Material.GREEN_CONCRETE + ); + private static final List ratingItems = IntStream.range(0, ratingMaterials.size()) + .mapToObj(i -> ItemStack.builder(ratingMaterials.get(i)) + .customName(Component.text((i + 1) + " Punkte")) + .build()) + .toList(); private static final List themes = List.of( "Burg", "Raumschiff", "Unterwasserwelt", "Pizzeria", "Spukhaus", "Bauernhof", "Dschungel", "Zukunftsstadt", "Piratenschiff", "Vulkan", @@ -47,96 +48,84 @@ public class BuildBattle extends StatelessGame { "Ein Dönerladen im Weltall", "Ein Spa für Enderman", "Der Käse-Palast", "Mein Zimmer nach 3 Wochen ohne Aufräumen", "Die Hüpfburg des Todes" ); - private String theme = ""; + + private int spawnPosx = 0; + private int spawnPosz = 0; + private final Map spawnPositions = new WeakHashMap<>(); + private final int seconds; + private final Map currentVotes = new HashMap<>(); + private Player currentOwner = null; public BuildBattle(int seconds) { - super(Dimension.THE_END.key, "BluidBattle", new PointsWinScore()); + super(Dimension.THE_END.key, "BuildBattle", new PointsWinScore()); this.seconds = seconds; this.setGenerator(new BuildBattleChunkgenerator(height)); + this.eventNode().addListener(PlayerUseItemEvent.class, this::onRatingItemUse); } @Override protected void onStart() { - this.theme = themes.get(this.rnd.nextInt(themes.size())); + String theme = themes.get(this.rnd.nextInt(themes.size())); - Title title = Title.title( + this.showTitle(Title.title( Component.text("Thema", NamedTextColor.GOLD), - Component.text(this.theme, NamedTextColor.YELLOW) - ); - this.getPlayers().forEach(player -> { - player.showTitle(title); - player.sendMessage(Component.text("Euer Thema: ", NamedTextColor.GRAY) - .append(Component.text(this.theme, NamedTextColor.YELLOW))); - }); - + Component.text(theme, NamedTextColor.YELLOW) + )); + this.sendMessage(Component.text("Euer Thema: ", NamedTextColor.GRAY) + .append(Component.text(theme, NamedTextColor.YELLOW))); this.getPlayers().forEach(player -> player.setGameMode(GameMode.CREATIVE)); - MinecraftServer.getSchedulerManager() - .buildTask(() -> { - this.getPlayers().forEach(player -> player.sendMessage("Die Bauzeit ist beendet!")); - this.getPlayers().forEach(p -> { - p.setGameMode(GameMode.ADVENTURE); - p.setAllowFlying(true); - p.setFlying(true); - this.scores.put(p, 0); - }); - MinecraftServer.getSchedulerManager() - .buildTask(() -> { - this.rating(); - }).delay(TaskSchedule.seconds(3)).schedule(); - }).delay(TaskSchedule.seconds(this.seconds)).schedule(); + this.scheduler().scheduleTask(this::endBuildPhase, TaskSchedule.seconds(this.seconds), TaskSchedule.stop()); + } + + private void endBuildPhase() { + this.sendMessage(Component.text("Die Bauzeit ist beendet!")); + this.getPlayers().forEach(p -> { + p.setGameMode(GameMode.ADVENTURE); + p.setAllowFlying(true); + p.setFlying(true); + }); + this.scheduler().scheduleTask(this::rating, TaskSchedule.seconds(3), TaskSchedule.stop()); } @Override protected boolean onPlayerJoin(Player player) { - Pos spawnPos = new Pos(this.spawnPosx * this.spacing, height, this.spawnPosz * this.spacing); - this.spawnPositions.put(player, spawnPos.add(16, 0, 16)); + Pos plotCenter = new Pos( + this.spawnPosx * BuildBattleChunkgenerator.period + plotHalf, + height, + this.spawnPosz * BuildBattleChunkgenerator.period + plotHalf + ); + this.spawnPositions.put(player, plotCenter); - if(this.spawnPosx >= this.rowCount) { + if(this.spawnPosx >= rowCount) { this.spawnPosx = 0; this.spawnPosz++; } this.spawnPosx++; player.setGameMode(GameMode.ADVENTURE); - MinecraftServer.getSchedulerManager().scheduleNextTick(() -> - player.teleport(spawnPos.add(16, 1.5, 16))); + this.scheduler().scheduleNextTick(() -> player.teleport(plotCenter.add(0, 1.5, 0))); return super.onPlayerJoin(player); } @Override protected void onBlockBreak(@NotNull PlayerBlockBreakEvent event) { - var player = event.getPlayer(); - Pos blockPos = event.getBlockPosition().asPos(); - event.setCancelled(!this.isInArea(blockPos, player)); + event.setCancelled(!this.isInArea(event.getBlockPosition(), event.getPlayer())); } @Override protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent event) { - var player = event.getPlayer(); - Pos blockPos = event.getBlockPosition().asPos(); - event.setCancelled(!this.isInArea(blockPos, player)); + event.setCancelled(!this.isInArea(event.getBlockPosition(), event.getPlayer())); } private void rating() { - List owners = new ArrayList<>(this.getPlayers()); - this.registerRatingListener(); + Queue owners = new ArrayDeque<>(this.getPlayers()); - AtomicInteger index = new AtomicInteger(0); - MinecraftServer.getSchedulerManager().submitTask(() -> { + this.scheduler().submitTask(() -> { if (this.currentOwner != null) this.finishRound(); - Player next = null; - while (index.get() < owners.size()) { - Player candidate = owners.get(index.getAndIncrement()); - if (candidate.isOnline() && this.spawnPositions.containsKey(candidate)) { - next = candidate; - break; - } - } - - if (next == null) { - return TaskSchedule.stop(); - } + Player next = owners.poll(); + while (next != null && !(next.isOnline() && this.spawnPositions.containsKey(next))) next = owners.poll(); + if (next == null) return TaskSchedule.stop(); this.startRound(next); return TaskSchedule.seconds(ratingSeconds); @@ -148,42 +137,30 @@ public class BuildBattle extends StatelessGame { this.currentVotes.clear(); Pos plot = this.spawnPositions.get(owner).add(0, 1.5, 0); + this.sendMessage(Component.text("Bewerte das Grundstück von " + owner.getUsername() + "!")); this.getPlayers().forEach(p -> { p.teleport(plot); - p.sendMessage(Component.text("Bewerte das Grundstück von " + owner.getUsername() + "!")); + p.getInventory().clear(); if (p != owner) this.giveRatingItems(p); - else p.getInventory().clear(); }); } private void giveRatingItems(Player player) { - Material[] materials = { - Material.RED_CONCRETE, Material.ORANGE_CONCRETE, Material.YELLOW_CONCRETE, - Material.LIME_CONCRETE, Material.GREEN_CONCRETE - }; - player.getInventory().clear(); - for (int i = 0; i < materials.length; i++) { - player.getInventory().setItemStack(i, ItemStack.builder(materials[i]) - .customName(Component.text((i + 1) + " Punkte")) - .build()); + for (int i = 0; i < ratingItems.size(); i++) { + player.getInventory().setItemStack(i, ratingItems.get(i)); } } - private void registerRatingListener() { - if (this.listenerRegistered) return; - this.listenerRegistered = true; + private void onRatingItemUse(PlayerUseItemEvent event) { + Player voter = event.getPlayer(); + if (this.currentOwner == null || voter == this.currentOwner) return; - this.eventNode().addListener(PlayerUseItemEvent.class, event -> { - Player voter = event.getPlayer(); - if (this.currentOwner == null || voter == this.currentOwner) return; + int slot = voter.getHeldSlot(); + if (slot >= ratingItems.size()) return; - int slot = voter.getHeldSlot(); - if (slot > 4) return; - - event.setCancelled(true); - this.currentVotes.put(voter, slot + 1); - voter.sendMessage(Component.text("Du hast " + (slot + 1) + " Punkte vergeben.")); - }); + event.setCancelled(true); + this.currentVotes.put(voter, slot + 1); + voter.sendMessage(Component.text("Du hast " + (slot + 1) + " Punkte vergeben.")); } private void finishRound() { @@ -195,11 +172,13 @@ public class BuildBattle extends StatelessGame { this.getScore().insertResult(owner, sum); } - private boolean isInArea(Pos blockToCheck, Player player) { - Pos pos1 = this.spawnPositions.get(player).add(15, 1, 15); - Pos pos2 = this.spawnPositions.get(player).add(-16, 300, -16); - return blockToCheck.x() >= Math.min(pos1.x(), pos2.x()) && blockToCheck.x() <= Math.max(pos1.x(), pos2.x()) - && blockToCheck.y() >= Math.min(pos1.y(), pos2.y()) && blockToCheck.y() <= Math.max(pos1.y(), pos2.y()) - && blockToCheck.z() >= Math.min(pos1.z(), pos2.z()) && blockToCheck.z() <= Math.max(pos1.z(), pos2.z()); + private boolean isInArea(Point block, Player player) { + Pos center = this.spawnPositions.get(player); + double dx = block.x() - center.x(); + double dy = block.y() - center.y(); + double dz = block.z() - center.z(); + return dx >= -plotHalf && dx < plotHalf + && dy >= 1 && dy <= 300 + && dz >= -plotHalf && dz < plotHalf; } } diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleChunkgenerator.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleChunkgenerator.java index 1db44ef..af4b744 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleChunkgenerator.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattleChunkgenerator.java @@ -5,43 +5,34 @@ import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator; import net.minestom.server.instance.block.Block; public class BuildBattleChunkgenerator extends BaseGenerator { - private static final int inner = 32; + static final int inner = 32; private static final int ring = 3; private static final int wall = 1; private static final int wallHeight = 200; + static final int period = wall + ring + inner + ring; - private static final int period = wall + ring + inner + ring; - - private static final int offset = wall + ring; + private static final int innerStart = wall + ring; + private static final int innerEnd = innerStart + inner; private static final Block middleBlocks = Block.QUARTZ_BLOCK; private static final Block outerBlocks = Block.STONE_BRICKS; private static final Block wallBlocks = Block.POLISHED_DEEPSLATE; public BuildBattleChunkgenerator(int height) { - this.addMixIn(unit -> { - GeneratorUtils.foreachXZ(unit, point -> { - int lx = Math.floorMod(point.blockX() + offset, period); - int lz = Math.floorMod(point.blockZ() + offset, period); - - boolean isWall = lx < wall || lz < wall; - if (isWall) { - for (int y = 0; y <= wallHeight; y++) { - unit.modifier().setBlock(point.withY(height + y), wallBlocks); - } - return; - } + this.addMixIn(unit -> GeneratorUtils.foreachXZ(unit, point -> { + int lx = Math.floorMod(point.blockX() + innerStart, period); + int lz = Math.floorMod(point.blockZ() + innerStart, period); + if (lx < wall || lz < wall) { + unit.modifier().fill(point.withY(height), point.add(1, 0, 1).withY(height + wallHeight + 1), wallBlocks); + } else { unit.modifier().setBlock(point.withY(height), floorBlock(lx, lz)); - }); - }); + } + })); } private static Block floorBlock(int lx, int lz) { - int innerStart = wall + ring; - int innerEnd = innerStart + inner; - boolean inInner = lx >= innerStart && lx < innerEnd && lz >= innerStart && lz < innerEnd; -- 2.47.3 From 75cd304bda987552dc5a2bcd242a2c61b1ac9189 Mon Sep 17 00:00:00 2001 From: jannis Date: Fri, 16 Oct 2026 20:43:14 +0200 Subject: [PATCH 6/6] fixed issues in BuildBattle --- .../stateless/types/buildBattle/BuildBattle.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java index 95ce16c..8145ad8 100644 --- a/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java +++ b/src/main/java/eu/mhsl/minenet/minigames/instance/game/stateless/types/buildBattle/BuildBattle.java @@ -97,11 +97,11 @@ public class BuildBattle extends StatelessGame { ); this.spawnPositions.put(player, plotCenter); - if(this.spawnPosx >= rowCount) { + if(this.spawnPosx >= rowCount - 1) { this.spawnPosx = 0; this.spawnPosz++; - } - this.spawnPosx++; + } else this.spawnPosx ++; + player.setGameMode(GameMode.ADVENTURE); this.scheduler().scheduleNextTick(() -> player.teleport(plotCenter.add(0, 1.5, 0))); return super.onPlayerJoin(player); @@ -164,12 +164,14 @@ public class BuildBattle extends StatelessGame { } private void finishRound() { - int sum = this.currentVotes.values().stream().mapToInt(Integer::intValue).sum(); - this.getPlayers().forEach(p -> p.getInventory().clear()); + int voteSum = this.currentVotes.values().stream() + .mapToInt(Integer::intValue) + .sum(); + int score = (int) Math.round((double) voteSum / this.getPlayers().size()); - Player owner = this.currentOwner; + this.getPlayers().forEach(p -> p.getInventory().clear()); + this.getScore().insertResult(this.currentOwner, score); this.currentOwner = null; - this.getScore().insertResult(owner, sum); } private boolean isInArea(Point block, Player player) { -- 2.47.3