17 Commits

Author SHA1 Message Date
535008a31e startet implementation of buildBattle 2025-04-11 10:21:59 +02:00
24af27f2e3 fixed different player gamemodes in lobby after games 2025-03-22 11:11:08 +01:00
13132eace6 fixed minestom-pvp version, made stickfight playable 2025-03-03 20:28:10 +01:00
8d479b69e3 updated JumpDive translations 2025-03-03 01:31:57 +01:00
5ca8ad8bd7 added jumpDive game 2025-03-03 01:28:29 +01:00
3f2ba1e428 prevent execution of /hub in api driven rooms 2025-03-02 23:40:39 +01:00
5bab1a1ac7 fixed skin not being applied properly, made /skin privileged 2025-03-02 23:35:30 +01:00
8fdd0487bf updated project to newest minestom commit 2025-03-02 23:26:58 +01:00
e0ee1e66c9 added description message on game start 2025-01-02 01:08:53 +01:00
5acb44b0e1 disabled player collisions 2025-01-01 22:20:57 +01:00
7cd849946b fixed elytra race spectators flying elytra 2024-12-27 12:02:38 +01:00
a71aca5d6c added missing translations 2024-12-27 12:01:44 +01:00
ea08ac7a81 fixed tnt run falling before start 2024-12-27 11:10:18 +01:00
ee192c1035 fixed some bugs 2024-12-27 10:58:07 +01:00
81dbf16d3f fixed tetris player inputs 2024-12-27 10:53:02 +01:00
f03011e4f1 Merge remote-tracking branch 'origin/develop' into develop 2024-12-24 00:26:53 +01:00
9069ead9e9 fixed barrier border for terrain generator 2024-12-24 00:26:41 +01:00
34 changed files with 453 additions and 151 deletions

View File

