19 Commits

Author SHA1 Message Date
jannis 728dc92fc8 Merge pull request 'elytra race fix boost ring 1' (#8) from develop-jannis into develop
Reviewed-on: #8
2026-01-10 13:48:50 +00:00
jannis 2f8ff36e5e Merge branch 'develop' into develop-jannis 2026-01-10 13:48:39 +00:00
jannis 5cb71c5c32 changed respawn height on first respawn in elytrarace
added level indicator for stickfight
2026-01-10 14:47:57 +01:00
jannis 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
jannis d5c2f06409 elytra race fix boost ring 1 2026-01-10 14:02:21 +01:00
jannis 1ff8cca7e9 added stick to inventory for stick fight 2026-01-10 00:41:24 +01:00
MineTec 47c40c4941 fixed winning condition in SpaceSnake 2026-01-07 15:06:12 +01:00
MineTec d4a7fcada7 improved chat formatting by adding username colors and better separators 2026-01-02 02:26:56 +01:00
Pupsi a0124f1bcb Merge remote-tracking branch 'origin/develop' into develop 2025-12-28 18:53:52 +01:00
Pupsi c79fbf3136 fixed tournament random order at the end 2025-12-28 18:53:14 +01:00
MineTec 660eb645e4 Merge remote-tracking branch 'origin/develop' into develop 2025-12-27 11:37:36 +01:00
MineTec 3c50aca1e8 updated reward API endpoint in PublishRewardCommand 2025-12-27 11:37:33 +01:00
Pupsi 865cdfa605 added gamemode change to survival on leaving tetris 2025-12-25 00:52:56 +01:00
Pupsi fe88e3f921 added slowness to tetris 2025-12-24 13:20:05 +01:00
MineTec 5e94479949 updated locales file with enhanced Stickfight description and added BoatRace entry 2025-12-21 10:42:23 +01:00
MineTec b15c9c97b0 finished boat race 2025-12-18 21:36:22 +01:00
MineTec 334e130cf6 fixed boat stuttering 2025-12-18 20:02:26 +01:00
MineTec 31385fbd7f cleanup 2025-12-13 15:15:23 +01:00
MineTec b1b1e24104 added BoatRace game with factory and updated GameList 2025-12-03 23:08:55 +01:00
59 changed files with 306 additions and 142 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Minigames" />
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="25" />
<bytecodeTargetLevel target="21" />
</component>
</project>
+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
</project>
+1
View File
@@ -4,6 +4,7 @@
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Minigames.main.iml" filepath="$PROJECT_DIR$/.idea/modules/Minigames.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Minigames.test.iml" filepath="$PROJECT_DIR$/.idea/modules/Minigames.test.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/eu.mhsl.minenet.Minigames.main.iml" filepath="$PROJECT_DIR$/.idea/modules/eu.mhsl.minenet.Minigames.main.iml" />
</modules>
</component>
</project>
+4
View File
@@ -10,4 +10,8 @@
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
+7 -7
View File
@@ -3,7 +3,7 @@
plugins {
id 'java'
id "com.github.johnrengelman.shadow" version "8.1.1"
id "com.github.johnrengelman.shadow" version "7.1.0"
}
group 'eu.mhsl.minenet'
@@ -35,7 +35,7 @@ allprojects {
java {
toolchain {
languageVersion = JavaLanguageVersion.of(25)
languageVersion = JavaLanguageVersion.of(21)
}
}
@@ -44,7 +44,7 @@ dependencies {
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
//https://jitpack.io/#Minestom/Minestom
implementation 'net.minestom:minestom:2025.10.11-1.21.10'
implementation 'net.minestom:minestom-snapshots:fd51c8d17a'
//Tools
implementation 'de.articdive:jnoise:3.0.2'
@@ -57,12 +57,12 @@ dependencies {
//PvP
implementation 'io.github.TogAr2:MinestomPvP:56a831b41cb2ec6db8da681ad5d212ed7c71e3ee'
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 {
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
@@ -3,13 +3,12 @@ package eu.mhsl.minenet.minigames;
import eu.mhsl.minenet.minigames.api.HttpServer;
import eu.mhsl.minenet.minigames.command.Commands;
import eu.mhsl.minenet.minigames.handler.Listeners;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.lang.Languages;
import eu.mhsl.minenet.minigames.server.tasks.TablistUpdateTask;
import io.github.togar2.pvp.MinestomPvP;
import net.minestom.server.Auth;
import net.minestom.server.MinecraftServer;
import net.minestom.server.extras.bungee.BungeeCordProxy;
import net.minestom.server.extras.lan.OpenToLAN;
import net.minestom.server.extras.velocity.VelocityProxy;
import net.minestom.server.timer.TaskSchedule;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
@@ -26,7 +25,7 @@ public class Main {
public static ConfigurationNode globalConfig;
@SuppressWarnings("ResultOfMethodCallIgnored")
static void main() throws ConfigurateException {
public static void main(String[] args) throws ConfigurateException {
//noinspection ResultOfMethodCallIgnored
Resource.values(); // This initializes and preloads the enum and extracts the resources
Languages.getInstance(); //Preload languages into the jvm
@@ -41,35 +40,29 @@ public class Main {
logger.info("Initialize Minecraft server...");
MinecraftServer server = null;
if(serverConfig.node("open-to-lan").getBoolean()) OpenToLAN.open();
if(globalConfig.node("bungeecord", "enabled").getBoolean()) {
server = MinecraftServer.init(new Auth.Bungee());
}
if(globalConfig.node("velocity", "enabled").getBoolean()) {
server = MinecraftServer.init(new Auth.Velocity(Objects.requireNonNull(globalConfig.node("velocity", "secret").getString())));
}
if(server == null) server = MinecraftServer.init();
MinestomPvP.init();
MinecraftServer server = MinecraftServer.init();
// MinestomPvP.init();
MinecraftServer.setBrandName("mhsl.eu - minenet - credits to minestom");
MinecraftServer.setCompressionThreshold(serverConfig.node("compression-threshold").getInt(0));
System.setProperty("minestom.chunk-view-distance", String.valueOf(serverConfig.node("view-distance").getInt()));
System.setProperty("minestom.registry.unsafe-ops", "true");
Commands.values();
Listeners.values();
Dimension.values();
new HttpServer();
MinecraftServer.getSchedulerManager().scheduleTask(new TablistUpdateTask(), TaskSchedule.tick(20), TaskSchedule.tick(20));
logger.info("Starting Minecraft server ... ");
if(serverConfig.node("open-to-lan").getBoolean()) OpenToLAN.open();
if(globalConfig.node("bungeecord", "enabled").getBoolean()) BungeeCordProxy.enable();
if(globalConfig.node("velocity", "enabled").getBoolean()) {
VelocityProxy.enable(Objects.requireNonNull(globalConfig.node("velocity", "secret").getString()));
}
server.start("0.0.0.0", serverConfig.node("port").getInt(25565));
System.gc();
@@ -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();
@@ -21,7 +21,7 @@ public class SetMemorialCommand extends PrivilegedCommand {
ArgumentString loreArgument = ArgumentType.String("lore");
materialArgument.setSuggestionCallback(
(_, _, suggestion) -> Material
(sender, context, suggestion) -> Material
.values()
.stream()
.map(material -> new SuggestionEntry(material.name(), Component.text(material.name())))
@@ -35,7 +35,7 @@ public class SetMemorialCommand extends PrivilegedCommand {
.getTournament()
.setMemorialConfiguration(
new MemorialConfiguration(
Material.fromKey(context.get(materialArgument)),
Material.fromNamespaceId(context.get(materialArgument)),
context.get(titleArgument),
context.get(loreArgument)
)
@@ -23,7 +23,7 @@ public class SetRewardCommand extends PrivilegedCommand {
ArgumentStringArray amountsArgument = ArgumentType.StringArray("amount");
materialArgument.setSuggestionCallback(
(_, _, suggestion) -> Material
(sender, context, suggestion) -> Material
.values()
.stream()
.map(material -> new SuggestionEntry(material.name(), Component.text(material.name())))
@@ -37,7 +37,7 @@ public class SetRewardCommand extends PrivilegedCommand {
.getTournament()
.setRewardConfiguration(
new RewardConfiguration(
Material.fromKey(context.get(materialArgument)),
Material.fromNamespaceId(context.get(materialArgument)),
Arrays.stream(context.get(amountsArgument)).map(Integer::valueOf).collect(Collectors.toList())
)
);
@@ -25,6 +25,7 @@ public class SetRoomOwnerCommand extends PrivilegedCommand {
});
this.addSyntax((sender, context) -> {
System.out.println("Test");
if(sender instanceof Player p) {
Player newOwner = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("player"));
Room.getRoom(p).orElseThrow().setOwner(Objects.requireNonNull(newOwner));
@@ -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;
}
}
@@ -1,50 +1,49 @@
package eu.mhsl.minenet.minigames.instance;
import net.kyori.adventure.key.Key;
import net.minestom.server.MinecraftServer;
import net.minestom.server.registry.RegistryKey;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.world.DimensionType;
import org.jetbrains.annotations.NotNull;
/**
* Prebuilt dimensions
*/
public enum Dimension {
OVERWORLD(
Key.key("minenet:fullbright_overworld"),
NamespaceID.from("minenet:fullbright_overworld"),
DimensionType
.builder()
.ambientLight(1.0f)
.ambientLight(2.0f)
.build()
),
NETHER(
Key.key("minenet:fullbright_nether"),
NamespaceID.from("minenet:fullbright_nether"),
DimensionType
.builder()
.ambientLight(1.0f)
.ambientLight(2.0f)
.effects("minecraft:the_nether")
.build()
),
THE_END(
Key.key("minenet:fullbright_end"),
NamespaceID.from("minenet:fullbright_end"),
DimensionType
.builder()
.ambientLight(1.0f)
.ambientLight(2.0f)
.effects("minecraft:the_end")
.build()
);
public final DimensionType DIMENSION;
public final Key namespaceID;
public final RegistryKey<@NotNull DimensionType> key;
public final NamespaceID namespaceID;
public final DynamicRegistry.Key<DimensionType> key;
Dimension(Key namespaceID, DimensionType dimType) {
Dimension(NamespaceID namespaceID, DimensionType dimType) {
this.DIMENSION = dimType;
this.namespaceID = namespaceID;
this.key = MinecraftServer.getDimensionTypeRegistry().register(this.namespaceID, this.DIMENSION);
this.key = MinecraftServer.getDimensionTypeRegistry().register(namespaceID, this.DIMENSION);
}
}
@@ -7,15 +7,14 @@ import net.minestom.server.event.instance.AddEntityToInstanceEvent;
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.registry.RegistryKey;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.timer.TaskSchedule;
import net.minestom.server.world.DimensionType;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public class MineNetInstance extends InstanceContainer {
public MineNetInstance(RegistryKey<@NotNull DimensionType> type) {
public MineNetInstance(DynamicRegistry.Key<DimensionType> type) {
super(UUID.randomUUID(), type);
MinecraftServer.getInstanceManager().registerInstance(this);
@@ -16,7 +16,7 @@ import net.minestom.server.event.item.ItemDropEvent;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.registry.RegistryKey;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.TaskSchedule;
import net.minestom.server.world.DimensionType;
@@ -34,7 +34,7 @@ public abstract class Game extends MineNetInstance implements Spawnable {
protected boolean isRunning = false;
protected boolean isBeforeBeginning = true;
public Game(RegistryKey<@NotNull DimensionType> dimensionType) {
public Game(DynamicRegistry.Key<DimensionType> dimensionType) {
super(dimensionType);
MinecraftServer.getInstanceManager().registerInstance(this);
@@ -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;
@@ -9,12 +9,11 @@ import eu.mhsl.minenet.minigames.score.Score;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.registry.RegistryKey;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.Task;
import net.minestom.server.timer.TaskSchedule;
import net.minestom.server.world.DimensionType;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
@@ -27,7 +26,7 @@ public class StatelessGame extends Game {
private int timeLimit = 0;
private int timePlayed = 0;
public StatelessGame(RegistryKey<@NotNull DimensionType> dimensionType, String gameName, Score score) {
public StatelessGame(DynamicRegistry.Key<DimensionType> dimensionType, String gameName, Score score) {
super(dimensionType);
this.score = score;
this.name = gameName;
@@ -15,7 +15,8 @@ import net.minestom.server.entity.Player;
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.inventory.condition.InventoryConditionResult;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.sound.SoundEvent;
@@ -38,8 +39,8 @@ public class GameConfigurationInventory extends InteractableInventory {
this.factory = factory;
room.eventNode()
.addListener(AddEntityToInstanceEvent.class, _ -> MinecraftServer.getSchedulerManager().scheduleNextTick(this::updatePlayButton))
.addListener(RemoveEntityFromInstanceEvent.class, _ -> MinecraftServer.getSchedulerManager().scheduleNextTick(this::updatePlayButton));
.addListener(AddEntityToInstanceEvent.class, addEntityToInstanceEvent -> MinecraftServer.getSchedulerManager().scheduleNextTick(this::updatePlayButton))
.addListener(RemoveEntityFromInstanceEvent.class, removeEntityFromInstanceEvent -> MinecraftServer.getSchedulerManager().scheduleNextTick(this::updatePlayButton));
ConfigManager config = factory.configuration();
@@ -52,7 +53,7 @@ public class GameConfigurationInventory extends InteractableInventory {
)
.build(),
0,
itemClick -> itemClick.player().closeInventory(),
itemClick -> itemClick.getPlayer().closeInventory(),
true
);
@@ -105,7 +106,8 @@ public class GameConfigurationInventory extends InteractableInventory {
}
@Override
protected void onClick(Player player, int slot, Click clickType) {
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
inventoryConditionResult.setCancel(true);
if(!this.map.containsKey(slot)) return;
@@ -131,7 +133,7 @@ public class GameConfigurationInventory extends InteractableInventory {
.lore(restrictionHandler.getWarnings(restrictionData).stream().map(translatedComponent -> translatedComponent.getAssembled(this.p)).collect(Collectors.toList()))
.build(),
8,
itemClick -> Game.initialize(this.factory, this.map.values().stream().toList(), itemClick.player()),
itemClick -> Game.initialize(this.factory, this.map.values().stream().toList(), itemClick.getPlayer()),
true
);
@@ -153,7 +155,7 @@ public class GameConfigurationInventory extends InteractableInventory {
this.updatePlayButton();
return;
}
itemClick.player().playSound(Sound.sound(SoundEvent.ENTITY_SILVERFISH_DEATH, Sound.Source.AMBIENT, 1f, 1f));
itemClick.getPlayer().playSound(Sound.sound(SoundEvent.ENTITY_SILVERFISH_DEATH, Sound.Source.AMBIENT, 1f, 1f));
},
false
);
@@ -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);
}
}
@@ -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);
}
}
@@ -35,6 +35,7 @@ class Deathcube extends StatelessGame {
.add(CombatFeatures.VANILLA_KNOCKBACK)
.build().createNode()
);
System.out.println(radius);
}
@Override
@@ -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));
@@ -8,7 +8,6 @@ import io.github.togar2.pvp.events.EntityKnockbackEvent;
import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.events.PrepareAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures;
import io.github.togar2.pvp.feature.knockback.KnockbackSettings;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.event.instance.InstanceTickEvent;
@@ -51,7 +50,7 @@ class HighGround extends StatelessGame {
this.eventNode().addListener(
EntityKnockbackEvent.class,
entityKnockbackEvent -> entityKnockbackEvent.setSettings(new KnockbackSettings(1.1, 1.1, 2, 0, 0))
entityKnockbackEvent -> entityKnockbackEvent.setStrength(1.1f)
);
this.eventNode().addListener(InstanceTickEvent.class, instanceTickEvent -> {
@@ -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();
@@ -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;
@@ -79,6 +81,9 @@ 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();
}
@@ -117,6 +122,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));
}
}
@@ -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);
}
@@ -19,7 +19,7 @@ public class HubInventory extends InteractableInventory {
.lore(TranslatedComponent.assemble("hub#create_description", p))
.build(),
12,
itemClick -> Room.createRoom(itemClick.player()),
itemClick -> Room.createRoom(itemClick.getPlayer()),
true
);
@@ -30,7 +30,7 @@ public class HubInventory extends InteractableInventory {
.lore(TranslatedComponent.assemble("hub#join_description", p))
.build(),
14,
itemClick -> itemClick.player().openInventory(new JoinInventory(itemClick.player()))
itemClick -> itemClick.getPlayer().openInventory(new JoinInventory(itemClick.getPlayer()))
);
}
}
@@ -11,7 +11,8 @@ import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerPacketEvent;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.inventory.condition.InventoryConditionResult;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.network.packet.client.play.ClientNameItemPacket;
@@ -31,7 +32,7 @@ public class JoinInventory extends InteractableInventory {
.customName(Component.text(this.prefix))
.build(),
0,
_ -> {
itemClick -> {
}
);
@@ -44,8 +45,9 @@ public class JoinInventory extends InteractableInventory {
}
@Override
protected void onClick(Player player, int slot, Click clickType) {
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
if(slot != 2) return;
inventoryConditionResult.setCancel(true);
player.closeInventory();
this.typedText = this.formatInput(this.typedText);
@@ -33,7 +33,7 @@ public class MinigameSelectInventory extends InteractableInventory {
.lore(type.getDescription().addWrap().getWrappedAssembled(p))
.build(),
itemAlignment.next().get(),
_ -> this.drawGames(type)
itemClick -> this.drawGames(type)
);
}
@@ -62,8 +62,7 @@ public class MinigameSelectInventory extends InteractableInventory {
.lore(gameFactory.description().addWrap().getWrappedAssembled(this.p))
.build(),
offset + itemAlignment.next().get(),
itemClick -> itemClick.player().openInventory(new GameConfigurationInventory(this.room, itemClick.player(), gameFactory)),
true
itemClick -> itemClick.getPlayer().openInventory(new GameConfigurationInventory(this.room, itemClick.getPlayer(), gameFactory))
);
}
}
@@ -24,8 +24,8 @@ public class Tournament {
for(Player player : players) {
int points = (game.getScores().size() - count) + this.boost(count, game.getScores().size());
data.computeIfPresent(player, (_, existingPoints) -> existingPoints + points);
data.computeIfAbsent(player, _ -> points);
data.computeIfPresent(player, (existingPlayer, existingPoints) -> existingPoints + points);
data.computeIfAbsent(player, newPlayer -> points);
}
}
});
@@ -44,28 +44,28 @@ public class Tournament {
}
return new Rewards(
this.memorialConfiguration.memorialMaterial().key().value(),
this.memorialConfiguration.memorialMaterial().namespace().value(),
this.memorialConfiguration.memorialTitle(),
this.memorialConfiguration.memorialLore(),
this.getGameScores().keySet().stream().map(Player::getUuid).toList(),
this.rewardConfiguration.item().key().value(),
this.rewardConfiguration.item().namespace().value(),
itemCount
);
}
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) {
@@ -2,64 +2,38 @@ package eu.mhsl.minenet.minigames.shared.inventory;
import net.kyori.adventure.text.Component;
import net.minestom.server.entity.Player;
import net.minestom.server.event.inventory.InventoryPreClickEvent;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.click.Click;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.inventory.condition.InventoryConditionResult;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
public class InteractableInventory extends Inventory {
private final Map<Integer, ClickableItem> clickableItems = new HashMap<>();
public record ItemClick(Player player, InteractableInventory inventory, int clickedSlot, ItemStack item, Click clickType) { }
public record ClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback, boolean closeAfterClick) { }
/**
* Defines an Inventory with direct callbacks for ItemSlots
*/
protected InteractableInventory(@NotNull InventoryType inventoryType, @NotNull Component title) {
super(inventoryType, title);
this.eventNode().addListener(
InventoryPreClickEvent.class,
inventoryPreClickEvent -> this.onClick(
inventoryPreClickEvent.getPlayer(),
inventoryPreClickEvent.getSlot(),
inventoryPreClickEvent.getClick()
)
);
this.eventNode().addListener(InventoryPreClickEvent.class, inventoryPreClickEvent -> {
@Nullable ClickableItem selectedItem = this.clickableItems.values().stream()
.filter(clickableItem -> clickableItem.slot() == inventoryPreClickEvent.getSlot())
.findFirst()
.orElse(null);
if(selectedItem == null) {
inventoryPreClickEvent.setCancelled(true);
return;
}
if(selectedItem.closeAfterClick()) inventoryPreClickEvent.getPlayer().closeInventory();
selectedItem.callback().accept(
new ItemClick(inventoryPreClickEvent.getPlayer(), this, inventoryPreClickEvent.getSlot(), selectedItem.item(), inventoryPreClickEvent.getClick())
);
inventoryPreClickEvent.setCancelled(true);
});
this.addInventoryCondition(this::onClick);
}
/**
* Set Item with Callback
*/
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback, boolean closeAfter) {
ClickableItem clickableItem = new ClickableItem(item, slot, callback, closeAfter);
this.setItemStack(clickableItem.slot(), clickableItem.item());
this.clickableItems.put(clickableItem.slot(), clickableItem);
this.setItemStack(slot, item);
this.addInventoryCondition((player, clickedSlot, clickType, inventoryConditionResult) -> {
if(clickedSlot == slot) {
if(closeAfter) player.closeInventory();
callback.accept(new ItemClick(player, this, clickedSlot, item, clickType));
}
inventoryConditionResult.setCancel(true);
});
}
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback) {
@@ -73,7 +47,7 @@ public class InteractableInventory extends Inventory {
this.setClickableItem(
item,
slot,
_ -> {
itemClick -> {
}
);
}
@@ -88,7 +62,7 @@ public class InteractableInventory extends Inventory {
/**
* You may want to Override this method to get more generic click events
*/
protected void onClick(Player player, int slot, Click clickType) {
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
}
}
@@ -0,0 +1,45 @@
package eu.mhsl.minenet.minigames.shared.inventory;
import net.minestom.server.entity.Player;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.item.ItemStack;
public class ItemClick {
private final Player player;
private final InteractableInventory inventory;
private final int clickedSlot;
private final ItemStack item;
private final ClickType clickType;
/**
* Describes a click on an Item from an IntractableInventory
*/
public ItemClick(Player player, InteractableInventory inventory, int clickedSlot, ItemStack item, ClickType clickType) {
this.player = player;
this.inventory = inventory;
this.clickedSlot = clickedSlot;
this.item = item;
this.clickType = clickType;
}
public Player getPlayer() {
return this.player;
}
public Inventory getInventory() {
return this.inventory;
}
public int getClickedSlot() {
return this.clickedSlot;
}
public ItemStack getItem() {
return this.item;
}
public ClickType getClickType() {
return this.clickType;
}
}
@@ -1,12 +1,12 @@
package eu.mhsl.minenet.minigames.util;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.instance.batch.Batch;
import net.minestom.server.instance.batch.ChunkBatch;
import net.minestom.server.utils.chunk.ChunkUtils;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
public class BatchUtil {
@@ -16,13 +16,10 @@ public class BatchUtil {
field.setAccessible(true);
@SuppressWarnings("unchecked")
Map<Long, ChunkBatch> chunkBatchesMap = (Map<Long, ChunkBatch>) field.get(batch);
Long2ObjectMap<ChunkBatch> chunkBatchesMap = (Long2ObjectMap<ChunkBatch>) field.get(batch);
long[] out = new long[chunkBatchesMap.size()];
int i = 0;
for (Long k : chunkBatchesMap.keySet()) out[i++] = k;
return out;
} catch (NoSuchFieldException | IllegalAccessException e) {
return chunkBatchesMap.keySet().toLongArray();
} catch(NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@@ -39,9 +36,15 @@ public class BatchUtil {
long[] affectedChunks = BatchUtil.getAffectedChunks(batch);
CompletableFuture<Void> loadChunksTask = ChunkUtils.optionalLoadAll(instance, affectedChunks, null);
Runnable completerTask = () -> future.complete(null);
Runnable completerTask = () -> {
System.out.println("COMPLETE");
future.complete(null);
};
loadChunksTask.thenRun(() -> batch.apply(instance, completerTask));
loadChunksTask.thenRun(() -> {
System.out.println("BEGIN");
batch.apply(instance, completerTask);
});
try {
future.get();
@@ -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");
}
};
}
@@ -19,6 +19,7 @@ public class WeatherUtils {
MinecraftServer.getSchedulerManager().submitTask(() -> {
this.intensity += 0.1f;
players.forEach(p -> p.sendPacket(new ChangeGameStatePacket(ChangeGameStatePacket.Reason.RAIN_LEVEL_CHANGE, this.intensity)));
System.out.println(this.intensity);
if(this.intensity < 1) {
return TaskSchedule.millis(500);
} else {
@@ -38,6 +38,8 @@ public class CircularPlateGenerator extends HeightTerrainGenerator {
@Override
public void generate(@NotNull GenerationUnit unit) {
this.execution.singleRun(() -> unit.fork(setter -> {
System.out.println(new Pos(-(this.radius + this.centerX), unit.absoluteStart().y(), -(this.radius + this.centerZ)));
System.out.println(new Pos(this.radius + this.centerX, this.height, this.radius + this.centerZ));
GeneratorUtils.foreachXZ(
new Pos(-(this.radius + this.centerX), unit.absoluteStart().y(), -(this.radius + this.centerZ)),
new Pos(this.radius + this.centerX, this.height, this.radius + this.centerZ),
@@ -46,6 +46,7 @@ public class HeightTerrainGenerator extends BaseGenerator {
double heightNoise = this.base.getNoise(bottomPoint.x(), bottomPoint.z());
double noiseModifier = heightNoise * this.heightNoiseMultiplier.apply(bottomPoint);
double heightModifier = NumberUtil.clamp(this.calculateHeight.apply(bottomPoint) + noiseModifier, 1d, unit.size().y());
if(heightModifier < 1) System.out.println("HEIGHT MODIFIER ILLEGAL");
synchronized(this.batches) {
double batchNoise = this.batches.getNoise(bottomPoint.x(), bottomPoint.z());
@@ -68,6 +69,8 @@ public class HeightTerrainGenerator extends BaseGenerator {
Point absoluteHeight = bottomPoint.add(0, heightModifier, 0);
int seaLevel = this.calculateSeaLevel.apply(bottomPoint);
if(absoluteHeight.y() < seaLevel) {
// System.out.println("HM:" + absoluteHeight.y() + " SL:" + seaLevel);
// System.out.println("Filling from " + bottomPoint.y() + " to " + absoluteHeight.withY(seaLevel).y());
unit.modifier().fill(bottomPoint.withY(v -> v + heightModifier), absoluteHeight.add(1, 0, 1).withY(seaLevel), Block.WATER);
}
}
+5 -1
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