20 Commits

Author SHA1 Message Date
e760cdb2c6 removed 0 add option seconds 2026-01-10 21:41:45 +01:00
c111c027ff added second option to game selection menu, finished stickfight 2026-01-10 17:41:19 +01:00
2f8ff36e5e Merge branch 'develop' into develop-jannis 2026-01-10 13:48:39 +00:00
5cb71c5c32 changed respawn height on first respawn in elytrarace
added level indicator for stickfight
2026-01-10 14:47:57 +01:00
5ab42fde4b Merge pull request 'added stick to inventory for stick fight' (#7) from develop-stickfight into develop
Reviewed-on: #7
Reviewed-by: Elias Müller <elias@elias-mueller.com>
2026-01-10 13:10:26 +00:00
d5c2f06409 elytra race fix boost ring 1 2026-01-10 14:02:21 +01:00
1ff8cca7e9 added stick to inventory for stick fight 2026-01-10 00:41:24 +01:00
47c40c4941 fixed winning condition in SpaceSnake 2026-01-07 15:06:12 +01:00
d4a7fcada7 improved chat formatting by adding username colors and better separators 2026-01-02 02:26:56 +01:00
a0124f1bcb Merge remote-tracking branch 'origin/develop' into develop 2025-12-28 18:53:52 +01:00
c79fbf3136 fixed tournament random order at the end 2025-12-28 18:53:14 +01:00
660eb645e4 Merge remote-tracking branch 'origin/develop' into develop 2025-12-27 11:37:36 +01:00
3c50aca1e8 updated reward API endpoint in PublishRewardCommand 2025-12-27 11:37:33 +01:00
865cdfa605 added gamemode change to survival on leaving tetris 2025-12-25 00:52:56 +01:00
fe88e3f921 added slowness to tetris 2025-12-24 13:20:05 +01:00
5e94479949 updated locales file with enhanced Stickfight description and added BoatRace entry 2025-12-21 10:42:23 +01:00
b15c9c97b0 finished boat race 2025-12-18 21:36:22 +01:00
334e130cf6 fixed boat stuttering 2025-12-18 20:02:26 +01:00
31385fbd7f cleanup 2025-12-13 15:15:23 +01:00
b1b1e24104 added BoatRace game with factory and updated GameList 2025-12-03 23:08:55 +01:00
34 changed files with 168 additions and 23 deletions

View File

@@ -60,9 +60,9 @@ dependencies {
implementation 'io.github.TogAr2:MinestomPvP:PR62-SNAPSHOT'
// Hephaestus engine
implementation("team.unnamed:hephaestus-api:0.2.1-SNAPSHOT")
implementation("team.unnamed:hephaestus-reader-blockbench:0.2.1-SNAPSHOT")
implementation("team.unnamed:hephaestus-runtime-minestom:0.2.1-SNAPSHOT")
// implementation("team.unnamed:hephaestus-api:0.2.1-SNAPSHOT")
// implementation("team.unnamed:hephaestus-reader-blockbench:0.2.1-SNAPSHOT")
// implementation("team.unnamed:hephaestus-runtime-minestom:0.2.1-SNAPSHOT")
}
tasks {

View File

@@ -25,7 +25,7 @@ public class PublishRewardCommand extends PrivilegedCommand {
String rewardRequestJson = new Gson().toJson(room.getTournament().getRewards());
HttpRequest giveRewardsRequest = HttpRequest.newBuilder()
.uri(new URI("http://10.20.7.1:8080/api/event/reward"))
.uri(new URI("http://10.20.9.3:8080/api/event/reward"))
.POST(HttpRequest.BodyPublishers.ofString(rewardRequestJson))
.build();

View File

@@ -2,6 +2,8 @@ package eu.mhsl.minenet.minigames.handler.global;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.event.EventListener;
import net.minestom.server.event.player.PlayerChatEvent;
import org.jetbrains.annotations.NotNull;
@@ -14,7 +16,14 @@ public class ChatFormatHandler implements EventListener<PlayerChatEvent> {
@Override
public @NotNull Result run(@NotNull PlayerChatEvent event) {
event.setFormattedMessage(new ChatMessage(Icon.CHAT).appendStatic(event.getRawMessage()).build(event.getPlayer()));
NamedTextColor color = event.getPlayer().getPermissionLevel() > 0 ? NamedTextColor.AQUA : NamedTextColor.GRAY;
event.setFormattedMessage(
new ChatMessage(Icon.CHAT)
.appendStatic(Component.text(event.getPlayer().getUsername(), color))
.appendStatic(Component.text(" > ", NamedTextColor.DARK_GRAY))
.appendStatic(event.getRawMessage())
.build(event.getPlayer())
);
return Result.SUCCESS;
}
}

View File

@@ -6,6 +6,7 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRun
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory;
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.deathcube.DeathcubeFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory;
@@ -44,7 +45,8 @@ public enum GameList {
HIGHGROUND(new HighGroundFactory(), GameType.PVP),
FASTBRIDGE(new FastbridgeFactory(), GameType.OTHER),
BLOCKBREAKRACE(new BlockBreakRaceFactory(), GameType.OTHER),
SPACESNAKE(new SpaceSnakeFactory(), GameType.PVP);
SPACESNAKE(new SpaceSnakeFactory(), GameType.PVP),
BOATRACE(new BoatRaceFactory(), GameType.OTHER);
private final GameFactory factory;
private final GameType type;

View File

@@ -0,0 +1,75 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace;
import eu.mhsl.minenet.minigames.Resource;
import eu.mhsl.minenet.minigames.handler.global.PlayerLoginHandler;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
import eu.mhsl.minenet.minigames.util.CommonProperties;
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.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.anvil.AnvilLoader;
import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
public class BoatRace extends StatelessGame {
public BoatRace() {
super(Dimension.OVERWORLD.key, "boatRace", new FirstWinsScore());
this.setChunkLoader(new AnvilLoader(Resource.GAME_MAP.getPath().resolve("boatRace/woodlandMansion")));
}
@Override
protected boolean onPlayerJoin(Player p) {
Entity boat = new Entity(EntityType.OAK_BOAT);
boat.setInstance(this, this.getSpawn());
boat.setSynchronizationTicks(100000);
PlayerLoginHandler.globalTeam.addMember(boat.getUuid().toString());
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> boat.addPassenger(p));
return super.onPlayerJoin(p);
}
@Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
for(int z = 9; z <= 32; z++) {
this.setBlock(31, 235, z, Block.CHERRY_FENCE.withProperties(CommonProperties.fenceNorthSouth));
}
}
@Override
protected void onStart() {
for(int z = 9; z <= 32; z++) {
this.setBlock(31, 235, z, Block.AIR);
}
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent event) {
if (this.isBeforeBeginning) return;
if(event.getNewPosition().z() > 469) {
Player player = event.getPlayer();
this.getScore().insertResult(player);
Entity vehicle = player.getVehicle();
if(vehicle != null) {
vehicle.removePassenger(player);
player.teleport(player.getPosition().withY(y -> y + 3));
player.setGameMode(GameMode.SPECTATOR);
vehicle.remove();
}
}
}
@Override
public Pos getSpawn() {
return new Pos(20, 236, 20, -90, 0);
}
}

View File

@@ -0,0 +1,27 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace;
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.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import net.minestom.server.item.Material;
import java.util.Map;
public class BoatRaceFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_BoatRace#name");
}
@Override
public Material symbol() {
return Material.OAK_BOAT;
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new BoatRace().setParent(parent);
}
}

