Compare commits
1 Commits
develop
...
develop-ha
Author | SHA1 | Date | |
---|---|---|---|
cc371a9c12 |
@ -10,6 +10,8 @@ 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()
|
||||||
|
|
||||||
@ -44,7 +46,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:fd51c8d17a'
|
implementation 'net.minestom:minestom-snapshots:59406d5b54'
|
||||||
|
|
||||||
//Tools
|
//Tools
|
||||||
implementation 'de.articdive:jnoise:3.0.2'
|
implementation 'de.articdive:jnoise:3.0.2'
|
||||||
@ -53,11 +55,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.1-android'
|
implementation 'com.google.guava:guava:32.0.0-android'
|
||||||
|
|
||||||
|
|
||||||
//PvP
|
//PvP
|
||||||
implementation 'io.github.TogAr2:MinestomPvP:PR62-SNAPSHOT'
|
implementation 'com.github.TogAr2:MinestomPvP:04180ddf9a'
|
||||||
|
|
||||||
// Hephaestus engine
|
// Hephaestus engine
|
||||||
implementation("team.unnamed:hephaestus-api:0.2.1-SNAPSHOT")
|
implementation("team.unnamed:hephaestus-api:0.2.1-SNAPSHOT")
|
||||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,7 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||||
networkTimeout=10000
|
|
||||||
validateDistributionUrl=true
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
56
gradlew
vendored
Executable file → Normal file
56
gradlew
vendored
Executable file → Normal file
@ -15,8 +15,6 @@
|
|||||||
# 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
|
|
||||||
#
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
@ -27,7 +25,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
|
||||||
# command line, like:
|
# eu.mhsl.minenet.minigames.command line, like:
|
||||||
#
|
#
|
||||||
# ksh Gradle
|
# ksh Gradle
|
||||||
#
|
#
|
||||||
@ -37,7 +35,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 «command», «set», and «ulimit».
|
# * various built-in commands including «eu.mhsl.minenet.minigames.command», «set», and «ulimit».
|
||||||
#
|
#
|
||||||
# Important for patching:
|
# Important for patching:
|
||||||
#
|
#
|
||||||
@ -57,7 +55,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/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/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/.
|
||||||
@ -82,12 +80,13 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# This is normally unused
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
# 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)
|
|
||||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
' "$PWD" ) || exit
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# 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
|
||||||
@ -118,7 +117,7 @@ esac
|
|||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java eu.mhsl.minenet.minigames.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
|
||||||
@ -134,36 +133,29 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
JAVACMD=java
|
||||||
if ! command -v java >/dev/null 2>&1
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
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 command, stacking in reverse order:
|
# Collect all arguments for the java eu.mhsl.minenet.minigames.command, stacking in reverse order:
|
||||||
# * args from the command line
|
# * args from the eu.mhsl.minenet.minigames.command line
|
||||||
# * the main class name
|
# * the main class name
|
||||||
# * -classpath
|
# * -classpath
|
||||||
# * -D...appname settings
|
# * -D...appname settings
|
||||||
@ -201,15 +193,11 @@ if "$cygwin" || "$msys" ; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java eu.mhsl.minenet.minigames.command;
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
# double quotes to make sure that they get re-expanded; and
|
||||||
# Collect all arguments for the java command:
|
# * put everything else in single quotes, so that it's not re-expanded.
|
||||||
# * 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" \
|
||||||
@ -217,12 +205,6 @@ 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.
|
||||||
@ -232,7 +214,7 @@ fi
|
|||||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
# set -- "${ARGS[@]}" "$@"
|
# set -- "${ARGS[@]}" "$@"
|
||||||
#
|
#
|
||||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
# but POSIX shell has neither arrays nor eu.mhsl.minenet.minigames.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
35
gradlew.bat
vendored
@ -13,8 +13,6 @@
|
|||||||
@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 ##########################################################################
|
||||||
@ -28,7 +26,6 @@ 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%
|
||||||
|
|
||||||
@ -43,13 +40,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% equ 0 goto execute
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
echo ERROR: JAVA_HOME is not set and no 'java' eu.mhsl.minenet.gameList.command could be found in your PATH.
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
@ -59,16 +56,16 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
echo. 1>&2
|
echo.
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation.
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the eu.mhsl.minenet.gameList.command line
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
@ -78,15 +75,13 @@ 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% equ 0 goto mainEnd
|
if "%ERRORLEVEL%"=="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!
|
||||||
set EXIT_CODE=%ERRORLEVEL%
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
exit /b 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
|
||||||
|
@ -5,6 +5,8 @@ import eu.mhsl.minenet.minigames.command.Commands;
|
|||||||
import eu.mhsl.minenet.minigames.handler.Listeners;
|
import eu.mhsl.minenet.minigames.handler.Listeners;
|
||||||
import eu.mhsl.minenet.minigames.lang.Languages;
|
import eu.mhsl.minenet.minigames.lang.Languages;
|
||||||
import eu.mhsl.minenet.minigames.server.tasks.TablistUpdateTask;
|
import eu.mhsl.minenet.minigames.server.tasks.TablistUpdateTask;
|
||||||
|
import eu.mhsl.minenet.minigames.server.provider.ByPlayerNameUuidProvider;
|
||||||
|
import io.github.togar2.pvp.MinestomPvP;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.extras.bungee.BungeeCordProxy;
|
import net.minestom.server.extras.bungee.BungeeCordProxy;
|
||||||
import net.minestom.server.extras.lan.OpenToLAN;
|
import net.minestom.server.extras.lan.OpenToLAN;
|
||||||
@ -40,12 +42,14 @@ public class Main {
|
|||||||
logger.info("Initialize Minecraft server...");
|
logger.info("Initialize Minecraft server...");
|
||||||
|
|
||||||
MinecraftServer server = MinecraftServer.init();
|
MinecraftServer server = MinecraftServer.init();
|
||||||
// MinestomPvP.init();
|
MinestomPvP.init();
|
||||||
|
|
||||||
MinecraftServer.setBrandName("mhsl.eu - minenet - credits to minestom");
|
MinecraftServer.setBrandName("mhsl.eu - minenet - credits to minestom");
|
||||||
MinecraftServer.setCompressionThreshold(serverConfig.node("compression-threshold").getInt(0));
|
MinecraftServer.setCompressionThreshold(serverConfig.node("compression-threshold").getInt(0));
|
||||||
System.setProperty("minestom.chunk-view-distance", String.valueOf(serverConfig.node("view-distance").getInt()));
|
System.setProperty("minestom.chunk-view-distance", String.valueOf(serverConfig.node("view-distance").getInt()));
|
||||||
|
|
||||||
|
MinecraftServer.getConnectionManager().setUuidProvider(new ByPlayerNameUuidProvider());
|
||||||
|
|
||||||
Commands.values();
|
Commands.values();
|
||||||
Listeners.values();
|
Listeners.values();
|
||||||
new HttpServer();
|
new HttpServer();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package eu.mhsl.minenet.minigames.command;
|
package eu.mhsl.minenet.minigames.command;
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.command.privileged.SkinCommand;
|
import eu.mhsl.minenet.minigames.command.anonymous.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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package eu.mhsl.minenet.minigames.command;
|
|||||||
|
|
||||||
import net.minestom.server.command.builder.Command;
|
import net.minestom.server.command.builder.Command;
|
||||||
import net.minestom.server.command.builder.condition.CommandCondition;
|
import net.minestom.server.command.builder.condition.CommandCondition;
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -28,7 +27,7 @@ public class PrivilegedCommand extends Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected CommandCondition isPrivileged() {
|
protected CommandCondition isPrivileged() {
|
||||||
return (sender, commandString) -> ((Player) sender).getPermissionLevel() == 4;
|
return (sender, commandString) -> sender.hasPermission("admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addCondition(CommandCondition condition) {
|
protected void addCondition(CommandCondition condition) {
|
||||||
|
@ -10,13 +10,9 @@ public class HubCommand extends Command {
|
|||||||
public HubCommand() {
|
public HubCommand() {
|
||||||
super("hub");
|
super("hub");
|
||||||
|
|
||||||
setCondition(
|
setCondition((sender, commandString) -> ((Player) sender).getInstance() instanceof Room);
|
||||||
(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);
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package eu.mhsl.minenet.minigames.command.privileged;
|
package eu.mhsl.minenet.minigames.command.anonymous;
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.command.PrivilegedCommand;
|
import net.minestom.server.command.builder.Command;
|
||||||
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 PrivilegedCommand {
|
public class SkinCommand extends Command {
|
||||||
public SkinCommand() {
|
public SkinCommand() {
|
||||||
super("skin");
|
super("skin");
|
||||||
|
|
@ -5,6 +5,7 @@ import eu.mhsl.minenet.minigames.message.Icon;
|
|||||||
import eu.mhsl.minenet.minigames.message.type.ActionBarMessage;
|
import eu.mhsl.minenet.minigames.message.type.ActionBarMessage;
|
||||||
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
|
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
|
||||||
import eu.mhsl.minenet.minigames.message.type.TitleMessage;
|
import eu.mhsl.minenet.minigames.message.type.TitleMessage;
|
||||||
|
import eu.mhsl.minenet.minigames.util.PacketUtil;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -35,6 +36,8 @@ public class DebugCommand extends PrivilegedCommand {
|
|||||||
.appendTranslated("score#thanks")
|
.appendTranslated("score#thanks")
|
||||||
.send(sender);
|
.send(sender);
|
||||||
|
|
||||||
|
PacketUtil.resendPlayerList(((Player) sender));
|
||||||
|
|
||||||
new ChatMessage(Icon.SCIENCE).appendStatic(((Player) sender).getUuid().toString()).send(sender);
|
new ChatMessage(Icon.SCIENCE).appendStatic(((Player) sender).getUuid().toString()).send(sender);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import eu.mhsl.minenet.minigames.message.type.ChatMessage;
|
|||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
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.permission.Permission;
|
||||||
|
|
||||||
public class OpCommand extends PrivilegedCommand {
|
public class OpCommand extends PrivilegedCommand {
|
||||||
public OpCommand() {
|
public OpCommand() {
|
||||||
@ -14,7 +15,7 @@ public class OpCommand extends PrivilegedCommand {
|
|||||||
addSyntax((sender, context) -> {
|
addSyntax((sender, context) -> {
|
||||||
Player target = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("target"));
|
Player target = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("target"));
|
||||||
if(target != null) {
|
if(target != null) {
|
||||||
target.setPermissionLevel(4);
|
target.addPermission(new Permission("admin"));
|
||||||
target.refreshCommands();
|
target.refreshCommands();
|
||||||
} else new ChatMessage(Icon.ERROR).appendStatic("Spieler nicht gefunden").send(sender);
|
} else new ChatMessage(Icon.ERROR).appendStatic("Spieler nicht gefunden").send(sender);
|
||||||
}, ArgumentType.Entity("target").onlyPlayers(true));
|
}, ArgumentType.Entity("target").onlyPlayers(true));
|
||||||
|
@ -24,7 +24,7 @@ public class PublishRewardCommand extends PrivilegedCommand {
|
|||||||
|
|
||||||
String rewardRequestJson = new Gson().toJson(room.getTournament().getRewards());
|
String rewardRequestJson = new Gson().toJson(room.getTournament().getRewards());
|
||||||
HttpRequest giveRewardsRequest = HttpRequest.newBuilder()
|
HttpRequest giveRewardsRequest = HttpRequest.newBuilder()
|
||||||
.uri(new URI("http://10.20.7.1:8080/api/event/reward"))
|
.uri(new URI("http://10.20.6.1:8080/api/event/reward"))
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(rewardRequestJson))
|
.POST(HttpRequest.BodyPublishers.ofString(rewardRequestJson))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import net.minestom.server.event.EventListener;
|
|||||||
|
|
||||||
public enum Listeners {
|
public enum Listeners {
|
||||||
SPAWN(new AddEntityToInstanceEventListener()),
|
SPAWN(new AddEntityToInstanceEventListener()),
|
||||||
|
CHAT(new PlayerChatHandler()),
|
||||||
LOGIN(new PlayerLoginHandler()),
|
LOGIN(new PlayerLoginHandler()),
|
||||||
LEAVE(new PlayerLeaveHandler());
|
LEAVE(new PlayerLeaveHandler());
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package eu.mhsl.minenet.minigames.handler.global;
|
package eu.mhsl.minenet.minigames.handler.global;
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.instance.Spawnable;
|
import eu.mhsl.minenet.minigames.instance.Spawnable;
|
||||||
|
import eu.mhsl.minenet.minigames.util.PacketUtil;
|
||||||
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.event.EventListener;
|
import net.minestom.server.event.EventListener;
|
||||||
@ -25,7 +26,9 @@ public class AddEntityToInstanceEventListener implements EventListener<AddEntity
|
|||||||
p.setRespawnPoint(instance.getSpawn());
|
p.setRespawnPoint(instance.getSpawn());
|
||||||
}
|
}
|
||||||
|
|
||||||
p.addEffect(new Potion(PotionEffect.BLINDNESS, (byte) 1, 20));
|
PacketUtil.resendPlayerList(p);
|
||||||
|
|
||||||
|
p.addEffect(new Potion(PotionEffect.BLINDNESS, (byte) 1, 20)); //TODO Uncomment, currently buggy causes disconnect see https://github.com/Minestom/Minestom/discussions/1302
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.SUCCESS;
|
return Result.SUCCESS;
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.handler.global;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
|
||||||
|
import net.minestom.server.event.EventListener;
|
||||||
|
import net.minestom.server.event.player.PlayerChatEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class PlayerChatHandler implements EventListener<PlayerChatEvent> {
|
||||||
|
@Override
|
||||||
|
public @NotNull Class<PlayerChatEvent> eventType() {
|
||||||
|
return PlayerChatEvent.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Result run(@NotNull PlayerChatEvent event) {
|
||||||
|
event.setChatFormat(
|
||||||
|
(messages) -> new ChatMessage()
|
||||||
|
.appendStatic(event.getPlayer().getUsername())
|
||||||
|
.pipe()
|
||||||
|
.appendStatic(messages.getMessage())
|
||||||
|
.build(event.getPlayer())
|
||||||
|
);
|
||||||
|
|
||||||
|
return Result.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
@ -11,8 +11,7 @@ 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.permission.Permission;
|
||||||
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;
|
||||||
@ -22,11 +21,6 @@ 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;
|
||||||
@ -44,14 +38,13 @@ 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(1),
|
TaskSchedule.seconds(5),
|
||||||
TaskSchedule.stop()
|
TaskSchedule.stop()
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -59,7 +52,7 @@ public class PlayerLoginHandler implements EventListener<AsyncPlayerConfiguratio
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if(Objects.requireNonNull(Main.globalConfig.node("admins").getList(String.class)).stream().anyMatch(s -> s.equalsIgnoreCase(p.getUsername()))) {
|
if(Objects.requireNonNull(Main.globalConfig.node("admins").getList(String.class)).stream().anyMatch(s -> s.equalsIgnoreCase(p.getUsername()))) {
|
||||||
p.setPermissionLevel(4);
|
p.addPermission(new Permission("admin"));
|
||||||
}
|
}
|
||||||
} catch (SerializationException | NullPointerException ignored) {}
|
} catch (SerializationException | NullPointerException ignored) {}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public abstract class Game extends MineNetInstance implements Spawnable {
|
|||||||
|
|
||||||
MinecraftServer.getInstanceManager().registerInstance(this);
|
MinecraftServer.getInstanceManager().registerInstance(this);
|
||||||
|
|
||||||
logger = Logger.getLogger("Game:" + getUuid());
|
logger = Logger.getLogger("Game:" + getUniqueId());
|
||||||
|
|
||||||
eventNode()
|
eventNode()
|
||||||
.addListener(PlayerMoveEvent.class, this::onPlayerMove)
|
.addListener(PlayerMoveEvent.class, this::onPlayerMove)
|
||||||
@ -63,17 +63,6 @@ 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());
|
||||||
@ -113,7 +102,7 @@ public abstract class Game extends MineNetInstance implements Spawnable {
|
|||||||
|
|
||||||
scheduler().scheduleTask(() -> {
|
scheduler().scheduleTask(() -> {
|
||||||
|
|
||||||
logger.info("stopping game instance " + this.uuid);
|
logger.info("stopping game instance " + this.uniqueId);
|
||||||
getPlayers().forEach(player -> player.kick("timeout"));
|
getPlayers().forEach(player -> player.kick("timeout"));
|
||||||
|
|
||||||
MinecraftServer.getInstanceManager().unregisterInstance(this);
|
MinecraftServer.getInstanceManager().unregisterInstance(this);
|
||||||
|
@ -8,31 +8,30 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.Backroo
|
|||||||
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;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.TetrisFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.test.Test;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.test.TestFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tntrun.TntRunFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tntrun.TntRunFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.TowerdefenseFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.TowerdefenseFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace.TrafficLightRaceFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace.TrafficLightRaceFactory;
|
||||||
|
|
||||||
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),
|
||||||
BOWSPLEEF(new BowSpleefFactory(), GameType.PROTOTYPE),
|
|
||||||
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),
|
||||||
|
ANVILRUN(new AnvilRunFactory(), GameType.PVE),
|
||||||
ELYTRARACE(new ElytraRaceFactory(), GameType.PVP),
|
ELYTRARACE(new ElytraRaceFactory(), GameType.PVP),
|
||||||
SPLEEF(new SpleefFactory(), GameType.PVP),
|
SPLEEF(new SpleefFactory(), GameType.PVP),
|
||||||
JUMPDIVE(new JumpDiveFactory(), GameType.JUMPNRUN);
|
BOWSPLEEF(new BowSpleefFactory(), GameType.PVP),
|
||||||
|
Test(new TestFactory(), GameType.OTHER);
|
||||||
|
|
||||||
private final GameFactory factory;
|
private final GameFactory factory;
|
||||||
private final GameType type;
|
private final GameType type;
|
||||||
|
@ -11,7 +11,6 @@ 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;
|
||||||
|
|
||||||
@ -21,7 +20,6 @@ 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;
|
||||||
@ -42,12 +40,8 @@ public class StatelessGame extends Game {
|
|||||||
|
|
||||||
public void setTimeLimit(int limit) {
|
public void setTimeLimit(int limit) {
|
||||||
this.timeLimit = limit;
|
this.timeLimit = limit;
|
||||||
if(this.timeLimitTask != null) {
|
if(timeLimit > 0) {
|
||||||
this.timeLimitTask.cancel();
|
scheduler().submitTask(() -> {
|
||||||
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();
|
||||||
@ -56,7 +50,7 @@ public class StatelessGame extends Game {
|
|||||||
|
|
||||||
int timeLeft = timeLimit - timePlayed;
|
int timeLeft = timeLimit - timePlayed;
|
||||||
switch (timeLeft) {
|
switch (timeLeft) {
|
||||||
case 90, 60, 30, 10, 5, 4, 3, 2, 1 ->
|
case 60, 30, 10, 5, 4, 3, 2, 1 ->
|
||||||
new ChatMessage(Icon.SCIENCE).appendStatic("Noch " + timeLeft + " Sekunden!").send(getPlayers());
|
new ChatMessage(Icon.SCIENCE).appendStatic("Noch " + timeLeft + " Sekunden!").send(getPlayers());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import net.minestom.server.item.ItemStack;
|
|||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public abstract class Option<T> {
|
public abstract class Option<T> {
|
||||||
private RestrictionHandler restrictionHandler;
|
private RestrictionHandler restrictionHandler;
|
||||||
@ -26,7 +25,7 @@ public abstract class Option<T> {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
|
||||||
currentValue = options.getFirst();
|
currentValue = options.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRestrictionHandler(RestrictionHandler restrictionHandler) {
|
public void setRestrictionHandler(RestrictionHandler restrictionHandler) {
|
||||||
@ -45,11 +44,11 @@ public abstract class Option<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getCurrent(Player p) {
|
public ItemStack getCurrent(Player p) {
|
||||||
String value = options.get(pointer).toString();
|
int amount = Integer.parseInt(options.get(pointer).toString());
|
||||||
return ItemStack.builder(item)
|
return ItemStack.builder(item)
|
||||||
.customName(name.getAssembled(p))
|
.customName(name.getAssembled(p))
|
||||||
.lore(TranslatedComponent.byId("optionCommon#value").setColor(NamedTextColor.GOLD).getAssembled(p)
|
.lore(TranslatedComponent.byId("optionCommon#value").setColor(NamedTextColor.GOLD).getAssembled(p)
|
||||||
.append(Component.text(": ")).append(Component.text(value)))
|
.append(Component.text(": ")).append(Component.text(amount)))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,10 +56,6 @@ public abstract class Option<T> {
|
|||||||
return Integer.parseInt(getAsString());
|
return Integer.parseInt(getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getAsBoolean() {
|
|
||||||
return Objects.equals(getAsString(), "true") || Objects.equals(getAsString(), "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAsString() {
|
public String getAsString() {
|
||||||
return currentValue.toString();
|
return currentValue.toString();
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ import net.minestom.server.item.Material;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BoolOption extends Option<String> {
|
public class BoolOption extends Option<Boolean> {
|
||||||
public BoolOption(String id, Material item, TranslatedComponent name) {
|
public BoolOption(String id, Material item, TranslatedComponent name) {
|
||||||
super(id, item, name, List.of("true", "false"));
|
super(id, item, name, List.of(true, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,6 @@ 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;
|
||||||
|
@ -6,22 +6,31 @@ import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
|||||||
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.util.BatchUtil;
|
||||||
import eu.mhsl.minenet.minigames.util.GeneratorUtils;
|
import eu.mhsl.minenet.minigames.util.GeneratorUtils;
|
||||||
|
import io.github.togar2.pvp.entity.projectile.CustomEntityProjectile;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.coordinate.Vec;
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.entity.*;
|
import net.minestom.server.entity.*;
|
||||||
import net.minestom.server.entity.metadata.other.PrimedTntMeta;
|
import net.minestom.server.entity.metadata.other.PrimedTntMeta;
|
||||||
|
import net.minestom.server.entity.metadata.projectile.ArrowMeta;
|
||||||
import net.minestom.server.event.EventListener;
|
import net.minestom.server.event.EventListener;
|
||||||
import net.minestom.server.event.entity.projectile.ProjectileCollideWithBlockEvent;
|
import net.minestom.server.event.entity.projectile.ProjectileCollideWithBlockEvent;
|
||||||
import net.minestom.server.event.entity.projectile.ProjectileCollideWithEntityEvent;
|
import net.minestom.server.event.entity.projectile.ProjectileCollideWithEntityEvent;
|
||||||
|
import net.minestom.server.event.item.ItemUpdateStateEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerItemAnimationEvent;
|
||||||
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;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.item.enchant.Enchantment;
|
||||||
import net.minestom.server.tag.Tag;
|
import net.minestom.server.tag.Tag;
|
||||||
|
import net.minestom.server.utils.MathUtils;
|
||||||
|
import net.minestom.server.utils.time.TimeUnit;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class BowSpleef extends StatelessGame {
|
public class BowSpleef extends StatelessGame {
|
||||||
@ -32,40 +41,40 @@ public class BowSpleef extends StatelessGame {
|
|||||||
public BowSpleef() {
|
public BowSpleef() {
|
||||||
super(Dimension.OVERWORLD.key, "bowSpleef", new LastWinsScore());
|
super(Dimension.OVERWORLD.key, "bowSpleef", new LastWinsScore());
|
||||||
|
|
||||||
// eventNode().addListener( TODO implement bow mechanism
|
eventNode().addListener(
|
||||||
// EventListener
|
EventListener
|
||||||
// .builder(PlayerItemAnimationEvent.class)
|
.builder(PlayerItemAnimationEvent.class)
|
||||||
// .handler(playerItemAnimationEvent -> playerItemAnimationEvent.getPlayer().setTag(CHARGE_BOW_SINCE, System.currentTimeMillis()))
|
.handler(playerItemAnimationEvent -> playerItemAnimationEvent.getPlayer().setTag(CHARGE_BOW_SINCE, System.currentTimeMillis()))
|
||||||
// .filter(playerItemAnimationEvent -> playerItemAnimationEvent.getItemAnimationType() == PlayerItemAnimationEvent.ItemAnimationType.BOW)
|
.filter(playerItemAnimationEvent -> playerItemAnimationEvent.getItemAnimationType() == PlayerItemAnimationEvent.ItemAnimationType.BOW)
|
||||||
// .build()
|
.build()
|
||||||
// );
|
);
|
||||||
//
|
|
||||||
// eventNode().addListener(
|
eventNode().addListener(
|
||||||
// EventListener
|
EventListener
|
||||||
// .builder(ItemUpdateStateEvent.class)
|
.builder(ItemUpdateStateEvent.class)
|
||||||
// .handler(event -> {
|
.handler(event -> {
|
||||||
// final Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
// final double chargedFor = (System.currentTimeMillis() - player.getTag(CHARGE_BOW_SINCE)) / 1000D;
|
final double chargedFor = (System.currentTimeMillis() - player.getTag(CHARGE_BOW_SINCE)) / 1000D;
|
||||||
// final double power = MathUtils.clamp((chargedFor * chargedFor + 2 * chargedFor) / 2D, 0, 1);
|
final double power = MathUtils.clamp((chargedFor * chargedFor + 2 * chargedFor) / 2D, 0, 1);
|
||||||
//
|
|
||||||
// if (power > 0.2) {
|
if (power > 0.2) {
|
||||||
// final CustomEntityProjectile projectile = new CustomEntityProjectile(player, EntityType.ARROW);
|
final CustomEntityProjectile projectile = new CustomEntityProjectile(player, EntityType.ARROW);
|
||||||
// final ArrowMeta meta = (ArrowMeta) projectile.getEntityMeta();
|
final ArrowMeta meta = (ArrowMeta) projectile.getEntityMeta();
|
||||||
// meta.setCritical(power >= 0.9);
|
meta.setCritical(power >= 0.9);
|
||||||
// projectile.scheduleRemove(Duration.of(100, TimeUnit.SERVER_TICK));
|
projectile.scheduleRemove(Duration.of(100, TimeUnit.SERVER_TICK));
|
||||||
// meta.setOnFire(true);
|
meta.setOnFire(true);
|
||||||
//
|
|
||||||
// final Pos position = player.getPosition().add(0, player.getEyeHeight(), 0);
|
final Pos position = player.getPosition().add(0, player.getEyeHeight(), 0);
|
||||||
// projectile.setInstance(Objects.requireNonNull(player.getInstance()), position);
|
projectile.setInstance(Objects.requireNonNull(player.getInstance()), position);
|
||||||
//
|
|
||||||
// final Vec direction = projectile.getPosition().direction();
|
final Vec direction = projectile.getPosition().direction();
|
||||||
// projectile.shootFrom(position.add(direction).sub(0, 0.2, 0), power * 3, 1.0);
|
projectile.shootFrom(position.add(direction).sub(0, 0.2, 0), power * 3, 1.0);
|
||||||
// projectile.setTag(ARROW_FIRST_HIT, true);
|
projectile.setTag(ARROW_FIRST_HIT, true);
|
||||||
// }
|
}
|
||||||
// })
|
})
|
||||||
// .filter(itemUpdateStateEvent -> itemUpdateStateEvent.getItemStack().material() == Material.BOW)
|
.filter(itemUpdateStateEvent -> itemUpdateStateEvent.getItemStack().material() == Material.BOW)
|
||||||
// .build()
|
.build()
|
||||||
// );
|
);
|
||||||
|
|
||||||
eventNode().addListener(
|
eventNode().addListener(
|
||||||
EventListener
|
EventListener
|
||||||
|
@ -12,12 +12,7 @@ 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("game_BowSpleef#name");
|
return TranslatedComponent.byId("");
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TranslatedComponent description() {
|
|
||||||
return TranslatedComponent.byId("game_BowSpleef#description");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,8 +6,8 @@ import eu.mhsl.minenet.minigames.util.BatchUtil;
|
|||||||
import eu.mhsl.minenet.minigames.instance.Dimension;
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
|
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
|
||||||
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.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 org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -27,13 +27,12 @@ class Deathcube extends StatelessGame {
|
|||||||
this.percentage = percentage;
|
this.percentage = percentage;
|
||||||
this.setGenerator(new CircularPlateTerrainGenerator(radius+10).setPlateHeight(50));
|
this.setGenerator(new CircularPlateTerrainGenerator(radius+10).setPlateHeight(50));
|
||||||
|
|
||||||
if(pvpEnabled == 1) eventNode().addChild(
|
// if(pvpEnabled == 1) eventNode().addChild( // TODO update
|
||||||
CombatFeatures.empty()
|
// PvPConfig.emptyBuilder()
|
||||||
.add(CombatFeatures.VANILLA_ATTACK)
|
// .damage(DamageConfig.LEGACY.fallDamage(false))
|
||||||
.add(CombatFeatures.VANILLA_DAMAGE)
|
// .attack(AttackConfig.DEFAULT.attackCooldown(true))
|
||||||
.add(CombatFeatures.VANILLA_KNOCKBACK)
|
// .build().createNode()
|
||||||
.build().createNode()
|
// );
|
||||||
);
|
|
||||||
System.out.println(radius);
|
System.out.println(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ public class DeathcubeFactory implements GameFactory {
|
|||||||
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 10, 20, 30))
|
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 10, 20, 30))
|
||||||
.addOption(new NumericOption("height", Material.SCAFFOLDING, TranslatedComponent.byId("optionCommon#height"), 10, 30, 50))
|
.addOption(new NumericOption("height", Material.SCAFFOLDING, TranslatedComponent.byId("optionCommon#height"), 10, 30, 50))
|
||||||
.addOption(new NumericOption("percentage", Material.COBWEB, TranslatedComponent.byId("game_Deathcube#optionPercentageBlocks"), 5, 7, 9, 11, 13))
|
.addOption(new NumericOption("percentage", Material.COBWEB, TranslatedComponent.byId("game_Deathcube#optionPercentageBlocks"), 5, 7, 9, 11, 13))
|
||||||
.addOption(new NumericOption("pvpEnabled", Material.STICK, TranslatedComponent.byId("game_Deathcube#optionPvpEnabled"), 0, 1));
|
.addOption(new NumericOption("pvpEnabled", Material.STICK, TranslatedComponent.byId("game_Deathcube#optionPvpEnabled"), 1, 0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ import net.kyori.adventure.text.format.NamedTextColor;
|
|||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.coordinate.Vec;
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.entity.EquipmentSlot;
|
|
||||||
import net.minestom.server.entity.GameMode;
|
import net.minestom.server.entity.GameMode;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.event.player.*;
|
import net.minestom.server.event.player.*;
|
||||||
@ -40,7 +39,6 @@ public class ElytraRace extends StatelessGame {
|
|||||||
private final ValeGenerator vale = new ValeGenerator();
|
private final ValeGenerator vale = new ValeGenerator();
|
||||||
|
|
||||||
private final int gameHeight = 0;
|
private final int gameHeight = 0;
|
||||||
private final int seaLevel = -55;
|
|
||||||
private final int ringSpacing = 100;
|
private final int ringSpacing = 100;
|
||||||
private final int ringCount;
|
private final int ringCount;
|
||||||
|
|
||||||
@ -63,7 +61,7 @@ public class ElytraRace extends StatelessGame {
|
|||||||
this.ringCount = ringCount;
|
this.ringCount = ringCount;
|
||||||
|
|
||||||
setGenerator(vale);
|
setGenerator(vale);
|
||||||
vale.setCalculateSeaLevel(point -> seaLevel);
|
vale.setCalculateSeaLevel(point -> -55);
|
||||||
vale.setXShiftMultiplier(integer -> NumberUtil.map(integer, 50, 500, 0, 1));
|
vale.setXShiftMultiplier(integer -> NumberUtil.map(integer, 50, 500, 0, 1));
|
||||||
vale.addMixIn(new PlaneTerrainGenerator(gameHeight, Block.BARRIER));
|
vale.addMixIn(new PlaneTerrainGenerator(gameHeight, Block.BARRIER));
|
||||||
|
|
||||||
@ -107,7 +105,9 @@ public class ElytraRace extends StatelessGame {
|
|||||||
@Override
|
@Override
|
||||||
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||||
Point spawnpoint = new Pos(vale.getXShiftAtZ(0), -46, 0);
|
Point spawnpoint = new Pos(vale.getXShiftAtZ(0), -46, 0);
|
||||||
GeneratorUtils.iterateArea(spawnpoint.sub(5, 0, 5), spawnpoint.add(5, 0, 5), point -> setBlock(point, BlockPallet.STREET.rnd()));
|
GeneratorUtils.iterateArea(spawnpoint.sub(5, 0, 5), spawnpoint.add(5, 0, 5), point -> {
|
||||||
|
setBlock(point, BlockPallet.STREET.rnd());
|
||||||
|
});
|
||||||
|
|
||||||
generateRing(ringSpacing);
|
generateRing(ringSpacing);
|
||||||
generateRing(ringSpacing * 2);
|
generateRing(ringSpacing * 2);
|
||||||
@ -117,7 +117,7 @@ public class ElytraRace extends StatelessGame {
|
|||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
getPlayers().forEach(player -> {
|
getPlayers().forEach(player -> {
|
||||||
player.getInventory().setEquipment(EquipmentSlot.CHESTPLATE, (byte) 0, ItemStack.of(Material.ELYTRA));
|
player.getInventory().setChestplate(ItemStack.of(Material.ELYTRA));
|
||||||
for(int i = 0; i < 3; i++) {
|
for(int i = 0; i < 3; i++) {
|
||||||
player.getInventory().setItemStack(i, ItemStack.builder(boostMaterial).customName(TranslatedComponent.byId("boost").getAssembled(player)).build());
|
player.getInventory().setItemStack(i, ItemStack.builder(boostMaterial).customName(TranslatedComponent.byId("boost").getAssembled(player)).build());
|
||||||
}
|
}
|
||||||
@ -169,7 +169,6 @@ 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,8 +194,8 @@ public class ElytraRace extends StatelessGame {
|
|||||||
|
|
||||||
Point ringPos = getRingPositionAtZ(zPos);
|
Point ringPos = getRingPositionAtZ(zPos);
|
||||||
GeneratorUtils.iterateArea(
|
GeneratorUtils.iterateArea(
|
||||||
ringPos.sub(100, 0, 0).withY(0),
|
ringPos.sub(100, 0, 0).withY(0), // TODO 0 was before update getDimensionType().getMinY, might not work correctly
|
||||||
ringPos.add(100, 0, 0).withY(seaLevel),
|
ringPos.add(100, 0, 0).withY(gameHeight),
|
||||||
point -> batch.setBlock(point, Block.BARRIER)
|
point -> batch.setBlock(point, Block.BARRIER)
|
||||||
);
|
);
|
||||||
GeneratorUtils.iterateArea(
|
GeneratorUtils.iterateArea(
|
||||||
|
@ -14,12 +14,7 @@ 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("game_ElytraRace#name");
|
return TranslatedComponent.byId("");
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TranslatedComponent description() {
|
|
||||||
return TranslatedComponent.byId("game_ElytraRace#description");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -30,7 +25,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("game_ElytraRace#ringCount"), 5, 10, 20, 30, 40, 50));
|
.addOption(new NumericOption("ringCount", Material.DIAMOND_BLOCK, TranslatedComponent.byId("ringCount"), 5, 10, 20, 30, 40, 50));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
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));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,6 +10,7 @@ import eu.mhsl.minenet.minigames.world.BlockPallet;
|
|||||||
import eu.mhsl.minenet.minigames.world.generator.terrain.SquarePlateTerrainGenerator;
|
import eu.mhsl.minenet.minigames.world.generator.terrain.SquarePlateTerrainGenerator;
|
||||||
import net.kyori.adventure.sound.Sound;
|
import net.kyori.adventure.sound.Sound;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
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;
|
||||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
@ -86,6 +87,7 @@ class Minerun extends StatelessGame {
|
|||||||
|
|
||||||
if(Intersect.withPressurePlate(this, BlockPallet.PRESSURE_PLATES, middle)) { //Player died
|
if(Intersect.withPressurePlate(this, BlockPallet.PRESSURE_PLATES, middle)) { //Player died
|
||||||
p.playSound(Sound.sound(SoundEvent.ENTITY_GENERIC_EXPLODE, Sound.Source.PLAYER, 1f, 1f));
|
p.playSound(Sound.sound(SoundEvent.ENTITY_GENERIC_EXPLODE, Sound.Source.PLAYER, 1f, 1f));
|
||||||
|
p.setPose(Entity.Pose.DYING);
|
||||||
p.teleport(new Pos(p.getPosition().x(), getSpawn().y(), getSpawn().z()));
|
p.teleport(new Pos(p.getPosition().x(), getSpawn().y(), getSpawn().z()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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#optionPercentageMines"), 30, 40, 50, 60, 70));
|
.addOption(new NumericOption("percentage", Material.LIGHT_WEIGHTED_PRESSURE_PLATE, TranslatedComponent.byId("game_Minerun#optionPercentageMiens"), 30, 40, 50, 60, 70));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -78,7 +78,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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("optionCommon#radius"), 10, 20, 30))
|
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("game_Spleef#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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,33 +3,29 @@ 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.config.PvPConfig;
|
||||||
import io.github.togar2.pvp.events.FinalAttackEvent;
|
import io.github.togar2.pvp.events.FinalAttackEvent;
|
||||||
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());
|
||||||
|
|
||||||
eventNode().addChild(
|
// eventNode().addChild( // TODO update
|
||||||
CombatFeatures.empty()
|
// PvPConfig.emptyBuilder()
|
||||||
.add(CombatFeatures.VANILLA_ATTACK)
|
// .damage(DamageConfig.legacyBuilder().fallDamage(false))
|
||||||
.add(CombatFeatures.VANILLA_DAMAGE)
|
// .attack(AttackConfig.legacyBuilder().attackCooldown(true))
|
||||||
.add(CombatFeatures.VANILLA_KNOCKBACK)
|
// .build().createNode()
|
||||||
.build().createNode()
|
// );
|
||||||
);
|
|
||||||
|
|
||||||
eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
|
eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
|
||||||
finalAttackEvent.setBaseDamage(0);
|
finalAttackEvent.setBaseDamage(0);
|
||||||
@ -41,56 +37,21 @@ public class Stickfight extends StatelessGame {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||||
setBlock(0, 50, 0, Block.DIAMOND_BLOCK);
|
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||||
|
for (int z = -10; z <= 10; z++) {
|
||||||
|
batch.setBlock(0, 50, z, Block.SANDSTONE);
|
||||||
}
|
}
|
||||||
|
batch.setBlock(0, 50, 0, Block.GOLD_BLOCK);
|
||||||
|
|
||||||
@Override
|
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
|
||||||
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(!spawnPoints.containsKey(playerMoveEvent.getPlayer())) {
|
if(isBeforeBeginning) playerMoveEvent.setCancelled(true);
|
||||||
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(spawnPoints.get(playerMoveEvent.getPlayer()));
|
playerMoveEvent.getPlayer().teleport(new Pos(0, 51, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.test;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
|
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.event.player.PlayerBlockInteractEvent;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class Test extends StatelessGame {
|
||||||
|
|
||||||
|
int zähler = 0;
|
||||||
|
|
||||||
|
public Test() {
|
||||||
|
super(Dimension.THE_END.key, "test", new FirstWinsScore());
|
||||||
|
eventNode().addListener(PlayerBlockInteractEvent.class, event -> {
|
||||||
|
if (!isBeforeBeginning) {
|
||||||
|
zähler++;
|
||||||
|
}
|
||||||
|
if (zähler >= 10) {
|
||||||
|
getScore().insertResult(event.getPlayer());
|
||||||
|
System.out.println("Sieg");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||||
|
for(int x = 0; x <= 10; x++) {
|
||||||
|
for(int z = 0; z <= 10; z++) {
|
||||||
|
setBlock(x, 0, z, Block.BEDROCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setBlock(3,1,6, Block.BIRCH_BUTTON.withProperty("face", "floor"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pos getSpawn() {
|
||||||
|
return new Pos(5, 3, 5);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.test;
|
||||||
|
|
||||||
|
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.kyori.adventure.text.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class TestFactory implements GameFactory {
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent name() {
|
||||||
|
return TranslatedComponent.byId("test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
|
return new Test().setParent(parent);
|
||||||
|
}
|
||||||
|
}
|
@ -1,160 +0,0 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris;
|
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.TetrisGame;
|
|
||||||
import eu.mhsl.minenet.minigames.instance.Dimension;
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.Tetromino;
|
|
||||||
import eu.mhsl.minenet.minigames.score.PointsWinScore;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
|
||||||
import net.minestom.server.entity.Entity;
|
|
||||||
import net.minestom.server.entity.GameMode;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.minestom.server.event.player.*;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
import net.minestom.server.item.Material;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
class Tetris extends StatelessGame {
|
|
||||||
private final Map<Player, TetrisGame> tetrisGames = new WeakHashMap<>();
|
|
||||||
private final int nextTetrominoesCount;
|
|
||||||
private final boolean isFast;
|
|
||||||
private final boolean hasCombat;
|
|
||||||
private boolean setTimeLimit = false;
|
|
||||||
private final long randomSeed;
|
|
||||||
|
|
||||||
public Tetris(int nextTetrominoesCount, boolean isFast, boolean hasCombat) {
|
|
||||||
super(Dimension.THE_END.key, "Tetris", new PointsWinScore());
|
|
||||||
|
|
||||||
this.eventNode()
|
|
||||||
.addListener(PlayerUseItemEvent.class, this::onPlayerInteract)
|
|
||||||
.addListener(PlayerHandAnimationEvent.class, this::onPlayerAttack)
|
|
||||||
.addListener(PlayerTickEvent.class, this::onPlayerTick);
|
|
||||||
|
|
||||||
this.nextTetrominoesCount = nextTetrominoesCount;
|
|
||||||
this.isFast = isFast;
|
|
||||||
this.hasCombat = hasCombat;
|
|
||||||
|
|
||||||
Random random = new Random();
|
|
||||||
this.randomSeed = random.nextLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
this.getEntities().stream()
|
|
||||||
.filter(entity -> entity.getEntityType().equals(Tetromino.getGhostEntityType()))
|
|
||||||
.forEach(Entity::remove);
|
|
||||||
|
|
||||||
if(this.hasCombat) {
|
|
||||||
this.tetrisGames.values().forEach(tetrisGame -> tetrisGame.updateOtherTetrisGames(this.tetrisGames.values()));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tetrisGames.forEach((player, tetrisGame) -> tetrisGame.start());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
this.tetrisGames.forEach((player, tetrisGame) -> {
|
|
||||||
tetrisGame.loose();
|
|
||||||
this.getScore().insertResult(player, tetrisGame.getScore());
|
|
||||||
tetrisGame.sidebar.removeViewer(player);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPlayerLeave(Player p) {
|
|
||||||
this.tetrisGames.get(p).sidebar.removeViewer(p);
|
|
||||||
this.letPlayerLoose(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPlayerMove(@NotNull PlayerMoveEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
Pos currentPosition = event.getNewPosition();
|
|
||||||
|
|
||||||
TetrisGame tetrisGame = this.tetrisGames.get(player);
|
|
||||||
|
|
||||||
if(tetrisGame == null) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(tetrisGame.lost) 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));
|
|
||||||
player.setSprinting(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onPlayerInteract(@NotNull PlayerUseItemEvent event) {
|
|
||||||
this.tetrisGames.get(event.getPlayer()).pressedButton(TetrisGame.Button.mouseRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onPlayerAttack(@NotNull PlayerHandAnimationEvent event) {
|
|
||||||
this.tetrisGames.get(event.getPlayer()).pressedButton(TetrisGame.Button.mouseLeft);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onPlayerTick(PlayerTickEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
TetrisGame tetrisGame = this.tetrisGames.get(player);
|
|
||||||
if(tetrisGame == null) return;
|
|
||||||
if(tetrisGame.lost && player.getGameMode() != GameMode.SPECTATOR) {
|
|
||||||
this.letPlayerLoose(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void letPlayerLoose(Player player) {
|
|
||||||
TetrisGame tetrisGame = this.tetrisGames.get(player);
|
|
||||||
player.setGameMode(GameMode.SPECTATOR);
|
|
||||||
player.setInvisible(true);
|
|
||||||
this.getScore().insertResult(player, tetrisGame.getScore());
|
|
||||||
|
|
||||||
boolean allGamesLost = this.tetrisGames.values().stream()
|
|
||||||
.filter(game -> !game.lost)
|
|
||||||
.toList()
|
|
||||||
.isEmpty();
|
|
||||||
if(!this.setTimeLimit && !allGamesLost) {
|
|
||||||
this.setTimeLimit(90);
|
|
||||||
this.setTimeLimit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean onPlayerJoin(Player p) {
|
|
||||||
p.getInventory().setItemStack(0, ItemStack.builder(Material.BIRCH_BUTTON).customName(Component.text("Controller")).build());
|
|
||||||
p.setSprinting(false);
|
|
||||||
|
|
||||||
if(this.tetrisGames.get(p) == null) {
|
|
||||||
this.tetrisGames.put(p, new TetrisGame(
|
|
||||||
this,
|
|
||||||
this.getSpawn().sub(6, 8, 15).add(this.tetrisGames.size()*30, 0, 0),
|
|
||||||
Tetromino.Shape.J,
|
|
||||||
this.nextTetrominoesCount,
|
|
||||||
this.isFast,
|
|
||||||
this.hasCombat,
|
|
||||||
this.randomSeed
|
|
||||||
));
|
|
||||||
this.tetrisGames.get(p).generate();
|
|
||||||
this.tetrisGames.values().forEach(tetrisGame -> tetrisGame.updateOtherTetrisGames(this.tetrisGames.values()));
|
|
||||||
}
|
|
||||||
|
|
||||||
TetrisGame tetrisGame = this.tetrisGames.get(p);
|
|
||||||
|
|
||||||
p.teleport(tetrisGame.getPlayerSpawnPosition());
|
|
||||||
tetrisGame.sidebar.addViewer(p);
|
|
||||||
|
|
||||||
return super.onPlayerJoin(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Pos getSpawn() {
|
|
||||||
return new Pos(0, 30, 15).withView(180, 0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris;
|
|
||||||
|
|
||||||
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.game.stateless.config.ConfigManager;
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.BoolOption;
|
|
||||||
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 TetrisFactory implements GameFactory {
|
|
||||||
@Override
|
|
||||||
public TranslatedComponent name() {
|
|
||||||
return TranslatedComponent.byId("game_Tetris#name");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TranslatedComponent description() {
|
|
||||||
return TranslatedComponent.byId("game_Tetris#description");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConfigManager configuration() {
|
|
||||||
return new ConfigManager()
|
|
||||||
.addOption(new NumericOption("nextTetrominoesCount", Material.LADDER, TranslatedComponent.byId("game_Tetris#nextTetrominoesCount"), 3, 4, 5, 1, 2))
|
|
||||||
.addOption(new BoolOption("isFast", Material.MINECART, TranslatedComponent.byId("game_Tetris#isFast")))
|
|
||||||
.addOption(new BoolOption("hasCombat", Material.DIAMOND_SWORD, TranslatedComponent.byId("game_Tetris#hasCombat")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
|
|
||||||
return new Tetris(configuration.get("nextTetrominoesCount").getAsInt(), configuration.get("isFast").getAsBoolean(), configuration.get("hasCombat").getAsBoolean()).setParent(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material symbol() {
|
|
||||||
return Material.PURPLE_WOOL;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,191 +0,0 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
|
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
|
||||||
import eu.mhsl.minenet.minigames.util.BatchUtil;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
|
||||||
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
|
||||||
import net.minestom.server.instance.block.Block;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class Playfield {
|
|
||||||
private final Pos lowerLeftCorner;
|
|
||||||
private final StatelessGame instance;
|
|
||||||
private final static int height = 22;
|
|
||||||
private final static Block scoreBlock = Block.STONE;
|
|
||||||
private final int nextTetrominoesCount;
|
|
||||||
private final Random random;
|
|
||||||
|
|
||||||
public Playfield(Pos lowerLeftCorner, StatelessGame instance, int nextTetrominoesCount) {
|
|
||||||
this.nextTetrominoesCount = nextTetrominoesCount;
|
|
||||||
this.lowerLeftCorner = lowerLeftCorner;
|
|
||||||
this.instance = instance;
|
|
||||||
this.random = new Random();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pos getPlayerSpawnPosition() {
|
|
||||||
return this.lowerLeftCorner.add(6, 9, 20).withView(180, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pos getTetrominoSpawnPosition() {
|
|
||||||
return this.lowerLeftCorner.add(5, 21, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pos getHoldPosition() {
|
|
||||||
return this.lowerLeftCorner.add(-4, 18, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pos getNextPosition() {
|
|
||||||
return this.lowerLeftCorner.add(15, 18, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pos getScorePosition() {
|
|
||||||
return this.lowerLeftCorner.add(-5, height+3, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generate() {
|
|
||||||
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
|
||||||
|
|
||||||
// actual playfield:
|
|
||||||
for(int x=0; x<12; x++) {
|
|
||||||
for(int y = 0; y< height; y++) {
|
|
||||||
batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.GLASS);
|
|
||||||
batch.setBlock(this.lowerLeftCorner.add(x, y, -1), Block.BLACK_CONCRETE);
|
|
||||||
|
|
||||||
if(x==0 || x==11 || y==0) {
|
|
||||||
batch.setBlock(this.lowerLeftCorner.add(x, y, 1), Block.GRAY_CONCRETE);
|
|
||||||
batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.GRAY_CONCRETE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// hold position:
|
|
||||||
for(int x = 0; x < 4; x++) {
|
|
||||||
for(int y = 0; y < 4; y++) {
|
|
||||||
batch.setBlock(this.getHoldPosition().add(x-1, y-1, -1), Block.QUARTZ_BLOCK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// next positions:
|
|
||||||
for(int x = 0; x < 4; x++) {
|
|
||||||
for(int y = -4*this.nextTetrominoesCount+4; y < 4; y++) {
|
|
||||||
batch.setBlock(this.getNextPosition().add(x-1, y-1, -1), Block.QUARTZ_BLOCK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
batch.setBlock(this.getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE);
|
|
||||||
batch.setBlock(this.getPlayerSpawnPosition().sub(1, 1, 0), Block.STONE);
|
|
||||||
batch.setBlock(this.getPlayerSpawnPosition().sub(1, 1, 1), Block.STONE);
|
|
||||||
batch.setBlock(this.getPlayerSpawnPosition().sub(0, 1, 1), Block.STONE);
|
|
||||||
|
|
||||||
BatchUtil.loadAndApplyBatch(batch, this.instance, () -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
public int removeFullLines() {
|
|
||||||
int removedLinesCounter = 0;
|
|
||||||
for(int y = 1; y< height; y++) {
|
|
||||||
boolean isFullLine = true;
|
|
||||||
for(int x=1; x<11; x++) {
|
|
||||||
if(this.instance.getBlock(this.lowerLeftCorner.add(x, y, 1)) == Block.AIR) isFullLine = false;
|
|
||||||
}
|
|
||||||
if(isFullLine) {
|
|
||||||
this.removeFullLine(y);
|
|
||||||
removedLinesCounter += 1;
|
|
||||||
y -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return removedLinesCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLines(int lines) {
|
|
||||||
int xPosMissing = this.random.nextInt(1, 10);
|
|
||||||
|
|
||||||
for (int i = 0; i < lines; i++) {
|
|
||||||
this.moveAllLinesUp();
|
|
||||||
for (int x = 1; x < 11; x++) {
|
|
||||||
if(x != xPosMissing) {
|
|
||||||
this.instance.setBlock(this.lowerLeftCorner.add(x, 1, 1), Block.LIGHT_GRAY_CONCRETE);
|
|
||||||
} else {
|
|
||||||
this.instance.setBlock(this.lowerLeftCorner.add(x, 1, 1), Block.AIR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateAttackingLines(int attackingLines) {
|
|
||||||
for (int y = 0; y < height + 5; y++) {
|
|
||||||
if(attackingLines > 0) {
|
|
||||||
this.instance.setBlock(this.lowerLeftCorner.add(12, y, 1), Block.REDSTONE_BLOCK);
|
|
||||||
attackingLines -= 1;
|
|
||||||
} else {
|
|
||||||
this.instance.setBlock(this.lowerLeftCorner.add(12, y, 1), Block.AIR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateScore(int score) {
|
|
||||||
this.removeDigits();
|
|
||||||
String scoreString = String.valueOf(score);
|
|
||||||
char[] characters = scoreString.toCharArray();
|
|
||||||
ArrayUtils.reverse(characters);
|
|
||||||
for(int i = 6; i > 0; i--) {
|
|
||||||
char digit;
|
|
||||||
if(i <= characters.length) {
|
|
||||||
digit = characters[i-1];
|
|
||||||
} else {
|
|
||||||
digit = '0';
|
|
||||||
}
|
|
||||||
this.displayDigit(digit, 6-i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void displayDigit(char digit, int positionFromLeft) {
|
|
||||||
int[][] digitArray;
|
|
||||||
switch (digit) {
|
|
||||||
case '1' -> digitArray = new int[][]{{0,0,1},{0,1,1},{0,0,1},{0,0,1},{0,0,1}};
|
|
||||||
case '2' -> digitArray = new int[][]{{1,1,1},{0,0,1},{1,1,1},{1,0,0},{1,1,1}};
|
|
||||||
case '3' -> digitArray = new int[][]{{1,1,1},{0,0,1},{0,1,1},{0,0,1},{1,1,1}};
|
|
||||||
case '4' -> digitArray = new int[][]{{1,0,1},{1,0,1},{1,1,1},{0,0,1},{0,0,1}};
|
|
||||||
case '5' -> digitArray = new int[][]{{1,1,1},{1,0,0},{1,1,1},{0,0,1},{1,1,1}};
|
|
||||||
case '6' -> digitArray = new int[][]{{1,1,1},{1,0,0},{1,1,1},{1,0,1},{1,1,1}};
|
|
||||||
case '7' -> digitArray = new int[][]{{1,1,1},{0,0,1},{0,1,0},{0,1,0},{0,1,0}};
|
|
||||||
case '8' -> digitArray = new int[][]{{1,1,1},{1,0,1},{1,1,1},{1,0,1},{1,1,1}};
|
|
||||||
case '9' -> digitArray = new int[][]{{1,1,1},{1,0,1},{1,1,1},{0,0,1},{1,1,1}};
|
|
||||||
default -> digitArray = new int[][]{{1,1,1},{1,0,1},{1,0,1},{1,0,1},{1,1,1}};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int x = 0; x < 3; x++) {
|
|
||||||
for (int y = 0; y < 5; y++) {
|
|
||||||
if(digitArray[4-y][x] == 1) this.instance.setBlock(this.getScorePosition().add(positionFromLeft*4+x, y, 0), scoreBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeDigits() {
|
|
||||||
for (int x = 0; x < 4 * 6; x++) {
|
|
||||||
for (int y = 0; y < 5; y++) {
|
|
||||||
this.instance.setBlock(this.getScorePosition().add(x, y, 0), Block.AIR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moveAllLinesUp() {
|
|
||||||
for (int y = height + 3; y > 1; y--) {
|
|
||||||
for (int x = 1; x < 11; x++) {
|
|
||||||
Block blockBeneath = this.instance.getBlock(this.lowerLeftCorner.add(x, y - 1, 1));
|
|
||||||
this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockBeneath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeFullLine(int positionY) {
|
|
||||||
for(int y = positionY; y< height; y++) {
|
|
||||||
for(int x=1; x<11; x++) {
|
|
||||||
Block blockAbove = this.instance.getBlock(this.lowerLeftCorner.add(x, y+1, 1));
|
|
||||||
this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockAbove);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,318 +0,0 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
|
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
|
||||||
import net.minestom.server.scoreboard.Sidebar;
|
|
||||||
import net.minestom.server.timer.Scheduler;
|
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class TetrisGame {
|
|
||||||
private final StatelessGame instance;
|
|
||||||
private final Playfield playfield;
|
|
||||||
private final boolean isFast;
|
|
||||||
private int level = 1;
|
|
||||||
private int lines = 0;
|
|
||||||
private int score = 0;
|
|
||||||
private int combo = 0;
|
|
||||||
private int attackingLines = 0;
|
|
||||||
public boolean lost = false;
|
|
||||||
public boolean paused = true;
|
|
||||||
private final boolean hasCombat;
|
|
||||||
public Tetromino currentTetromino;
|
|
||||||
private final List<Tetromino> nextTetrominoes = new ArrayList<>();
|
|
||||||
private Tetromino holdTetromino;
|
|
||||||
private final List<Tetromino> tetrominoBag = new ArrayList<>();
|
|
||||||
private boolean holdPossible = true;
|
|
||||||
private final Pos nextPosition;
|
|
||||||
private final Pos holdPosition;
|
|
||||||
private final Pos tetrominoSpawnPosition;
|
|
||||||
public Sidebar sidebar = new Sidebar(Component.text("Info:"));
|
|
||||||
private final Map<Button, Long> lastPresses = new HashMap<>();
|
|
||||||
private final List<TetrisGame> otherTetrisGames = new ArrayList<>();
|
|
||||||
private final Random random;
|
|
||||||
|
|
||||||
public enum Button {
|
|
||||||
W,
|
|
||||||
A,
|
|
||||||
S,
|
|
||||||
D,
|
|
||||||
mouseLeft,
|
|
||||||
mouseRight,
|
|
||||||
space
|
|
||||||
}
|
|
||||||
|
|
||||||
public TetrisGame(StatelessGame instance, Pos lowerLeftCorner, Tetromino.Shape startTetrominoShape, int nextTetrominoesCount, boolean isfast, boolean hasCombat, long randomSeed) {
|
|
||||||
this.isFast = isfast;
|
|
||||||
this.hasCombat = hasCombat;
|
|
||||||
this.instance = instance;
|
|
||||||
this.playfield = new Playfield(lowerLeftCorner, this.instance, nextTetrominoesCount);
|
|
||||||
this.random = new Random(randomSeed);
|
|
||||||
|
|
||||||
this.holdPosition = this.playfield.getHoldPosition();
|
|
||||||
this.nextPosition = this.playfield.getNextPosition();
|
|
||||||
this.tetrominoSpawnPosition = this.playfield.getTetrominoSpawnPosition();
|
|
||||||
this.buildSidebar();
|
|
||||||
|
|
||||||
this.currentTetromino = new Tetromino(this.instance, startTetrominoShape);
|
|
||||||
for (int i = 0; i < nextTetrominoesCount; i++) {
|
|
||||||
this.updateNextTetrominoes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pressedButton(Button button) {
|
|
||||||
final int standardButtonDelay = 100;
|
|
||||||
final int buttonDebounce = 70;
|
|
||||||
|
|
||||||
if(this.lastPresses.getOrDefault(button, 0L) >= System.currentTimeMillis()-standardButtonDelay) return;
|
|
||||||
|
|
||||||
this.lastPresses.put(button, System.currentTimeMillis());
|
|
||||||
if(button == Button.W) this.lastPresses.put(button, System.currentTimeMillis()+buttonDebounce);
|
|
||||||
if(button == Button.S) this.lastPresses.put(button, System.currentTimeMillis()-buttonDebounce);
|
|
||||||
|
|
||||||
if(this.lost || this.paused) return;
|
|
||||||
|
|
||||||
switch (button) {
|
|
||||||
case A -> this.currentTetromino.moveLeft();
|
|
||||||
case S -> this.moveDown();
|
|
||||||
case D -> this.currentTetromino.moveRight();
|
|
||||||
case W -> this.hardDrop();
|
|
||||||
case mouseLeft -> this.currentTetromino.rotate(false);
|
|
||||||
case mouseRight -> this.currentTetromino.rotate(true);
|
|
||||||
case space -> this.switchHold();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pos getPlayerSpawnPosition() {
|
|
||||||
return this.playfield.getPlayerSpawnPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
|
||||||
this.paused = false;
|
|
||||||
Scheduler scheduler = MinecraftServer.getSchedulerManager();
|
|
||||||
scheduler.submitTask(() -> {
|
|
||||||
if(this.lost) return TaskSchedule.stop();
|
|
||||||
int standardTickDelay = 40;
|
|
||||||
if(this.isFast) standardTickDelay = 20;
|
|
||||||
|
|
||||||
TaskSchedule nextTick = TaskSchedule.tick(Math.round((float) standardTickDelay /this.level));
|
|
||||||
if(this.paused) return nextTick;
|
|
||||||
this.tick();
|
|
||||||
return nextTick;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.updateInfo();
|
|
||||||
this.nextTetrominoes.forEach(tetromino -> {
|
|
||||||
double xChange = -tetromino.getXChange();
|
|
||||||
tetromino.setPosition(this.nextPosition.sub(xChange, 4*this.nextTetrominoes.indexOf(tetromino), 0));
|
|
||||||
tetromino.drawAsEntities();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generate() {
|
|
||||||
this.playfield.generate();
|
|
||||||
|
|
||||||
this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
|
|
||||||
this.currentTetromino.draw(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tick() {
|
|
||||||
if(this.lost || this.paused) return;
|
|
||||||
if(!this.currentTetromino.moveDown()) {
|
|
||||||
this.setActiveTetrominoDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getScore() {
|
|
||||||
return this.score;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateOtherTetrisGames(Collection<TetrisGame> tetrisGames) {
|
|
||||||
List<TetrisGame> games = new ArrayList<>(tetrisGames);
|
|
||||||
games.remove(this);
|
|
||||||
games.removeIf(tetrisGame -> tetrisGame.lost);
|
|
||||||
this.otherTetrisGames.clear();
|
|
||||||
this.otherTetrisGames.addAll(games);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getAttacked(int lines) {
|
|
||||||
if(this.hasCombat && !this.lost) {
|
|
||||||
this.attackingLines += lines;
|
|
||||||
this.playfield.updateAttackingLines(this.attackingLines);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loose() {
|
|
||||||
this.lost = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private boolean moveDown() {
|
|
||||||
if(!this.currentTetromino.moveDown()) {
|
|
||||||
this.setActiveTetrominoDown();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.score += 1;
|
|
||||||
this.updateInfo();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hardDrop() {
|
|
||||||
if(!this.currentTetromino.moveDown()) {
|
|
||||||
this.setActiveTetrominoDown();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.score += 2;
|
|
||||||
this.updateInfo();
|
|
||||||
while(this.currentTetromino.moveDown()) {
|
|
||||||
this.score += 2;
|
|
||||||
this.updateInfo();
|
|
||||||
}
|
|
||||||
this.setActiveTetrominoDown();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean switchHold() {
|
|
||||||
if(!this.holdPossible) return false;
|
|
||||||
|
|
||||||
Tetromino newCurrentTetromino;
|
|
||||||
if(this.holdTetromino == null) {
|
|
||||||
newCurrentTetromino = this.nextTetrominoes.removeFirst();
|
|
||||||
newCurrentTetromino.remove();
|
|
||||||
this.updateNextTetrominoes();
|
|
||||||
} else {
|
|
||||||
newCurrentTetromino = this.holdTetromino;
|
|
||||||
this.holdTetromino.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.currentTetromino.remove();
|
|
||||||
this.holdTetromino = new Tetromino(this.instance, this.currentTetromino.getShape());
|
|
||||||
this.currentTetromino = newCurrentTetromino;
|
|
||||||
|
|
||||||
this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
|
|
||||||
this.currentTetromino.draw();
|
|
||||||
if(!this.currentTetromino.moveDown()) this.loose();
|
|
||||||
|
|
||||||
double xChange = this.holdTetromino.getXChange();
|
|
||||||
this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0));
|
|
||||||
this.holdTetromino.drawAsEntities();
|
|
||||||
this.holdPossible = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void updateNextTetrominoes() {
|
|
||||||
if(this.tetrominoBag.isEmpty()) {
|
|
||||||
for(Tetromino.Shape shape : Tetromino.Shape.values()) {
|
|
||||||
this.tetrominoBag.add(new Tetromino(this.instance, shape));
|
|
||||||
}
|
|
||||||
Collections.shuffle(this.tetrominoBag, this.random);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.nextTetrominoes.isEmpty()) this.nextTetrominoes.forEach(Tetromino::remove);
|
|
||||||
Tetromino newTetromino = this.tetrominoBag.removeFirst();
|
|
||||||
this.nextTetrominoes.add(newTetromino);
|
|
||||||
this.nextTetrominoes.forEach(tetromino -> {
|
|
||||||
double xChange = -tetromino.getXChange();
|
|
||||||
tetromino.setPosition(this.nextPosition.sub(xChange, 4*this.nextTetrominoes.indexOf(tetromino), 0));
|
|
||||||
tetromino.drawAsEntities();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildSidebar() {
|
|
||||||
this.sidebar.createLine(new Sidebar.ScoreboardLine(
|
|
||||||
"0",
|
|
||||||
Component.text("Score: "),
|
|
||||||
0
|
|
||||||
));
|
|
||||||
this.sidebar.createLine(new Sidebar.ScoreboardLine(
|
|
||||||
"1",
|
|
||||||
Component.text("Lines: "),
|
|
||||||
0
|
|
||||||
));
|
|
||||||
this.sidebar.createLine(new Sidebar.ScoreboardLine(
|
|
||||||
"2",
|
|
||||||
Component.text("Level: "),
|
|
||||||
1
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateInfo() {
|
|
||||||
this.playfield.updateScore(this.score);
|
|
||||||
this.sidebar.updateLineScore("0", this.score);
|
|
||||||
this.sidebar.updateLineScore("1", this.lines);
|
|
||||||
this.sidebar.updateLineScore("2", this.level);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setActiveTetrominoDown() {
|
|
||||||
this.currentTetromino.removeOwnEntities();
|
|
||||||
this.currentTetromino = this.nextTetrominoes.removeFirst();
|
|
||||||
this.currentTetromino.remove();
|
|
||||||
this.updateNextTetrominoes();
|
|
||||||
|
|
||||||
int removedLines = this.playfield.removeFullLines();
|
|
||||||
int combatLines = 0;
|
|
||||||
this.combo += 1;
|
|
||||||
switch (removedLines) {
|
|
||||||
case 0 -> this.combo = 0;
|
|
||||||
case 1 -> {
|
|
||||||
this.lines += 1;
|
|
||||||
this.score += 40 * this.level;
|
|
||||||
}
|
|
||||||
case 2 -> {
|
|
||||||
combatLines = 1;
|
|
||||||
this.lines += 2;
|
|
||||||
this.score += 100 * this.level;
|
|
||||||
}
|
|
||||||
case 3 -> {
|
|
||||||
combatLines = 2;
|
|
||||||
this.lines += 3;
|
|
||||||
this.score += 300 * this.level;
|
|
||||||
}
|
|
||||||
case 4 -> {
|
|
||||||
combatLines = 4;
|
|
||||||
this.lines += 4;
|
|
||||||
this.score += 1200 * this.level;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.score += 50 * this.combo * this.level;
|
|
||||||
if(this.combo >= 2) {
|
|
||||||
combatLines += (int) Math.floor((double) this.combo /2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.hasCombat && this.attackingLines > 0) {
|
|
||||||
if(combatLines > 0 && this.attackingLines >= combatLines) {
|
|
||||||
this.attackingLines -= combatLines;
|
|
||||||
combatLines = 0;
|
|
||||||
} else if(combatLines > 0) {
|
|
||||||
combatLines -= this.attackingLines;
|
|
||||||
this.attackingLines = 0;
|
|
||||||
} else {
|
|
||||||
this.playfield.addLines(this.attackingLines);
|
|
||||||
this.attackingLines = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.playfield.updateAttackingLines(this.attackingLines);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.hasCombat && !this.otherTetrisGames.isEmpty()) {
|
|
||||||
Collections.shuffle(this.otherTetrisGames);
|
|
||||||
this.otherTetrisGames.getFirst().getAttacked(combatLines);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.level = (int) Math.floor((double) this.lines / 10) + 1;
|
|
||||||
this.holdPossible = true;
|
|
||||||
|
|
||||||
this.updateInfo();
|
|
||||||
|
|
||||||
this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
|
|
||||||
this.currentTetromino.draw();
|
|
||||||
if(!this.currentTetromino.moveDown()) {
|
|
||||||
this.loose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,246 +0,0 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
|
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
|
||||||
import net.minestom.server.entity.Entity;
|
|
||||||
import net.minestom.server.entity.EntityType;
|
|
||||||
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
|
||||||
import net.minestom.server.instance.block.Block;
|
|
||||||
import net.minestom.server.tag.Tag;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class Tetromino {
|
|
||||||
private final Shape shape;
|
|
||||||
private final StatelessGame instance;
|
|
||||||
private Pos position;
|
|
||||||
private int[][] shapeArray;
|
|
||||||
private final static EntityType ghostEntityType = EntityType.FALLING_BLOCK;
|
|
||||||
private final UUID uuid;
|
|
||||||
private final static Tag<String> uuidTag = Tag.String("uuid");
|
|
||||||
|
|
||||||
public enum Shape {
|
|
||||||
I,
|
|
||||||
J,
|
|
||||||
L,
|
|
||||||
O,
|
|
||||||
S,
|
|
||||||
T,
|
|
||||||
Z
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tetromino(StatelessGame instance, Shape shape) {
|
|
||||||
this.instance = instance;
|
|
||||||
this.shape = shape;
|
|
||||||
this.uuid = UUID.randomUUID();
|
|
||||||
|
|
||||||
switch (this.shape) {
|
|
||||||
case I -> this.shapeArray = new int[][]{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}};
|
|
||||||
case J -> this.shapeArray = new int[][]{{1,0,0}, {1,1,1}, {0,0,0}};
|
|
||||||
case L -> this.shapeArray = new int[][]{{0,0,1}, {1,1,1}, {0,0,0}};
|
|
||||||
case O -> this.shapeArray = new int[][]{{1,1}, {1,1}};
|
|
||||||
case S -> this.shapeArray = new int[][]{{0,1,1}, {1,1,0}, {0,0,0}};
|
|
||||||
case T -> this.shapeArray = new int[][]{{0,1,0}, {1,1,1}, {0,0,0}};
|
|
||||||
case Z -> this.shapeArray = new int[][]{{1,1,0}, {0,1,1}, {0,0,0}};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityType getGhostEntityType() {
|
|
||||||
return ghostEntityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPosition(Pos newPosition) {
|
|
||||||
this.position = newPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean rotate(boolean clockwise) {
|
|
||||||
int[][] newShapeArray = this.getTurnedShapeArray(clockwise);
|
|
||||||
return this.checkCollisionAndMove(this.position, newShapeArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean moveDown() {
|
|
||||||
Pos newPosition = this.position.sub(0, 1, 0);
|
|
||||||
return this.checkCollisionAndMove(newPosition, this.shapeArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean moveLeft() {
|
|
||||||
Pos newPosition = this.position.sub(1, 0, 0);
|
|
||||||
return this.checkCollisionAndMove(newPosition, this.shapeArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean moveRight() {
|
|
||||||
Pos newPosition = this.position.add(1, 0, 0);
|
|
||||||
return this.checkCollisionAndMove(newPosition, this.shapeArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw() {
|
|
||||||
this.draw(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(boolean withGhost) {
|
|
||||||
if(withGhost) {
|
|
||||||
Pos ghostPos = this.position;
|
|
||||||
while (!this.checkCollision(ghostPos.sub(0, 1, 0), this.shapeArray)) {
|
|
||||||
ghostPos = ghostPos.sub(0, 1, 0);
|
|
||||||
}
|
|
||||||
Pos positionChange = this.position.sub(ghostPos);
|
|
||||||
this.getBlockPositions().forEach(pos -> {
|
|
||||||
Entity ghostBlock = new Entity(ghostEntityType);
|
|
||||||
((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getGhostBlock());
|
|
||||||
ghostBlock.setNoGravity(true);
|
|
||||||
ghostBlock.setGlowing(true);
|
|
||||||
ghostBlock.setTag(uuidTag, this.uuid.toString());
|
|
||||||
ghostBlock.setInstance(this.instance, pos.sub(positionChange).add(0.5, 0, 0.5));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getBlockPositions().forEach(pos -> this.instance.setBlock(pos, this.getColoredBlock()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawAsEntities() {
|
|
||||||
this.getBlockPositions().forEach(pos -> {
|
|
||||||
Entity ghostBlock = new Entity(ghostEntityType);
|
|
||||||
((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getColoredBlock());
|
|
||||||
ghostBlock.setNoGravity(true);
|
|
||||||
ghostBlock.setTag(uuidTag, this.uuid.toString());
|
|
||||||
ghostBlock.setInstance(this.instance, pos.add(0.5, 0, 0.5));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove() {
|
|
||||||
this.removeOwnEntities();
|
|
||||||
this.getBlockPositions().forEach(pos -> this.instance.setBlock(pos, Block.AIR));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Block getColoredBlock() {
|
|
||||||
Block returnBlock;
|
|
||||||
switch (this.shape) {
|
|
||||||
case I -> returnBlock = Block.LIGHT_BLUE_CONCRETE;
|
|
||||||
case J -> returnBlock = Block.BLUE_CONCRETE;
|
|
||||||
case L -> returnBlock = Block.ORANGE_CONCRETE;
|
|
||||||
case O -> returnBlock = Block.YELLOW_CONCRETE;
|
|
||||||
case S -> returnBlock = Block.GREEN_CONCRETE;
|
|
||||||
case T -> returnBlock = Block.PURPLE_CONCRETE;
|
|
||||||
case Z -> returnBlock = Block.RED_CONCRETE;
|
|
||||||
default -> returnBlock = Block.WHITE_CONCRETE;
|
|
||||||
}
|
|
||||||
return returnBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeOwnEntities() {
|
|
||||||
this.instance.getEntities().stream()
|
|
||||||
.filter(entity -> {
|
|
||||||
String tagValue = entity.getTag(uuidTag);
|
|
||||||
if(tagValue == null) return false;
|
|
||||||
return entity.getTag(uuidTag).equals(this.uuid.toString());
|
|
||||||
})
|
|
||||||
.forEach(Entity::remove);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getXChange() {
|
|
||||||
switch (this.shape) {
|
|
||||||
case O, I -> {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case null, default -> {
|
|
||||||
return 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Shape getShape() {
|
|
||||||
return this.shape;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Block getGhostBlock() {
|
|
||||||
Block returnBlock;
|
|
||||||
switch (this.shape) {
|
|
||||||
case I -> returnBlock = Block.LIGHT_BLUE_STAINED_GLASS;
|
|
||||||
case J -> returnBlock = Block.BLUE_STAINED_GLASS;
|
|
||||||
case L -> returnBlock = Block.ORANGE_STAINED_GLASS;
|
|
||||||
case O -> returnBlock = Block.YELLOW_STAINED_GLASS;
|
|
||||||
case S -> returnBlock = Block.GREEN_STAINED_GLASS;
|
|
||||||
case T -> returnBlock = Block.PURPLE_STAINED_GLASS;
|
|
||||||
case Z -> returnBlock = Block.RED_STAINED_GLASS;
|
|
||||||
default -> returnBlock = Block.WHITE_STAINED_GLASS;
|
|
||||||
}
|
|
||||||
return returnBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int[][] getTurnedShapeArray(boolean clockwise) {
|
|
||||||
int iterations = 1;
|
|
||||||
if(!clockwise) iterations = 3;
|
|
||||||
|
|
||||||
int arrayLength = this.shapeArray.length;
|
|
||||||
int[][] startArray = Arrays.stream(this.shapeArray).map(int[]::clone).toArray(int[][]::new);
|
|
||||||
int[][] returnArray = new int[arrayLength][arrayLength];
|
|
||||||
|
|
||||||
for(int k=0; k<iterations; k++) {
|
|
||||||
for(int i=0; i<arrayLength; i++) {
|
|
||||||
for(int j=0; j<arrayLength; j++) {
|
|
||||||
returnArray[i][arrayLength-1-j] = startArray[j][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startArray = Arrays.stream(returnArray).map(int[]::clone).toArray(int[][]::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isPartOfTetromino(Pos position) {
|
|
||||||
return this.getBlockPositions().stream()
|
|
||||||
.anyMatch(pos -> pos.equals(position));
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Pos> getBlockPositions() {
|
|
||||||
return this.getBlockPositions(this.position, this.shapeArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Pos> getBlockPositions(Pos position, int[][] shapeArray) {
|
|
||||||
List<Pos> returnList = new ArrayList<>();
|
|
||||||
if(position == null) return returnList;
|
|
||||||
|
|
||||||
int arrayLength = shapeArray.length;
|
|
||||||
|
|
||||||
for(int x=0; x<arrayLength; x++) {
|
|
||||||
for(int y=0; y<arrayLength; y++) {
|
|
||||||
if(shapeArray[arrayLength-1-y][x] == 1) {
|
|
||||||
switch (this.shape) {
|
|
||||||
case I -> returnList.add(position.add(x-1, y-2, 0));
|
|
||||||
case O -> returnList.add(position.add(x, y, 0));
|
|
||||||
default -> returnList.add(position.add(x-1, y-1, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkCollision(Pos newPosition, int[][] newShapeArray) {
|
|
||||||
List<Pos> newBlockPositions = this.getBlockPositions(newPosition, newShapeArray);
|
|
||||||
|
|
||||||
for(Pos pos : newBlockPositions) {
|
|
||||||
if(this.isPartOfTetromino(pos)) continue;
|
|
||||||
if(this.instance.getBlock(pos) == this.getGhostBlock()) continue;
|
|
||||||
if(this.instance.getBlock(pos) != Block.AIR) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkCollisionAndMove(Pos newPosition, int[][] newShapeArray) {
|
|
||||||
if(!this.checkCollision(newPosition, newShapeArray)) {
|
|
||||||
this.remove();
|
|
||||||
this.shapeArray = Arrays.stream(newShapeArray).map(int[]::clone).toArray(int[][]::new);
|
|
||||||
this.setPosition(newPosition);
|
|
||||||
this.draw();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,7 +7,10 @@ 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;
|
||||||
@ -48,13 +51,7 @@ 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());
|
||||||
}
|
}
|
||||||
@ -70,10 +67,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,7 @@ 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
|
||||||
@ -30,8 +25,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("optionCommon#radius"), 20, 30, 50, 60))
|
.addOption(new NumericOption("radius", Material.STICK, TranslatedComponent.byId("game_tntRun#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
|
||||||
|
@ -3,74 +3,23 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense;
|
|||||||
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.instance.game.stateless.types.towerdefense.generator.MazeGenerator;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.generator.MazeGenerator;
|
||||||
import eu.mhsl.minenet.minigames.score.LastWinsScore;
|
import eu.mhsl.minenet.minigames.score.NoScore;
|
||||||
import net.minestom.server.coordinate.Pos;
|
|
||||||
import net.minestom.server.entity.EntityType;
|
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class Towerdefense extends StatelessGame {
|
public class Towerdefense extends StatelessGame {
|
||||||
private final Random random = new Random();
|
|
||||||
private final AbsoluteBlockBatch mazeBatch = new AbsoluteBlockBatch();
|
|
||||||
private final List<Pos> mazePath = new ArrayList<>();
|
|
||||||
private List<TowerdefenseRoom> instances = new ArrayList<>();
|
|
||||||
|
|
||||||
public Towerdefense() {
|
public Towerdefense() {
|
||||||
super(Dimension.NETHER.key, "Towerdefense", new LastWinsScore());
|
super(Dimension.NETHER.key, "Towerdefense", new NoScore());
|
||||||
|
|
||||||
setGenerator(new MazeGenerator());
|
setGenerator(new MazeGenerator());
|
||||||
this.generateMaze();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateMaze() {
|
|
||||||
Pos position = new Pos(0, 0, 0);
|
|
||||||
this.addMazePosition(position, Block.GREEN_WOOL);
|
|
||||||
|
|
||||||
List<Integer> previousDirections = new ArrayList<>();
|
|
||||||
int direction = 1; // 0 -> right; 1 -> straight; 2 -> left
|
|
||||||
for (int i = 0; i < 9; i++) {
|
|
||||||
for (int j = 0; j < 3; j++) {
|
|
||||||
position = position.add(direction-1,0,direction%2);
|
|
||||||
this.addMazePosition(position, Block.WHITE_WOOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int origin = 0;
|
|
||||||
int bound = 3;
|
|
||||||
long rightLeftDifference = previousDirections.stream().filter(integer -> integer == 0).count() - previousDirections.stream().filter(integer -> integer == 2).count();
|
|
||||||
if(rightLeftDifference >= 2 || direction == 2) origin = 1;
|
|
||||||
if(rightLeftDifference <= -2 || direction == 0) bound = 2;
|
|
||||||
direction = this.random.nextInt(origin, bound);
|
|
||||||
previousDirections.add(direction);
|
|
||||||
}
|
|
||||||
this.addMazePosition(position, Block.WHITE_WOOL);
|
|
||||||
this.addMazePosition(position.add(0,0,1), Block.WHITE_WOOL);
|
|
||||||
this.addMazePosition(position.add(0,0,2), Block.RED_WOOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addMazePosition(Pos position, Block pathBlock) {
|
|
||||||
this.mazeBatch.setBlock(position, pathBlock);
|
|
||||||
this.mazePath.add(position.add(0.5,1,0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbsoluteBlockBatch getMazeBatch() {
|
|
||||||
return this.mazeBatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Pos> getMazePath() {
|
|
||||||
return this.mazePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onPlayerJoin(Player p) {
|
protected boolean onPlayerJoin(Player p) {
|
||||||
TowerdefenseRoom newRoom = new TowerdefenseRoom(p, this);
|
p.getInventory().setItemStack(1, ItemStack.of(Material.ARMOR_STAND));
|
||||||
this.instances.add(newRoom);
|
|
||||||
p.setInstance(newRoom);
|
|
||||||
newRoom.startWave(List.of(EntityType.ENDERMAN, EntityType.BLAZE, EntityType.PLAYER, EntityType.HORSE, EntityType.ARMOR_STAND, EntityType.SKELETON));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense;
|
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.instance.Dimension;
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.generator.MazeGenerator;
|
|
||||||
import eu.mhsl.minenet.minigames.util.BatchUtil;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.entity.*;
|
|
||||||
import net.minestom.server.entity.attribute.Attribute;
|
|
||||||
import net.minestom.server.instance.InstanceContainer;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
|
||||||
import net.minestom.server.item.Material;
|
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class TowerdefenseRoom extends InstanceContainer {
|
|
||||||
private final Player player;
|
|
||||||
private final Towerdefense game;
|
|
||||||
|
|
||||||
public TowerdefenseRoom(Player player, Towerdefense game) {
|
|
||||||
super(UUID.randomUUID(), Dimension.OVERWORLD.key);
|
|
||||||
MinecraftServer.getInstanceManager().registerInstance(this);
|
|
||||||
this.player = player;
|
|
||||||
this.game = game;
|
|
||||||
this.player.setGameMode(GameMode.ADVENTURE);
|
|
||||||
this.player.setAllowFlying(true);
|
|
||||||
this.player.getInventory().setItemStack(0, ItemStack.of(Material.ARMOR_STAND));
|
|
||||||
|
|
||||||
setGenerator(new MazeGenerator());
|
|
||||||
BatchUtil.loadAndApplyBatch(this.game.getMazeBatch(), this, () -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startWave(List<EntityType> entities) {
|
|
||||||
int counter = 0;
|
|
||||||
for(EntityType entityType : entities) {
|
|
||||||
MinecraftServer.getSchedulerManager().scheduleTask(() -> {
|
|
||||||
this.addEntity(new EntityCreature(entityType));
|
|
||||||
return TaskSchedule.stop();
|
|
||||||
}, TaskSchedule.millis(800L*counter));
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addEntity(EntityCreature entity) {
|
|
||||||
entity.setInstance(this, this.game.getMazePath().getFirst());
|
|
||||||
entity.getAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.15);
|
|
||||||
entity.getNavigator().setPathTo(this.game.getMazePath().get(1), 0.7, () -> changeEntityGoal(entity, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void changeEntityGoal(EntityCreature entity, int positionIndex) {
|
|
||||||
if(positionIndex == this.game.getMazePath().size()-1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
entity.getNavigator().setPathTo(this.game.getMazePath().get(positionIndex+1), 0.7, () -> changeEntityGoal(entity, positionIndex+1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -17,11 +17,6 @@ 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()
|
||||||
|
@ -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.uuid);
|
logger.info("Deleting room " + room.uniqueId);
|
||||||
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,7 +65,6 @@ 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);
|
||||||
|
@ -28,10 +28,10 @@ public class Languages {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Lang getLanguage(Player p) {
|
public Lang getLanguage(Player p) {
|
||||||
return getLanguage(p.getSettings().locale().toString()); // TODO funktioniert die locale noch?
|
return getLanguage(p.getSettings().getLocale());
|
||||||
}
|
}
|
||||||
public Lang getLanguage(String mapId) {
|
public Lang getLanguage(String mapId) {
|
||||||
return languages.computeIfAbsent(mapId.toLowerCase(), unused -> languages.computeIfAbsent(defaultLanguage, (key) -> new DummyLang()));
|
return languages.computeIfAbsent(mapId, unused -> languages.computeIfAbsent(defaultLanguage, (key) -> new DummyLang()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readAll() {
|
private void readAll() {
|
||||||
|
@ -10,7 +10,7 @@ import java.util.Set;
|
|||||||
public class LastWinsScore extends Score {
|
public class LastWinsScore extends Score {
|
||||||
@Override
|
@Override
|
||||||
public void insertResultImplementation(Set<Player> p) {
|
public void insertResultImplementation(Set<Player> p) {
|
||||||
getScores().addFirst(p);
|
getScores().add(0, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
package eu.mhsl.minenet.minigames.score;
|
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.message.Icon;
|
|
||||||
import eu.mhsl.minenet.minigames.message.TranslatableMessage;
|
|
||||||
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
|
|
||||||
import eu.mhsl.minenet.minigames.message.type.TitleMessage;
|
|
||||||
import eu.mhsl.minenet.minigames.util.MapUtil;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class PointsWinScore extends Score {
|
|
||||||
private Map<Set<Player>, Integer> scoreOrder = new HashMap<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void insertResultImplementation(Set<Player> p, int currentPoints) {
|
|
||||||
this.scoreOrder.put(p, currentPoints);
|
|
||||||
this.scoreOrder = MapUtil.sortByValue(this.scoreOrder);
|
|
||||||
getScores().clear();
|
|
||||||
this.scoreOrder.forEach((player, integer) -> getScores().addFirst(player));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void insertResultImplementation(Set<Player> p) {
|
|
||||||
this.insertResultImplementation(p, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDone() {
|
|
||||||
if(isClosed()) return;
|
|
||||||
close();
|
|
||||||
new ChatMessage(Icon.STAR, true)
|
|
||||||
.appendTranslated("score#result")
|
|
||||||
.newLine()
|
|
||||||
.indent()
|
|
||||||
.numberedList(
|
|
||||||
getScores()
|
|
||||||
.stream()
|
|
||||||
.filter(players -> !players.stream()
|
|
||||||
.filter(player -> !player.getUsername().isBlank())
|
|
||||||
.toList()
|
|
||||||
.isEmpty())
|
|
||||||
.map(players -> players
|
|
||||||
.stream()
|
|
||||||
.filter(player -> scoreOrder.get(Set.of(player)) != null)
|
|
||||||
.map(player -> player.getUsername()+" : "+scoreOrder.get(Set.of(player)).toString())
|
|
||||||
.collect(Collectors.joining(", "))
|
|
||||||
)
|
|
||||||
.toList()
|
|
||||||
)
|
|
||||||
.undent()
|
|
||||||
.newLine()
|
|
||||||
.appendTranslated("score#thanks")
|
|
||||||
.send(instance.getPlayers());
|
|
||||||
|
|
||||||
instance.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected TranslatableMessage scoreMessage() {
|
|
||||||
return new TitleMessage(Duration.ofMillis(1000), Duration.ofSeconds(1)).appendTranslated("score#death");
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,7 +8,6 @@ import net.minestom.server.entity.Player;
|
|||||||
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
|
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
|
||||||
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
|
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
|
||||||
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -23,19 +22,10 @@ public abstract class Score {
|
|||||||
|
|
||||||
public Score() {}
|
public Score() {}
|
||||||
|
|
||||||
protected abstract void insertResultImplementation(Set<Player> p);
|
public Score(int ignoreLastPlayers) {
|
||||||
|
this.ignoreLastPlayers = ignoreLastPlayers;
|
||||||
protected void insertResultImplementation(Set<Player> p, int points) {
|
|
||||||
throw new NotImplementedException("This Score type is not able to process points");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertResult(Player p) {
|
|
||||||
this.insertResultProcessor(p, () -> this.insertResultImplementation(Set.of(p)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insertResult(Player p, int points) {
|
|
||||||
this.insertResultProcessor(p, () -> this.insertResultImplementation(Set.of(p), points));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void attachListeners() {
|
public void attachListeners() {
|
||||||
this.instance.eventNode()
|
this.instance.eventNode()
|
||||||
@ -55,9 +45,16 @@ public abstract class Score {
|
|||||||
setDone();
|
setDone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
protected abstract void insertResultImplementation(Set<Player> p);
|
||||||
protected abstract TranslatableMessage scoreMessage();
|
protected abstract TranslatableMessage scoreMessage();
|
||||||
|
|
||||||
|
public void insertResult(Player p) {
|
||||||
|
if(hasResult(p)) return;
|
||||||
|
this.scoreMessage().send(p);
|
||||||
|
this.insertResultImplementation(Set.of(p));
|
||||||
|
this.checkGameEnd();
|
||||||
|
}
|
||||||
|
|
||||||
public void insertRemainingPlayers(Set<Player> players) {
|
public void insertRemainingPlayers(Set<Player> players) {
|
||||||
this.insertResultImplementation(players.stream().filter(p -> !hasResult(p)).collect(Collectors.toSet()));
|
this.insertResultImplementation(players.stream().filter(p -> !hasResult(p)).collect(Collectors.toSet()));
|
||||||
setDone();
|
setDone();
|
||||||
@ -96,19 +93,10 @@ public abstract class Score {
|
|||||||
instance.stop();
|
instance.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertResultProcessor(Player p, Runnable callback) {
|
|
||||||
if(hasResult(p)) return;
|
|
||||||
this.scoreMessage().send(p);
|
|
||||||
callback.run();
|
|
||||||
this.checkGameEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isClosed() {
|
public boolean isClosed() {
|
||||||
return isClosed;
|
return isClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() { isClosed = true; }
|
|
||||||
|
|
||||||
protected void onGameEnd() {
|
protected void onGameEnd() {
|
||||||
this.instance.stop();
|
this.instance.stop();
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ public class TournamentDisplay extends MineNetInstance implements Spawnable {
|
|||||||
private final Tournament tournament;
|
private final Tournament tournament;
|
||||||
|
|
||||||
private final Pos[] placePositions = new Pos[] {
|
private final Pos[] placePositions = new Pos[] {
|
||||||
new Pos(8.5, -56, 22.5, 180, 0),
|
new Pos(8.5, -57, 21.5, 180, 0),
|
||||||
new Pos(12.5, -57, 20.5, 180, 0),
|
new Pos(9.5, -58, 21.5, 180, 0),
|
||||||
new Pos(4.5, -58, 20.5, 180, 0)
|
new Pos(7.5, -59, 21.5, 180, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
public TournamentDisplay(Tournament tournament) {
|
public TournamentDisplay(Tournament tournament) {
|
||||||
@ -30,8 +30,6 @@ public class TournamentDisplay extends MineNetInstance implements Spawnable {
|
|||||||
this.places = tournament.getPlaces();
|
this.places = tournament.getPlaces();
|
||||||
this.tournament = tournament;
|
this.tournament = tournament;
|
||||||
|
|
||||||
this.places.forEach(player -> player.setGameMode(GameMode.ADVENTURE));
|
|
||||||
|
|
||||||
eventNode().addListener(PlayerMoveEvent.class, playerMoveEvent -> {
|
eventNode().addListener(PlayerMoveEvent.class, playerMoveEvent -> {
|
||||||
if(isOnDisplay(playerMoveEvent.getPlayer()) && !playerMoveEvent.getNewPosition().sameBlock(placePositions[getRankPosition(playerMoveEvent.getPlayer())])) {
|
if(isOnDisplay(playerMoveEvent.getPlayer()) && !playerMoveEvent.getNewPosition().sameBlock(placePositions[getRankPosition(playerMoveEvent.getPlayer())])) {
|
||||||
playerMoveEvent.setCancelled(true);
|
playerMoveEvent.setCancelled(true);
|
||||||
@ -64,6 +62,6 @@ public class TournamentDisplay extends MineNetInstance implements Spawnable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pos getSpawn() {
|
public Pos getSpawn() {
|
||||||
return new Pos(8.5, -59, 11.5);
|
return new Pos(8.5, -55, 8.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.server.provider;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.util.UuidUtil;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.network.UuidProvider;
|
||||||
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
|
import net.minestom.server.utils.mojang.MojangUtils;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class ByPlayerNameUuidProvider implements UuidProvider {
|
||||||
|
@Override
|
||||||
|
public UUID provide(PlayerConnection playerConnection, String username) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
if(MinecraftServer.getConnectionManager().findOnlinePlayer(username) != null) throw new IllegalStateException();
|
||||||
|
String client = MojangUtils.fromUsername(username).get("id").getAsString();
|
||||||
|
return UuidUtil.unTrimm(client);
|
||||||
|
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Logger.getGlobal().info("Player " + username + " is unknown by Mojang! (Using random UUID)");
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
Logger.getGlobal().info("Player with the username " + username + " is already online.");
|
||||||
|
playerConnection.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return UUID.randomUUID();
|
||||||
|
}
|
||||||
|
}
|
@ -28,6 +28,10 @@ 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) {
|
||||||
|
@ -3,6 +3,7 @@ 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;
|
||||||
@ -11,15 +12,19 @@ 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().scheduleTask(() -> {
|
MinecraftServer.getSchedulerManager().submitTask(() -> {
|
||||||
p.setSkin(SkinCache.getSkin(p.getUsername()));
|
p.setSkin(SkinCache.getSkin(p.getUsername()));
|
||||||
return TaskSchedule.stop();
|
return TaskSchedule.stop();
|
||||||
}, TaskSchedule.millis(500));
|
}, ExecutionType.TICK_END);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,22 @@ public class InventoryItemAlignment {
|
|||||||
}.get(count);
|
}.get(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public record ItemOffset(int x, int z) {
|
public static class ItemOffset {
|
||||||
|
private final int x;
|
||||||
|
private final int z;
|
||||||
|
|
||||||
|
public ItemOffset(int x, int z) {
|
||||||
|
this.x = x;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
public int get() {
|
public int get() {
|
||||||
return x + (z * 9);
|
return x + (z * 9);
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
package eu.mhsl.minenet.minigames.util;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class MapUtil {
|
|
||||||
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
|
|
||||||
List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
|
|
||||||
list.sort(Map.Entry.comparingByValue());
|
|
||||||
|
|
||||||
Map<K, V> result = new LinkedHashMap<>();
|
|
||||||
for (Map.Entry<K, V> entry : list) {
|
|
||||||
result.put(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
39
src/main/java/eu/mhsl/minenet/minigames/util/PacketUtil.java
Normal file
39
src/main/java/eu/mhsl/minenet/minigames/util/PacketUtil.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.util;
|
||||||
|
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.entity.PlayerSkin;
|
||||||
|
import net.minestom.server.network.packet.server.play.PlayerInfoUpdatePacket;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PacketUtil {
|
||||||
|
public static void resendPlayerList(Player p) {
|
||||||
|
MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(player -> {
|
||||||
|
if(player.getUuid().equals(p.getUuid())) return;
|
||||||
|
|
||||||
|
final PlayerSkin skin = player.getSkin();
|
||||||
|
List<PlayerInfoUpdatePacket.Property> properties =
|
||||||
|
skin != null ? List.of(new PlayerInfoUpdatePacket.Property("textures", skin.textures(), skin.signature())) : List.of();
|
||||||
|
|
||||||
|
p.sendPacket(
|
||||||
|
new PlayerInfoUpdatePacket(PlayerInfoUpdatePacket.Action.ADD_PLAYER,
|
||||||
|
new PlayerInfoUpdatePacket.Entry(
|
||||||
|
player.getUuid(),
|
||||||
|
player.getUsername(),
|
||||||
|
properties,
|
||||||
|
true,
|
||||||
|
0,
|
||||||
|
GameMode.SURVIVAL,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// p.sendPacket( //TODO spawnPlayerPacket does no longer exists
|
||||||
|
// new SpawnPlayerPacket(player.getEntityId(), player.getUuid(), player.getPosition())
|
||||||
|
// );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
5
src/main/java/eu/mhsl/minenet/minigames/util/Static.java
Normal file
5
src/main/java/eu/mhsl/minenet/minigames/util/Static.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.util;
|
||||||
|
|
||||||
|
public abstract class Static {
|
||||||
|
public abstract void load(); //TODO REMOVE
|
||||||
|
}
|
@ -67,7 +67,7 @@ public class SquarePlateTerrainGenerator extends PlateTerrainGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(generateBorders) {
|
if(generateBorders) {
|
||||||
Runnable generateBorder = () -> unit.modifier().fill(bottom, bottom.add(1, DimensionType.VANILLA_MAX_Y, 1), Block.BARRIER);
|
Runnable generateBorder = () -> unit.modifier().fill(bottom, bottom.add(1, 0, 1), Block.BARRIER); // TODO DimensionType.OVERWORLD.getMaxY() is now hardcoded 0, might break behaviour
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -18,4 +18,3 @@ api:
|
|||||||
|
|
||||||
admins:
|
admins:
|
||||||
- minetec
|
- minetec
|
||||||
- 28Pupsi28
|
|
@ -23,11 +23,7 @@ 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;Survive the world or fight entities;Überlebe die Welt oder kämpfe gegen Mobs
|
pve_description;Surivie 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
|
||||||
@ -40,7 +36,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
|
||||||
@ -69,26 +65,15 @@ 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 mines;Prozentsatz der Minen
|
optionPercentageMines;Percentage of Miens;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
|
||||||
@ -98,14 +83,6 @@ 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 ????;??????
|
||||||
@ -114,19 +91,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#;;
|
|
||||||
name;Tetris;Tetris
|
|
||||||
description;Sort falling blocks and clear lines;Sortiere fallende Blöcke und kläre Linien
|
|
||||||
nextTetrominoesCount;Number of upcoming Tetrominos displayed;Anzahl der angezeigten kommenden Tetrominos
|
|
||||||
isFast;Fast mode;Schneller 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 91.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user