@ -10,8 +10,6 @@ group 'eu.mhsl.minenet'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
repositories { repositories {
//maven 'https://repo.unnamed.team/repository/unnamed-public/'
mavenCentral() mavenCentral()
google() google()
@ -46,7 +44,7 @@ dependencies {
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
//https://jitpack.io/#Minestom/Minestom //https://jitpack.io/#Minestom/Minestom
implementation 'net.minestom:minestom-snapshots:d707b0674f' implementation 'net.minestom:minestom-snapshots:fd51c8d17a'
//Tools //Tools
implementation 'de.articdive:jnoise:3.0.2' implementation 'de.articdive:jnoise:3.0.2'
@ -55,11 +53,11 @@ dependencies {
implementation 'org.spongepowered:configurate-yaml:4.1.2' implementation 'org.spongepowered:configurate-yaml:4.1.2'
implementation 'com.sparkjava:spark-core:2.9.4' implementation 'com.sparkjava:spark-core:2.9.4'
implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.google.guava:guava:32.0.0-android' implementation 'com.google.guava:guava:32.0.1-android'
//PvP //PvP
implementation 'com.github.TogAr2:MinestomPvP:04180ddf9a' implementation 'io.github.TogAr2:MinestomPvP:PR62-SNAPSHOT'
// Hephaestus engine // Hephaestus engine
implementation("team.unnamed:hephaestus-api:0.2.1-SNAPSHOT") implementation("team.unnamed:hephaestus-api:0.2.1-SNAPSHOT")

View File

@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

56
gradlew vendored Normal file → Executable file
View File

@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@ -25,7 +27,7 @@
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or # noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole # bash, then to run this script, type that shell name before the whole
# eu.mhsl.minenet.minigames.command line, like: # command line, like:
# #
# ksh Gradle # ksh Gradle
# #
@ -35,7 +37,7 @@
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»; # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»; # * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «eu.mhsl.minenet.minigames.command», «set», and «ulimit». # * various built-in commands including «command», «set», and «ulimit».
# #
# Important for patching: # Important for patching:
# #
@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -80,13 +82,12 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' ' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -117,7 +118,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java eu.mhsl.minenet.minigames.command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
@ -133,29 +134,36 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
fi fi
# Collect all arguments for the java eu.mhsl.minenet.minigames.command, stacking in reverse order: # Collect all arguments for the java command, stacking in reverse order:
# * args from the eu.mhsl.minenet.minigames.command line # * args from the command line
# * the main class name # * the main class name
# * -classpath # * -classpath
# * -D...appname settings # * -D...appname settings
@ -193,11 +201,15 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Collect all arguments for the java eu.mhsl.minenet.minigames.command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# shell script including quotes and variable substitutions, so put them in DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded. # Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
@ -205,6 +217,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \ org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args. # Use "xargs" to parse quoted args.
# #
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
@ -214,7 +232,7 @@ set -- \
# readarray ARGS < <( xargs -n1 <<<"$var" ) && # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@" # set -- "${ARGS[@]}" "$@"
# #
# but POSIX shell has neither arrays nor eu.mhsl.minenet.minigames.command substitution, so instead we # but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any # post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse # character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap # that process (while maintaining the separation between arguments), and wrap

35
gradlew.bat vendored
View File

@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@ -26,6 +28,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' eu.mhsl.minenet.gameList.command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@ -56,16 +59,16 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
:execute :execute
@rem Setup the eu.mhsl.minenet.gameList.command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if %ERRORLEVEL% equ 0 goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 set EXIT_CODE=%ERRORLEVEL%
exit /b 1 if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

View File

@ -1,6 +1,6 @@
package eu.mhsl.minenet.minigames.command; package eu.mhsl.minenet.minigames.command;
import eu.mhsl.minenet.minigames.command.anonymous.SkinCommand; import eu.mhsl.minenet.minigames.command.privileged.SkinCommand;
import eu.mhsl.minenet.minigames.command.privileged.*; import eu.mhsl.minenet.minigames.command.privileged.*;
import eu.mhsl.minenet.minigames.command.anonymous.HubCommand; import eu.mhsl.minenet.minigames.command.anonymous.HubCommand;
import eu.mhsl.minenet.minigames.command.anonymous.LeaveCommand; import eu.mhsl.minenet.minigames.command.anonymous.LeaveCommand;
@ -41,7 +41,7 @@ public enum Commands {
static { static {
MinecraftServer.getCommandManager().setUnknownCommandCallback((sender, command) -> { MinecraftServer.getCommandManager().setUnknownCommandCallback((sender, command) -> {
if(command.isBlank()) return; if(command.isBlank()) return;
new ChatMessage(Icon.ERROR).appendStatic("Unknown command").quote(command).send(sender); new ChatMessage(Icon.ERROR).appendStatic("Unknown command: ").quote(command).send(sender);
}); });
} }
} }

View File

@ -10,9 +10,13 @@ public class HubCommand extends Command {
public HubCommand() { public HubCommand() {
super("hub"); super("hub");
setCondition((sender, commandString) -> ((Player) sender).getInstance() instanceof Room); setCondition(
(sender, commandString) ->
((Player) sender).getInstance() instanceof Room room && !room.apiDriven
);
setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
if(Room.getRoom((Player) sender).orElseThrow().apiDriven) return;
Room.unsetRoom((Player) sender); Room.unsetRoom((Player) sender);
MoveInstance.move((Player) sender, Hub.INSTANCE); MoveInstance.move((Player) sender, Hub.INSTANCE);
}); });

View File

@ -1,11 +1,11 @@
package eu.mhsl.minenet.minigames.command.anonymous; package eu.mhsl.minenet.minigames.command.privileged;
import net.minestom.server.command.builder.Command; import eu.mhsl.minenet.minigames.command.PrivilegedCommand;
import net.minestom.server.command.builder.arguments.ArgumentType; import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.entity.PlayerSkin; import net.minestom.server.entity.PlayerSkin;
public class SkinCommand extends Command { public class SkinCommand extends PrivilegedCommand {
public SkinCommand() { public SkinCommand() {
super("skin"); super("skin");

View File

@ -11,6 +11,8 @@ import net.minestom.server.entity.Player;
import eu.mhsl.minenet.minigames.instance.hub.Hub; import eu.mhsl.minenet.minigames.instance.hub.Hub;
import net.minestom.server.event.EventListener; import net.minestom.server.event.EventListener;
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
import net.minestom.server.network.packet.server.play.TeamsPacket;
import net.minestom.server.scoreboard.Team;
import net.minestom.server.timer.TaskSchedule; import net.minestom.server.timer.TaskSchedule;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.serialize.SerializationException;
@ -20,6 +22,11 @@ import java.util.UUID;
import java.util.logging.Logger; import java.util.logging.Logger;
public class PlayerLoginHandler implements EventListener<AsyncPlayerConfigurationEvent> { public class PlayerLoginHandler implements EventListener<AsyncPlayerConfigurationEvent> {
public static final Team globalTeam = MinecraftServer.getTeamManager()
.createBuilder("global")
.collisionRule(TeamsPacket.CollisionRule.NEVER)
.build();
@Override @Override
public @NotNull Class<AsyncPlayerConfigurationEvent> eventType() { public @NotNull Class<AsyncPlayerConfigurationEvent> eventType() {
return AsyncPlayerConfigurationEvent.class; return AsyncPlayerConfigurationEvent.class;
@ -37,13 +44,14 @@ public class PlayerLoginHandler implements EventListener<AsyncPlayerConfiguratio
MinecraftServer.getSchedulerManager().scheduleTask( MinecraftServer.getSchedulerManager().scheduleTask(
() -> { () -> {
p.setTeam(globalTeam);
if(pushQueue != null) { if(pushQueue != null) {
Room.setRoom(p, Room.getRoom(pushQueue).orElseThrow()); Room.setRoom(p, Room.getRoom(pushQueue).orElseThrow());
} else { } else {
MoveInstance.move(p, Hub.INSTANCE); MoveInstance.move(p, Hub.INSTANCE);
} }
}, },
TaskSchedule.seconds(5), TaskSchedule.seconds(1),
TaskSchedule.stop() TaskSchedule.stop()
); );

View File

@ -11,7 +11,6 @@ import eu.mhsl.minenet.minigames.instance.Spawnable;
import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.room.Room;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.item.ItemDropEvent; import net.minestom.server.event.item.ItemDropEvent;
import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.minestom.server.event.player.PlayerBlockBreakEvent;
@ -43,7 +42,7 @@ public abstract class Game extends MineNetInstance implements Spawnable {
MinecraftServer.getInstanceManager().registerInstance(this); MinecraftServer.getInstanceManager().registerInstance(this);
logger = Logger.getLogger("Game:" + getUniqueId()); logger = Logger.getLogger("Game:" + getUuid());
eventNode() eventNode()
.addListener(PlayerMoveEvent.class, this::onPlayerMove) .addListener(PlayerMoveEvent.class, this::onPlayerMove)
@ -64,6 +63,17 @@ public abstract class Game extends MineNetInstance implements Spawnable {
game.load(); game.load();
Room.getRoom(owner).orElseThrow().moveMembersToInstance(game); Room.getRoom(owner).orElseThrow().moveMembersToInstance(game);
MinecraftServer.getSchedulerManager().scheduleTask(() -> {
game.getPlayers().forEach(player -> new ChatMessage(Icon.SCIENCE)
.appendStatic(factory.name().getAssembled(player).asComponent())
.newLine()
.appendStatic(factory.description().getAssembled(player).asComponent())
.send(player));
return TaskSchedule.stop();
}, TaskSchedule.seconds(3));
} catch (Exception e) { } catch (Exception e) {
new ChatMessage(Icon.ERROR).appendStatic("Instance crashed: " + e.getMessage()).send(owner); new ChatMessage(Icon.ERROR).appendStatic("Instance crashed: " + e.getMessage()).send(owner);
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> Room.getRoom(owner).orElseThrow().moveMembersToRoomLobby()); MinecraftServer.getSchedulerManager().scheduleNextTick(() -> Room.getRoom(owner).orElseThrow().moveMembersToRoomLobby());
@ -99,15 +109,11 @@ public abstract class Game extends MineNetInstance implements Spawnable {
public void unload() { public void unload() {
this.onUnload(); this.onUnload();
getPlayers().forEach(player -> { getPlayers().forEach(Room::setOwnRoom);
Room.setOwnRoom(player);
player.setGameMode(GameMode.SURVIVAL);
player.setInvisible(false);
});
scheduler().scheduleTask(() -> { scheduler().scheduleTask(() -> {
logger.info("stopping game instance " + this.uniqueId); logger.info("stopping game instance " + this.uuid);
getPlayers().forEach(player -> player.kick("timeout")); getPlayers().forEach(player -> player.kick("timeout"));
MinecraftServer.getInstanceManager().unregisterInstance(this); MinecraftServer.getInstanceManager().unregisterInstance(this);

View File

@ -3,11 +3,13 @@ package eu.mhsl.minenet.minigames.instance.game;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory; 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.elytraRace.ElytraRaceFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory; 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.bedwars.BedwarsFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain.AcidRainFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain.AcidRainFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive.JumpDiveFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun.MinerunFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun.MinerunFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef.SpleefFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef.SpleefFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight.StickFightFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight.StickFightFactory;
@ -18,19 +20,21 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace.
public enum GameList { public enum GameList {
DEATHCUBE(new DeathcubeFactory(), GameType.JUMPNRUN), DEATHCUBE(new DeathcubeFactory(), GameType.JUMPNRUN),
STICKFIGHT(new StickFightFactory(), GameType.PVP),
MINERUN(new MinerunFactory(), GameType.JUMPNRUN), MINERUN(new MinerunFactory(), GameType.JUMPNRUN),
TRAFFICLIGHTRACE(new TrafficLightRaceFactory(), GameType.OTHER), TRAFFICLIGHTRACE(new TrafficLightRaceFactory(), GameType.OTHER),
STICKFIGHT(new StickFightFactory(), GameType.PROTOTYPE),
TOWERDEFENSE(new TowerdefenseFactory(), GameType.PROTOTYPE), TOWERDEFENSE(new TowerdefenseFactory(), GameType.PROTOTYPE),
BEDWARS(new BedwarsFactory(), GameType.PROTOTYPE), BEDWARS(new BedwarsFactory(), GameType.PROTOTYPE),
BACKROOMS(new BackroomsFactory(), GameType.PROTOTYPE), BACKROOMS(new BackroomsFactory(), GameType.PROTOTYPE),
ANVILRUN(new AnvilRunFactory(), GameType.PROTOTYPE), BOWSPLEEF(new BowSpleefFactory(), GameType.PROTOTYPE),
TETRIS(new TetrisFactory(), GameType.OTHER), TETRIS(new TetrisFactory(), GameType.OTHER),
TNTRUN(new TntRunFactory(), GameType.OTHER), TNTRUN(new TntRunFactory(), GameType.OTHER),
ANVILRUN(new AnvilRunFactory(), GameType.PVE),
ACIDRAIN(new AcidRainFactory(), GameType.PVE), ACIDRAIN(new AcidRainFactory(), GameType.PVE),
ELYTRARACE(new ElytraRaceFactory(), GameType.PVP), ELYTRARACE(new ElytraRaceFactory(), GameType.PVP),
SPLEEF(new SpleefFactory(), GameType.PVP), SPLEEF(new SpleefFactory(), GameType.PVP),
BOWSPLEEF(new BowSpleefFactory(), GameType.PVP); JUMPDIVE(new JumpDiveFactory(), GameType.JUMPNRUN),
BUILDBATTLE(new BuildBattleFactory(), GameType.OTHER);
private final GameFactory factory; private final GameFactory factory;
private final GameType type; private final GameType type;

View File

@ -11,6 +11,7 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.registry.DynamicRegistry; import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.timer.ExecutionType; import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.Task;
import net.minestom.server.timer.TaskSchedule; import net.minestom.server.timer.TaskSchedule;
import net.minestom.server.world.DimensionType; import net.minestom.server.world.DimensionType;
@ -20,6 +21,7 @@ import java.util.concurrent.CompletableFuture;
public class StatelessGame extends Game { public class StatelessGame extends Game {
private final String name; private final String name;
private final Score score; private final Score score;
private Task timeLimitTask;
private int timeLimit = 0; private int timeLimit = 0;
private int timePlayed = 0; private int timePlayed = 0;
@ -40,8 +42,12 @@ public class StatelessGame extends Game {
public void setTimeLimit(int limit) { public void setTimeLimit(int limit) {
this.timeLimit = limit; this.timeLimit = limit;
if(timeLimit > 0) { if(this.timeLimitTask != null) {
scheduler().submitTask(() -> { this.timeLimitTask.cancel();
this.timePlayed = 0;
}
if(this.timeLimit > 0) {
this.timeLimitTask = scheduler().submitTask(() -> {
if(!isRunning || timeLimit == 0) return TaskSchedule.stop(); if(!isRunning || timeLimit == 0) return TaskSchedule.stop();
if(timeLimit <= timePlayed) { if(timeLimit <= timePlayed) {
stop(); stop();

View File

@ -15,6 +15,11 @@ public class AcidRainFactory implements GameFactory {
return TranslatedComponent.byId("game_AcidRain#name"); return TranslatedComponent.byId("game_AcidRain#name");
} }
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_AcidRain#description");
}
@Override @Override
public Material symbol() { public Material symbol() {
return Material.SLIME_BALL; return Material.SLIME_BALL;

View File

@ -12,7 +12,12 @@ import java.util.Map;
public class BowSpleefFactory implements GameFactory { public class BowSpleefFactory implements GameFactory {
@Override @Override
public TranslatedComponent name() { public TranslatedComponent name() {
return TranslatedComponent.byId(""); return TranslatedComponent.byId("game_BowSpleef#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_BowSpleef#description");
} }
@Override @Override

View File

@ -0,0 +1,13 @@
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.NoScore;
public class BuildBattle extends StatelessGame {
public BuildBattle() {
super(Dimension.OVERWORLD.key, "buildBattle", new NoScore());
}
}

View File

@ -0,0 +1,21 @@
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.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 java.util.Map;
public class BuildBattleFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_BuildBattle#name");
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new BuildBattle();
}
}

View File

@ -0,0 +1,12 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.Score;
import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.world.DimensionType;
class BuilderWorld extends StatelessGame {
public BuilderWorld(DynamicRegistry.Key<DimensionType> dimensionType, String gameName, Score score) {
super(dimensionType, gameName, score);
}
}

View File

@ -169,6 +169,7 @@ public class ElytraRace extends StatelessGame {
if(newPos.z() > ringCount * ringSpacing) { if(newPos.z() > ringCount * ringSpacing) {
getScore().insertResult(player); getScore().insertResult(player);
player.setGameMode(GameMode.SPECTATOR); player.setGameMode(GameMode.SPECTATOR);
player.setFlyingWithElytra(false);
} }
} }

View File

@ -14,7 +14,12 @@ import java.util.Map;
public class ElytraRaceFactory implements GameFactory { public class ElytraRaceFactory implements GameFactory {
@Override @Override
public TranslatedComponent name() { public TranslatedComponent name() {
return TranslatedComponent.byId(""); return TranslatedComponent.byId("game_ElytraRace#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_ElytraRace#description");
} }
@Override @Override
@ -25,7 +30,7 @@ public class ElytraRaceFactory implements GameFactory {
@Override @Override
public ConfigManager configuration() { public ConfigManager configuration() {
return new ConfigManager() return new ConfigManager()
.addOption(new NumericOption("ringCount", Material.DIAMOND_BLOCK, TranslatedComponent.byId("ringCount"), 5, 10, 20, 30, 40, 50)); .addOption(new NumericOption("ringCount", Material.DIAMOND_BLOCK, TranslatedComponent.byId("game_ElytraRace#ringCount"), 5, 10, 20, 30, 40, 50));
} }
@Override @Override

View File

@ -0,0 +1,99 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.PointsWinScore;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.world.BlockPallet;
import net.kyori.adventure.sound.Sound;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block;
import net.minestom.server.sound.SoundEvent;
import org.jetbrains.annotations.NotNull;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
public class JumpDive extends StatelessGame {
private final int radius;
private final int height;
private final int timeLimit;
private final WeakHashMap<Player, Integer> scores = new WeakHashMap<>();
public JumpDive(int radius, int height, int timeLimit) {
super(Dimension.OVERWORLD.key, "jumpDive", new PointsWinScore());
this.radius = radius;
this.height = height;
this.timeLimit = timeLimit;
}
@Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = -radius*2; x <= radius*2; x++) {
for(int z = -radius*2; z <= radius*2; z++) {
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) {
batch.setBlock(x, height, z, BlockPallet.STONE.rnd());
} else {
batch.setBlock(x, 0, z, BlockPallet.GROUND.rnd());
batch.setBlock(x, 1, z, Block.WATER);
}
}
}
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
}
@Override
protected void onStart() {
setTimeLimit(timeLimit);
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player p = playerMoveEvent.getPlayer();
if(
p.isOnGround() && playerMoveEvent.getNewPosition().y() < height
|| playerMoveEvent.getNewPosition().y() < 0
|| isBeforeBeginning && playerMoveEvent.getNewPosition().y() < height
) {
p.teleport(getSpawn());
playerMoveEvent.setCancelled(true);
}
if(
playerMoveEvent.getNewPosition().y() <= 1
&& playerMoveEvent.getNewPosition().distance(0, 1, 0) < radius + 0.5
&& !(!isBeforeBeginning && !isRunning)
) {
setBlock(playerMoveEvent.getNewPosition().withY(1), Block.REDSTONE_BLOCK);
scores.merge(p, 1, Integer::sum);
p.teleport(getSpawn());
playerMoveEvent.setCancelled(true);
p.playSound(Sound.sound(SoundEvent.ENTITY_EXPERIENCE_ORB_PICKUP, Sound.Source.PLAYER, 2f, 2f));
}
}
@Override
protected void onStop() {
getPlayers().forEach(player -> getScore().insertResult(player, scores.getOrDefault(player, 0)));
}
@Override
public Pos getSpawn() {
double theta = rnd.nextDouble() * 2 * Math.PI;
double spawnRadius = radius + 2;
double x = spawnRadius * Math.cos(theta);
double z = spawnRadius * Math.sin(theta);
return new Pos(x, height + 2, z).withLookAt(new Pos(0, height, 0));
}
}

View File

@ -0,0 +1,43 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive;
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 JumpDiveFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_jumpDive#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_jumpDive#description");
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 5, 8, 10, 12, 14, 16))
.addOption(new NumericOption("height", Material.SCAFFOLDING, TranslatedComponent.byId("optionCommon#height"), 30, 60, 90))
.addOption(new NumericOption("timeLimit", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 60, 120, 180, 240, 300));
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new JumpDive(configuration.get("radius").getAsInt(), configuration.get("height").getAsInt(), configuration.get("timeLimit").getAsInt()).setParent(parent);
}
@Override
public Material symbol() {
return Material.WATER_BUCKET;
}
}

View File

@ -22,7 +22,7 @@ public class MinerunFactory implements GameFactory {
return new ConfigManager() return new ConfigManager()
.addOption(new NumericOption("width", Material.OAK_FENCE, TranslatedComponent.byId("optionCommon#width"), 10, 30, 50, 100)) .addOption(new NumericOption("width", Material.OAK_FENCE, TranslatedComponent.byId("optionCommon#width"), 10, 30, 50, 100))
.addOption(new NumericOption("length", Material.ZOMBIE_HEAD, TranslatedComponent.byId("optionCommon#length"), 50, 100, 150, 200)) .addOption(new NumericOption("length", Material.ZOMBIE_HEAD, TranslatedComponent.byId("optionCommon#length"), 50, 100, 150, 200))
.addOption(new NumericOption("percentage", Material.LIGHT_WEIGHTED_PRESSURE_PLATE, TranslatedComponent.byId("game_Minerun#optionPercentageMiens"), 30, 40, 50, 60, 70)); .addOption(new NumericOption("percentage", Material.LIGHT_WEIGHTED_PRESSURE_PLATE, TranslatedComponent.byId("game_Minerun#optionPercentageMines"), 30, 40, 50, 60, 70));
} }
@Override @Override

View File

@ -78,6 +78,7 @@ public class Spleef extends StatelessGame {
} }
private void destroyBlock(PlayerStartDiggingEvent event) { private void destroyBlock(PlayerStartDiggingEvent event) {
if(!isRunning) return;
setBlock(event.getBlockPosition(), Block.AIR); setBlock(event.getBlockPosition(), Block.AIR);
} }

View File

@ -33,7 +33,7 @@ public class SpleefFactory implements GameFactory {
@Override @Override
public ConfigManager configuration() { public ConfigManager configuration() {
return new ConfigManager() return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("game_Spleef#radius"), 10, 20, 30)) .addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 10, 20, 30))
.addOption(new NumericOption("stackCount", Material.SCAFFOLDING, TranslatedComponent.byId("game_Spleef#stackCount"), 1, 2, 3, 4, 5)); .addOption(new NumericOption("stackCount", Material.SCAFFOLDING, TranslatedComponent.byId("game_Spleef#stackCount"), 1, 2, 3, 4, 5));
} }

View File

@ -3,20 +3,23 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight;
import eu.mhsl.minenet.minigames.instance.Dimension; import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.LastWinsScore; import eu.mhsl.minenet.minigames.score.LastWinsScore;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import io.github.togar2.pvp.events.FinalAttackEvent; import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures; import io.github.togar2.pvp.feature.CombatFeatures;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class Stickfight extends StatelessGame { public class Stickfight extends StatelessGame {
private final double radius = 20;
private final WeakHashMap<Player, Pos> spawnPoints = new WeakHashMap<>();
public Stickfight() { public Stickfight() {
super(Dimension.OVERWORLD.key, "Stickfight", new LastWinsScore()); super(Dimension.OVERWORLD.key, "Stickfight", new LastWinsScore());
@ -38,21 +41,56 @@ public class Stickfight extends StatelessGame {
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); setBlock(0, 50, 0, Block.DIAMOND_BLOCK);
for (int z = -10; z <= 10; z++) {
batch.setBlock(0, 50, z, Block.SANDSTONE);
} }
batch.setBlock(0, 50, 0, Block.GOLD_BLOCK);
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null)); @Override
protected void start() {
List<Player> players = getPlayers().stream().toList();
int numPlayers = players.size();
for (int i = 0; i < numPlayers; i++) {
double angle = (2 * Math.PI / numPlayers) * i;
int spawnX = (int) (radius * Math.cos(angle));
int spawnZ = (int) (radius * Math.sin(angle));
int spawnY = 50;
Pos spawnpoint = new Pos(spawnX, spawnY + 1, spawnZ).add(0.5);
spawnPoints.put(players.get(i), spawnpoint.withLookAt(getSpawn()));
players.get(i).teleport(spawnpoint);
generateBridge(spawnX, spawnY, spawnZ);
}
setBlock(0, 50, 0, Block.GOLD_BLOCK);
super.start();
}
private void generateBridge(int startX, int startY, int startZ) {
int steps = (int) (radius * 1.5);
for (int i = 0; i < steps; i++) {
double t = (double) i / steps;
int x = (int) (startX * (1 - t));
int z = (int) (startZ * (1 - t));
setBlock(x, startY, z, Block.SANDSTONE);
}
} }
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(isBeforeBeginning) playerMoveEvent.setCancelled(true); if(!spawnPoints.containsKey(playerMoveEvent.getPlayer())) {
playerMoveEvent.setCancelled(true);
return;
}
if(isBeforeBeginning) {
if(spawnPoints.get(playerMoveEvent.getPlayer()).distance(playerMoveEvent.getNewPosition()) < 1) return;
playerMoveEvent.setCancelled(true);
playerMoveEvent.getPlayer().teleport(spawnPoints.get(playerMoveEvent.getPlayer()));
}
if(playerMoveEvent.getNewPosition().y() < 40) { if(playerMoveEvent.getNewPosition().y() < 40) {
playerMoveEvent.getPlayer().teleport(new Pos(0, 51, 0)); playerMoveEvent.getPlayer().teleport(spawnPoints.get(playerMoveEvent.getPlayer()));
} }
} }

View File

@ -7,7 +7,6 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.Tetro
import eu.mhsl.minenet.minigames.score.PointsWinScore; import eu.mhsl.minenet.minigames.score.PointsWinScore;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.GameMode; import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
@ -73,7 +72,6 @@ class Tetris extends StatelessGame {
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent event) { protected void onPlayerMove(@NotNull PlayerMoveEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
Pos previousPosition = event.getPlayer().getPosition();
Pos currentPosition = event.getNewPosition(); Pos currentPosition = event.getNewPosition();
TetrisGame tetrisGame = this.tetrisGames.get(player); TetrisGame tetrisGame = this.tetrisGames.get(player);
@ -85,37 +83,14 @@ class Tetris extends StatelessGame {
if(tetrisGame.lost) return; if(tetrisGame.lost) return;
if(player.getGameMode() == GameMode.SPECTATOR) return; if(player.getGameMode() == GameMode.SPECTATOR) return;
if(player.inputs().forward()) tetrisGame.pressedButton(TetrisGame.Button.W);
if(player.inputs().backward()) tetrisGame.pressedButton(TetrisGame.Button.S);
if(player.inputs().right()) tetrisGame.pressedButton(TetrisGame.Button.D);
if(player.inputs().left()) tetrisGame.pressedButton(TetrisGame.Button.A);
if(player.inputs().jump()) tetrisGame.pressedButton(TetrisGame.Button.space);
event.setNewPosition(tetrisGame.getPlayerSpawnPosition().withView(currentPosition)); event.setNewPosition(tetrisGame.getPlayerSpawnPosition().withView(currentPosition));
player.setSprinting(false); player.setSprinting(false);
Vec movementVector = currentPosition.asVec().sub(previousPosition.asVec());
float yaw = player.getPosition().yaw();
double yawRadians = Math.toRadians(yaw);
double forwardX = -Math.sin(yawRadians);
double forwardZ = Math.cos(yawRadians);
Vec forward = new Vec(forwardX, 0, forwardZ).normalize();
Vec left = forward.cross(new Vec(0, 1, 0)).normalize();
double forwardAmount = movementVector.dot(forward);
double leftAmount = movementVector.dot(left);
double buttonPressAmount = 0.05;
if (forwardAmount > buttonPressAmount) {
tetrisGame.pressedButton(TetrisGame.Button.W);
} else if (forwardAmount < -buttonPressAmount) {
tetrisGame.pressedButton(TetrisGame.Button.S);
}
if (leftAmount > buttonPressAmount) {
tetrisGame.pressedButton(TetrisGame.Button.D);
} else if (leftAmount < -buttonPressAmount) {
tetrisGame.pressedButton(TetrisGame.Button.A);
}
if(previousPosition.y() < currentPosition.y()) tetrisGame.pressedButton(TetrisGame.Button.space);
} }
protected void onPlayerInteract(@NotNull PlayerUseItemEvent event) { protected void onPlayerInteract(@NotNull PlayerUseItemEvent event) {

View File

@ -7,10 +7,7 @@ import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos; 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.GameMode;
import net.minestom.server.entity.metadata.other.PrimedTntMeta;
import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch; import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
@ -51,7 +48,13 @@ public class TntRun extends StatelessGame {
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(playerMoveEvent.getNewPosition().y() < totalElevation) { if(playerMoveEvent.getNewPosition().y() < totalElevation) {
if(isBeforeBeginning) {
playerMoveEvent.getPlayer().teleport(getSpawn());
return;
}
playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR); playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
getScore().insertResult(playerMoveEvent.getPlayer()); getScore().insertResult(playerMoveEvent.getPlayer());
} }
@ -67,10 +70,10 @@ public class TntRun extends StatelessGame {
setBlock(firstLocation, Block.AIR); setBlock(firstLocation, Block.AIR);
setBlock(secondLocation, Block.AIR); setBlock(secondLocation, Block.AIR);
Entity fallingTnt = new Entity(EntityType.TNT); // Entity fallingTnt = new Entity(EntityType.TNT);
PrimedTntMeta fallingTntMeta = (PrimedTntMeta) fallingTnt.getEntityMeta(); // PrimedTntMeta fallingTntMeta = (PrimedTntMeta) fallingTnt.getEntityMeta();
fallingTntMeta.setFuseTime(20); // fallingTntMeta.setFuseTime(20);
fallingTnt.setInstance(this, secondLocation); // fallingTnt.setInstance(this, secondLocation);
} }
} }
} }

View File

@ -14,7 +14,12 @@ import java.util.Map;
public class TntRunFactory implements GameFactory { public class TntRunFactory implements GameFactory {
@Override @Override
public TranslatedComponent name() { public TranslatedComponent name() {
return TranslatedComponent.byId("game_tntRun#name"); return TranslatedComponent.byId("game_TntRun#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_TntRun#description");
} }
@Override @Override
@ -25,8 +30,8 @@ public class TntRunFactory implements GameFactory {
@Override @Override
public ConfigManager configuration() { public ConfigManager configuration() {
return new ConfigManager() return new ConfigManager()
.addOption(new NumericOption("radius", Material.STICK, TranslatedComponent.byId("game_tntRun#radius"), 20, 30, 50, 60)) .addOption(new NumericOption("radius", Material.STICK, TranslatedComponent.byId("optionCommon#radius"), 20, 30, 50, 60))
.addOption(new NumericOption("levels", Material.SCAFFOLDING, TranslatedComponent.byId("game_tntRun#levels"), 1, 2, 3, 4, 5)); .addOption(new NumericOption("levels", Material.SCAFFOLDING, TranslatedComponent.byId("game_TntRun#levels"), 1, 2, 3, 4, 5));
} }
@Override @Override

View File

@ -17,6 +17,11 @@ public class TrafficLightRaceFactory implements GameFactory {
return TranslatedComponent.byId("game_TrafficlightRace#name"); return TranslatedComponent.byId("game_TrafficlightRace#name");
} }
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_TrafficlightRace#description");
}
@Override @Override
public ConfigManager configuration() { public ConfigManager configuration() {
return new ConfigManager() return new ConfigManager()

View File

@ -41,7 +41,7 @@ public class Room extends MineNetInstance implements Spawnable {
} }
public static void deleteRoom(Room room) { public static void deleteRoom(Room room) {
logger.info("Deleting room " + room.uniqueId); logger.info("Deleting room " + room.uuid);
rooms.remove(room); rooms.remove(room);
players.values().removeAll(Collections.singleton(room)); players.values().removeAll(Collections.singleton(room));
room.getAllMembers().forEach(player -> MoveInstance.move(player, Hub.INSTANCE)); room.getAllMembers().forEach(player -> MoveInstance.move(player, Hub.INSTANCE));
@ -65,6 +65,7 @@ public class Room extends MineNetInstance implements Spawnable {
p.clearTitle(); p.clearTitle();
p.getInventory().clear(); p.getInventory().clear();
p.setGameMode(GameMode.ADVENTURE); p.setGameMode(GameMode.ADVENTURE);
p.setInvisible(false);
rooms.add(room); rooms.add(room);
players.put(p, room); players.put(p, room);
MoveInstance.move(p, room); MoveInstance.move(p, room);

View File

@ -31,7 +31,7 @@ public class Languages {
return getLanguage(p.getSettings().locale().toString()); // TODO funktioniert die locale noch? return getLanguage(p.getSettings().locale().toString()); // TODO funktioniert die locale noch?
} }
public Lang getLanguage(String mapId) { public Lang getLanguage(String mapId) {
return languages.computeIfAbsent(mapId, unused -> languages.computeIfAbsent(defaultLanguage, (key) -> new DummyLang())); return languages.computeIfAbsent(mapId.toLowerCase(), unused -> languages.computeIfAbsent(defaultLanguage, (key) -> new DummyLang()));
} }
private void readAll() { private void readAll() {

View File

@ -28,10 +28,6 @@ public class InteractableEntity extends EntityCreature {
.addListener(PlayerEntityInteractEvent.class, this::onInteract) //TODO Why are some of these listeners not working? .addListener(PlayerEntityInteractEvent.class, this::onInteract) //TODO Why are some of these listeners not working?
.addListener(EntityAttackEvent.class, this::onAttack); .addListener(EntityAttackEvent.class, this::onAttack);
System.out.println(eventNode().getChildren());
System.out.println(eventNode().getParent().getChildren());
} }
private void setInstanceEvent(@NotNull AddEntityToInstanceEvent addEntityToInstanceEvent) { private void setInstanceEvent(@NotNull AddEntityToInstanceEvent addEntityToInstanceEvent) {

View File

@ -3,7 +3,6 @@ package eu.mhsl.minenet.minigames.skin;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.entity.PlayerSkin; import net.minestom.server.entity.PlayerSkin;
import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.TaskSchedule; import net.minestom.server.timer.TaskSchedule;
import java.util.HashMap; import java.util.HashMap;
@ -12,19 +11,15 @@ import java.util.Map;
public class SkinCache { public class SkinCache {
private static final Map<String, PlayerSkin> skins = new HashMap<>(); private static final Map<String, PlayerSkin> skins = new HashMap<>();
public static PlayerSkin getSkin(Player p) {
return SkinCache.getSkin(p.getUsername());
}
public static PlayerSkin getSkin(String p) { public static PlayerSkin getSkin(String p) {
if(!skins.containsKey(p)) skins.put(p, PlayerSkin.fromUsername(p)); if(!skins.containsKey(p)) skins.put(p, PlayerSkin.fromUsername(p));
return skins.get(p); return skins.get(p);
} }
public static void applySkin(Player p) { public static void applySkin(Player p) {
MinecraftServer.getSchedulerManager().submitTask(() -> { MinecraftServer.getSchedulerManager().scheduleTask(() -> {
p.setSkin(SkinCache.getSkin(p.getUsername())); p.setSkin(SkinCache.getSkin(p.getUsername()));
return TaskSchedule.stop(); return TaskSchedule.stop();
}, ExecutionType.TICK_END); }, TaskSchedule.millis(500));
} }
} }

View File

@ -67,7 +67,7 @@ public class SquarePlateTerrainGenerator extends PlateTerrainGenerator {
} }
if(generateBorders) { if(generateBorders) {
Runnable generateBorder = () -> unit.modifier().fill(bottom, bottom.add(1, 0, 1), Block.BARRIER); // TODO DimensionType.OVERWORLD.getMaxY() is now hardcoded 0, might break behaviour Runnable generateBorder = () -> unit.modifier().fill(bottom, bottom.add(1, DimensionType.VANILLA_MAX_Y, 1), Block.BARRIER);
if(bottom.z() <= length+1 && bottom.z() >= -1 && bottom.x() >= -1 && bottom.x() <= width+1) { if(bottom.z() <= length+1 && bottom.z() >= -1 && bottom.x() >= -1 && bottom.x() <= width+1) {
if(bottom.x() == -1 || bottom.x() == width+1) { if(bottom.x() == -1 || bottom.x() == width+1) {

View File

@ -23,7 +23,11 @@ other_description;Games which does not fit into other Categories;Spiele welche n
pvp;Player vs Player;Spieler gegen Spieler pvp;Player vs Player;Spieler gegen Spieler
pvp_description;Fight against other Players;Kämpfe gegen andere Spieler pvp_description;Fight against other Players;Kämpfe gegen andere Spieler
pve;Player vs Enviroment;Spieler gegen Umwelt pve;Player vs Enviroment;Spieler gegen Umwelt
pve_description;Surivie the world or fight entities;Überlebe die Welt oder kämpfe gegen Mobs pve_description;Survive the world or fight entities;Überlebe die Welt oder kämpfe gegen Mobs
jumpnrun;jump and run;jump and run
jumpnrun_description;Proof your jump-and-run skills;Stelle deine jump-and-run Fähigkeiten unter Beweis
prototype;Prototype;Prototyp
prototype_description;Prototype games;Prototyp Spiele
;; ;;
ns:hub#;; ns:hub#;;
invTitle;MineNet Servernetwork;MineNet Servernetzwerk invTitle;MineNet Servernetwork;MineNet Servernetzwerk
@ -36,7 +40,7 @@ join_notFound;Lobby not found: ;Lobby konnte nicht gefunden werden:
;; ;;
ns:score#;; ns:score#;;
result;Results;Ergebnisse result;Results;Ergebnisse
thanks;Thank you for Playing;Danke für's spielen thanks;Thank you for Playing;Danke für's Spielen
finish;You did it;Du hast es geschafft finish;You did it;Du hast es geschafft
death;You are out;Du hast verloren death;You are out;Du hast verloren
done;Finish;Fertig done;Finish;Fertig
@ -65,15 +69,26 @@ noOptionDescription;There are no options for this Game;Es gibt keine Einstellung
ns:GameFactory#;; ns:GameFactory#;;
missingDescription;No description;Keine Beschreibung missingDescription;No description;Keine Beschreibung
;; ;;
ns:game_TntRun#;;
name;TNT run;TNT Rennen
description;The tnt at the ground disappears, don't fall;Das TNT am Boden verschwindet, falle nicht herunter
levels;levels;Ebenen
;;
ns:game_ElytraRace#;;
name;Elytra race;Elytra Rennen
description;Be fast while flying through the rings;Sei schnell während du durch die Ringe fliegst
ringCount;ring count;Anzahl der Ringe
;;
ns:game_Minerun#;; ns:game_Minerun#;;
name;Minerun;Minenrennen name;Minerun;Minenrennen
description;Ditch deadly Mines in the ground an be the first in the goal;Weiche den tödlichen Bodenmienen aus und sei der erste im Ziel description;Ditch deadly Mines in the ground an be the first in the goal;Weiche den tödlichen Bodenmienen aus und sei der erste im Ziel
optionPercentageMines;Percentage of Miens;Prozentsatz der Minen optionPercentageMines;Percentage of mines;Prozentsatz der Minen
;; ;;
ns:game_Deathcube#;; ns:game_Deathcube#;;
name;Deathcube;Todeswürfel name;Deathcube;Todeswürfel
description;Find a way to jump higher and be the first on the top;Finde einen weg nach oben und sei der erste im Ziel description;Find a way to jump higher and be the first on the top;Finde einen weg nach oben und sei der erste im Ziel
optionPercentageBlocks;Percentage of Blocks;Prozentsatz der Blöcke optionPercentageBlocks;Percentage of Blocks;Prozentsatz der Blöcke
optionPvpEnabled;pvp enabled;PvP aktiviert
;; ;;
ns:game_Stickfight#;; ns:game_Stickfight#;;
name;Stickfight;Stockschlacht name;Stickfight;Stockschlacht
@ -83,6 +98,14 @@ ns:game_TrafficlightRace#;;
name;Red light green light;Rotes licht, Grünes licht name;Red light green light;Rotes licht, Grünes licht
description;Only go forward if the Trafficlights show green;Gehe nur bei Grün vorran description;Only go forward if the Trafficlights show green;Gehe nur bei Grün vorran
;; ;;
ns:game_AcidRain#;;
name;Acid rain;Säureregen
description;Stay under the holey roof to dodge acid rain;Bleib unter dem löchrigen Dach um dem sauren Regen auszuweichen
;;
ns:game_BowSpleef#;;
name;Bow spleef;Bogen Spleef
description;Spleef other players and be the last survivor;Zerstöre Blöcke unter anderen Spielern und sei der letzte im Feld
;;
ns:game_Towerdefense#;; ns:game_Towerdefense#;;
name;Towerdefense;Towerdefense name;Towerdefense;Towerdefense
description;Protect the path ????;?????? description;Protect the path ????;??????
@ -91,6 +114,7 @@ ns:game_Spleef#;;
name;Spleef;Spleef; name;Spleef;Spleef;
description;Spleef other players and be the last survivor;Zerstöre Blöcke unter anderen Spielern und sei der letzte im Feld description;Spleef other players and be the last survivor;Zerstöre Blöcke unter anderen Spielern und sei der letzte im Feld
shovelName;Snow thrower;Schneeflug shovelName;Snow thrower;Schneeflug
stackCount;levels;Ebenen
;; ;;
ns:game_Tetris#;; ns:game_Tetris#;;
name;Tetris;Tetris name;Tetris;Tetris
@ -100,5 +124,9 @@ isFast;Fast mode;Schneller Modus
hasCombat;Competitive mode;Kompetitiver Modus hasCombat;Competitive mode;Kompetitiver Modus
;; ;;
ns:game_AnvilRun#;; ns:game_AnvilRun#;;
name;Anvil Run;Anvil Run name;Anvil run;Anvil run
description;Run away from falling anvils;Renne von fallenden Ambossen davon description;Run away from falling anvils;Renne von fallenden Ambossen davon
;;
ns:game_jumpDive#;;
name;Jump dive;Wassersprung
description;Jump into the water, avoiding already used spots!;Springe ins wasser an stellen, in denen noch niemand zuvor gelandet ist!

Can't render this file because it has a wrong number of fields in line 114.