View File

@@ -133,7 +133,7 @@ public class ElytraRace extends StatelessGame {
return;
}
this.playerCheckpoints.putIfAbsent(player, new CheckPointData(this.ringSpacing, this.ringSpacing * 2));
this.playerCheckpoints.putIfAbsent(player, new CheckPointData(0, this.ringSpacing));
if(newPos.z() > this.generatedUntil - this.ringSpacing) {
this.generateRing(this.generatedUntil + this.ringSpacing);
@@ -224,7 +224,9 @@ public class ElytraRace extends StatelessGame {
}
private void toCheckpoint(Player p) {
CheckPointData data = this.playerCheckpoints.get(p);
Point checkpointPos = this.getRingPositionAtZ(this.playerCheckpoints.get(p).currentCheckpoint);
if(data.currentCheckpoint == 0) checkpointPos = this.getSpawn().add(0, 3, 0);
p.setVelocity(Vec.ZERO);
p.setFlyingWithElytra(false);
p.teleport(Pos.fromPoint(checkpointPos).add(0.5, 0, 0.5));

View File

@@ -110,7 +110,7 @@ public class SpaceSnake extends StatelessGame {
playerMoveEvent.getPlayer().teleport(this.getSpawn());
playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
long livingPlayers = this.getPlayers().stream()
.filter(p -> this.getScore().hasResult(p))
.filter(p -> !this.getScore().hasResult(p))
.count();
if(livingPlayers == 1) this.setTimeLimit(10);
if(livingPlayers == 0) this.stop();

View File

@@ -28,7 +28,8 @@ public class StickFightFactory implements GameFactory {
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("length", Material.SANDSTONE, TranslatedComponent.byId("optionCommon#length"), 7, 10, 13, 16, 19));
.addOption(new NumericOption("length", Material.SANDSTONE, TranslatedComponent.byId("optionCommon#length"), 7, 10, 13, 16, 19))
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 30, 60, 90, 120));
}
@Override
@@ -40,7 +41,7 @@ public class StickFightFactory implements GameFactory {
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
return new Stickfight(configuration.get("length").getAsInt()).setParent(parent);
return new Stickfight(configuration.get("length").getAsInt(), configuration.get("seconds").getAsInt()).setParent(parent);
}
@Override

View File

@@ -10,6 +10,8 @@ import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -22,10 +24,12 @@ public class Stickfight extends StatelessGame {
private final WeakHashMap<Player, Pos> spawnPoints = new WeakHashMap<>();
private final Map<Player, Integer> scoreMap = new WeakHashMap<>();
private boolean countdownStarted = false;
private final int seconds;
public Stickfight(int length) {
public Stickfight(int length, int seconds) {
super(Dimension.OVERWORLD.key, "Stickfight", new LowestPointsWinScore());
this.radius = length;
this.seconds = seconds;
this.eventNode().addChild(
CombatFeatures.empty()
@@ -79,10 +83,18 @@ public class Stickfight extends StatelessGame {
this.generateBridge(spawnX, spawnY, spawnZ);
}
ItemStack item = ItemStack.of(Material.STICK).withGlowing(true);
players.forEach(player -> player.getInventory().addItemStack(item));
this.setBlock(0, 50, 0, Block.GOLD_BLOCK);
super.start();
}
@Override
protected void onStart() {
this.setTimeLimit(this.seconds);
}
@Override
protected void onStop() {
this.scoreMap.forEach((player, score) -> this.getScore().insertResult(player, score));
@@ -117,6 +129,7 @@ public class Stickfight extends StatelessGame {
player.teleport(this.spawnPoints.get(player));
this.scoreMap.putIfAbsent(player, 0);
this.scoreMap.put(player, this.scoreMap.get(player) + 1);
player.setLevel(this.scoreMap.get(player));
}
}

View File

@@ -16,6 +16,8 @@ import net.minestom.server.event.player.PlayerTickEvent;
import net.minestom.server.event.player.PlayerUseItemEvent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.potion.Potion;
import net.minestom.server.potion.PotionEffect;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
@@ -71,7 +73,9 @@ class Tetris extends StatelessGame {
@Override
protected void onPlayerLeave(Player p) {
this.tetrisGames.get(p).sidebar.removeViewer(p);
p.clearEffects();
this.letPlayerLoose(p);
p.setGameMode(GameMode.SURVIVAL);
}
@Override
@@ -156,6 +160,7 @@ class Tetris extends StatelessGame {
p.teleport(tetrisGame.getPlayerSpawnPosition());
tetrisGame.sidebar.addViewer(p);
p.addEffect(new Potion(PotionEffect.SLOWNESS, 4, Potion.INFINITE_DURATION));
return super.onPlayerJoin(p);
}

View File

@@ -54,18 +54,18 @@ public class Tournament {
}
public List<Set<Player>> getPlaces() {
List<Set<Player>> players = new ArrayList<>(
this.getGameScores().entrySet().stream()
.collect(
Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toSet())
)
).values()
);
Map<Integer, Set<Player>> players = this.getGameScores().entrySet().stream()
.collect(
Collectors.groupingBy(
Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toSet())
)
);
Collections.reverse(players);
return players;
return players.entrySet().stream()
.sorted(Map.Entry.<Integer, Set<Player>>comparingByKey().reversed())
.map(Map.Entry::getValue)
.toList();
}
private int boost(int selfPlace, int placeCount) {

View File

@@ -10,4 +10,11 @@ public class CommonProperties {
this.put("east", "true");
}
};
public static Map<String, String> fenceNorthSouth = new HashMap<>() {
{
this.put("north", "true");
this.put("south", "true");
}
};
}

View File

@@ -105,7 +105,7 @@ optionPvpEnabled;pvp enabled;PvP aktiviert
;;
ns:game_Stickfight#;;
name;Stickfight;Stockschlacht
description;Push your opponents off the Bridge;Stoße deine Gegener von der Brücke
description;Push your opponents off the Bridge;Stoße deine Gegener von der Brücke, der Spieler mit den wenigsten Toden gewinnt!
;;
ns:game_TrafficlightRace#;;
name;Red light green light;Rotes licht, Grünes licht
@@ -170,3 +170,7 @@ ns:game_TurtleGame#;;
name;Turtle Game;Turtle Game
description;Eat snacks and dodge bombs to get the highest score!;Esse Snacks und weiche Bomben aus, um den höchsten Score zu erreichen!
startSpeed;Start Speed;Startgeschwindigkeit
;;
ns:game_BoatRace#;;
name;Boatrace;Bootrennen
description;;
1 map en_us de_de
105
106 ns:game_Stickfight#
107 name Stickfight Stockschlacht
108 description Push your opponents off the Bridge Stoße deine Gegener von der Brücke Stoße deine Gegener von der Brücke, der Spieler mit den wenigsten Toden gewinnt!
109
110 ns:game_TrafficlightRace#
111 name Red light green light Rotes licht, Grünes licht
170 name Turtle Game Turtle Game
171 description Eat snacks and dodge bombs to get the highest score! Esse Snacks und weiche Bomben aus, um den höchsten Score zu erreichen!
172 startSpeed Start Speed Startgeschwindigkeit
173
174 ns:game_BoatRace#
175 name Boatrace Bootrennen
176 description