Compare commits
53 Commits
2f8ff36e5e
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 7734b225eb | |||
| 1a9b9f5fd2 | |||
| b0cf527977 | |||
| 01646546a3 | |||
| 13a0cdde3a | |||
| 7d60c74d85 | |||
| 0d7f1fc646 | |||
| ee421245d1 | |||
| d75332927c | |||
| 2c579f4afe | |||
| 82984cf5cf | |||
| 14f6a38212 | |||
| 3bdc4113c0 | |||
| b7e292fe0e | |||
| 57cd5acdfd | |||
| 0f72b8049d | |||
| 9992b07ed5 | |||
| f55148203e | |||
| 41753f2805 | |||
| 9bdb98cdc9 | |||
| 6f0ebe4d12 | |||
| 58983be156 | |||
| ee7d434d7e | |||
| 410f7b4027 | |||
| e1515200ab | |||
| 27005f4fc4 | |||
| 2808393c23 | |||
| d0825695b3 | |||
| e822a5c5e2 | |||
| bf95c8dcc2 | |||
| 2f70b25e87 | |||
| cbec1ea7f8 | |||
| c176cfaf2c | |||
| 56f56d48b6 | |||
| 991e51bc10 | |||
| ffba86ac41 | |||
| f95c670514 | |||
| 0b3c757ce0 | |||
| 76df6643db | |||
| 7186b4dbea | |||
| 24d79d7a11 | |||
| 70fd5bafdb | |||
| 11ddd01470 | |||
| 7d5fb025bd | |||
| 05240660f2 | |||
| d0031b4ea5 | |||
| 360266339d | |||
| 325fba2a53 | |||
| e760cdb2c6 | |||
| c111c027ff | |||
| 73ab137ae4 | |||
| 9a9e646288 | |||
| 728dc92fc8 |
Generated
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK" />
|
||||||
</project>
|
</project>
|
||||||
+17
-40
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id "com.github.johnrengelman.shadow" version "7.1.0"
|
id "com.gradleup.shadow" version "9.6.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'eu.mhsl.minenet'
|
group 'eu.mhsl.minenet'
|
||||||
@@ -11,58 +11,33 @@ version '1.0-SNAPSHOT'
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
google()
|
|
||||||
|
|
||||||
maven {
|
|
||||||
url 'https://jitpack.io'
|
|
||||||
}
|
|
||||||
|
|
||||||
maven {
|
|
||||||
url "https://repo.unnamed.team/repository/unnamed-public/"
|
|
||||||
}
|
|
||||||
|
|
||||||
maven {
|
|
||||||
url 'https://oss.sonatype.org/content/repositories/snapshots'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
maven { url "https://jitpack.io" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
java {
|
java {
|
||||||
toolchain {
|
toolchain {
|
||||||
languageVersion = JavaLanguageVersion.of(21)
|
languageVersion = JavaLanguageVersion.of(25)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
|
testImplementation 'org.junit.jupiter:junit-jupiter:6.1.2'
|
||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
|
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||||
|
|
||||||
//https://jitpack.io/#Minestom/Minestom
|
//https://mvnrepository.com/artifact/net.minestom/minestom
|
||||||
implementation 'net.minestom:minestom-snapshots:fd51c8d17a'
|
implementation 'net.minestom:minestom:2026.07.12-26.2'
|
||||||
|
|
||||||
//Tools
|
//Tools
|
||||||
implementation 'de.articdive:jnoise:3.0.2'
|
implementation 'de.articdive:jnoise-pipeline:4.1.0'
|
||||||
|
compileOnly 'it.unimi.dsi:fastutil:8.5.18' // von Minestom nur zur Laufzeit bereitgestellt, fuer BatchUtil-Reflection benoetigt
|
||||||
implementation 'net.md-5:bungeecord-config:1.21-R0.3'
|
implementation 'net.md-5:bungeecord-config:1.21-R0.3'
|
||||||
implementation 'org.apache.commons:commons-text:1.10.0'
|
implementation 'org.apache.commons:commons-text:1.15.0'
|
||||||
implementation 'org.spongepowered:configurate-yaml:4.1.2'
|
implementation 'org.spongepowered:configurate-yaml:4.2.0'
|
||||||
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.14.0'
|
||||||
implementation 'com.google.guava:guava:32.0.1-android'
|
implementation 'com.google.guava:guava:33.4.8-jre'
|
||||||
|
|
||||||
|
|
||||||
//PvP
|
//PvP
|
||||||
implementation 'io.github.TogAr2:MinestomPvP:PR62-SNAPSHOT'
|
implementation 'io.github.togar2:MinestomPvP:2026.05.30-26.1.1'
|
||||||
|
|
||||||
// Hephaestus engine
|
|
||||||
// implementation("team.unnamed:hephaestus-api:0.2.1-SNAPSHOT")
|
|
||||||
// implementation("team.unnamed:hephaestus-reader-blockbench:0.2.1-SNAPSHOT")
|
|
||||||
// implementation("team.unnamed:hephaestus-runtime-minestom:0.2.1-SNAPSHOT")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
@@ -71,8 +46,6 @@ tasks {
|
|||||||
attributes 'Main-Class': 'eu.mhsl.minenet.minigames.Main'
|
attributes 'Main-Class': 'eu.mhsl.minenet.minigames.Main'
|
||||||
attributes 'Multi-Release': true
|
attributes 'Multi-Release': true
|
||||||
}
|
}
|
||||||
duplicatesStrategy = 'exclude'
|
|
||||||
from configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
|
||||||
}
|
}
|
||||||
build {
|
build {
|
||||||
dependsOn(shadowJar)
|
dependsOn(shadowJar)
|
||||||
@@ -89,3 +62,7 @@ tasks.register('copyJarToServer', Exec) {
|
|||||||
|
|
||||||
commandLine 'scp', 'build/libs/Minigames-1.0-SNAPSHOT.jar', 'root@10.20.6.5:/root/minigames'
|
commandLine 'scp', 'build/libs/Minigames-1.0-SNAPSHOT.jar', 'root@10.20.6.5:/root/minigames'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
options.compilerArgs << "-Xlint:deprecation"
|
||||||
|
}
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
+3
-1
@@ -1,7 +1,9 @@
|
|||||||
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-9.6.1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
|
retries=0
|
||||||
|
retryBackOffMs=500
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015-2021 the original authors.
|
# Copyright © 2015 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# Gradle start up script for POSIX generated by Gradle.
|
# gradlew start up script for POSIX generated by Gradle.
|
||||||
#
|
#
|
||||||
# Important for running:
|
# Important for running:
|
||||||
#
|
#
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
# 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:
|
# command line, like:
|
||||||
#
|
#
|
||||||
# ksh Gradle
|
# ksh gradlew
|
||||||
#
|
#
|
||||||
# Busybox and similar reduced shells will NOT work, because this script
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
# requires all of these POSIX shell features:
|
# requires all of these POSIX shell features:
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -86,8 +86,7 @@ done
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||||
' "$PWD" ) || exit
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
@@ -115,7 +114,6 @@ case "$( uname )" in #(
|
|||||||
NONSTOP* ) nonstop=true ;;
|
NONSTOP* ) nonstop=true ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
@@ -173,7 +171,6 @@ fi
|
|||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
if "$cygwin" || "$msys" ; then
|
if "$cygwin" || "$msys" ; then
|
||||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
|
||||||
|
|
||||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
@@ -206,15 +203,14 @@ fi
|
|||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command:
|
# Collect all arguments for the java command:
|
||||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
# and any embedded shellness will be escaped.
|
# 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
|
# * 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.
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
-classpath "$CLASSPATH" \
|
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||||
org.gradle.wrapper.GradleWrapperMain \
|
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Stop when "xargs" is not available.
|
# Stop when "xargs" is not available.
|
||||||
|
|||||||
Vendored
+12
-24
@@ -19,12 +19,12 @@
|
|||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem gradlew startup script for Windows
|
||||||
@rem
|
@rem
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
|
|
||||||
@rem Set local scope for the variables with windows NT shell
|
@rem Set local scope for the variables, and ensure extensions are enabled
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
setlocal EnableExtensions
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%"=="" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
@@ -51,7 +51,7 @@ echo. 1>&2
|
|||||||
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 1>&2
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
"%COMSPEC%" /c exit 1
|
||||||
|
|
||||||
:findJavaFromJavaHome
|
:findJavaFromJavaHome
|
||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
@@ -65,30 +65,18 @@ echo. 1>&2
|
|||||||
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 1>&2
|
||||||
echo location of your Java installation. 1>&2
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
"%COMSPEC%" /c exit 1
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute gradlew
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
|
||||||
|
@rem which allows us to clear the local environment before executing the java command
|
||||||
|
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
|
||||||
|
|
||||||
:end
|
:exitWithErrorLevel
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
|
||||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
"%COMSPEC%" /c exit %ERRORLEVEL%
|
||||||
|
|
||||||
:fail
|
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
|
||||||
rem the _cmd.exe /c_ return code!
|
|
||||||
set EXIT_CODE=%ERRORLEVEL%
|
|
||||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
|
||||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
|
||||||
exit /b %EXIT_CODE%
|
|
||||||
|
|
||||||
:mainEnd
|
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
|
||||||
|
|
||||||
:omega
|
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ package eu.mhsl.minenet.minigames;
|
|||||||
import eu.mhsl.minenet.minigames.api.HttpServer;
|
import eu.mhsl.minenet.minigames.api.HttpServer;
|
||||||
import eu.mhsl.minenet.minigames.command.Commands;
|
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.instance.Dimension;
|
||||||
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 net.minestom.server.Auth;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.extras.bungee.BungeeCordProxy;
|
|
||||||
import net.minestom.server.extras.lan.OpenToLAN;
|
import net.minestom.server.extras.lan.OpenToLAN;
|
||||||
import net.minestom.server.extras.velocity.VelocityProxy;
|
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
import org.spongepowered.configurate.ConfigurateException;
|
import org.spongepowered.configurate.ConfigurateException;
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
import org.spongepowered.configurate.ConfigurationNode;
|
||||||
@@ -25,7 +25,7 @@ public class Main {
|
|||||||
public static ConfigurationNode globalConfig;
|
public static ConfigurationNode globalConfig;
|
||||||
|
|
||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
public static void main(String[] args) throws ConfigurateException {
|
static void main(String[] args) throws ConfigurateException {
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
Resource.values(); // This initializes and preloads the enum and extracts the resources
|
Resource.values(); // This initializes and preloads the enum and extracts the resources
|
||||||
Languages.getInstance(); //Preload languages into the jvm
|
Languages.getInstance(); //Preload languages into the jvm
|
||||||
@@ -38,14 +38,31 @@ public class Main {
|
|||||||
|
|
||||||
ConfigurationNode serverConfig = globalConfig.node("server");
|
ConfigurationNode serverConfig = globalConfig.node("server");
|
||||||
|
|
||||||
|
// muss vor MinecraftServer.init() gesetzt werden: ServerFlag liest die Properties statisch beim Klassenladen;
|
||||||
|
// bei fehlendem/ungueltigem Config-Wert den Minestom-Default behalten (0 wuerde keine Chunks senden)
|
||||||
|
int viewDistance = serverConfig.node("view-distance").getInt(0);
|
||||||
|
if(viewDistance > 0) {
|
||||||
|
System.setProperty("minestom.chunk-view-distance", String.valueOf(viewDistance));
|
||||||
|
}
|
||||||
|
|
||||||
logger.info("Initialize Minecraft server...");
|
logger.info("Initialize Minecraft server...");
|
||||||
|
|
||||||
MinecraftServer server = MinecraftServer.init();
|
Auth auth = new Auth.Offline();
|
||||||
|
if(globalConfig.node("bungeecord", "enabled").getBoolean()) {
|
||||||
|
auth = new Auth.Bungee();
|
||||||
|
} else if(globalConfig.node("velocity", "enabled").getBoolean()) {
|
||||||
|
auth = new Auth.Velocity(Objects.requireNonNull(globalConfig.node("velocity", "secret").getString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
MinecraftServer server = MinecraftServer.init(auth);
|
||||||
// MinestomPvP.init();
|
// MinestomPvP.init();
|
||||||
|
|
||||||
|
// Dimensionen muessen vor server.start() registriert werden:
|
||||||
|
// seit Minestom 26.x sind die dynamischen Registries nach dem Start eingefroren
|
||||||
|
Dimension.values();
|
||||||
|
|
||||||
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()));
|
|
||||||
|
|
||||||
Commands.values();
|
Commands.values();
|
||||||
Listeners.values();
|
Listeners.values();
|
||||||
@@ -57,12 +74,6 @@ public class Main {
|
|||||||
|
|
||||||
if(serverConfig.node("open-to-lan").getBoolean()) OpenToLAN.open();
|
if(serverConfig.node("open-to-lan").getBoolean()) OpenToLAN.open();
|
||||||
|
|
||||||
if(globalConfig.node("bungeecord", "enabled").getBoolean()) BungeeCordProxy.enable();
|
|
||||||
|
|
||||||
if(globalConfig.node("velocity", "enabled").getBoolean()) {
|
|
||||||
VelocityProxy.enable(Objects.requireNonNull(globalConfig.node("velocity", "secret").getString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
server.start("0.0.0.0", serverConfig.node("port").getInt(25565));
|
server.start("0.0.0.0", serverConfig.node("port").getInt(25565));
|
||||||
System.gc();
|
System.gc();
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class SetMemorialCommand extends PrivilegedCommand {
|
|||||||
.getTournament()
|
.getTournament()
|
||||||
.setMemorialConfiguration(
|
.setMemorialConfiguration(
|
||||||
new MemorialConfiguration(
|
new MemorialConfiguration(
|
||||||
Material.fromNamespaceId(context.get(materialArgument)),
|
Material.fromKey(context.get(materialArgument)),
|
||||||
context.get(titleArgument),
|
context.get(titleArgument),
|
||||||
context.get(loreArgument)
|
context.get(loreArgument)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class SetRewardCommand extends PrivilegedCommand {
|
|||||||
.getTournament()
|
.getTournament()
|
||||||
.setRewardConfiguration(
|
.setRewardConfiguration(
|
||||||
new RewardConfiguration(
|
new RewardConfiguration(
|
||||||
Material.fromNamespaceId(context.get(materialArgument)),
|
Material.fromKey(context.get(materialArgument)),
|
||||||
Arrays.stream(context.get(amountsArgument)).map(Integer::valueOf).collect(Collectors.toList())
|
Arrays.stream(context.get(amountsArgument)).map(Integer::valueOf).collect(Collectors.toList())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package eu.mhsl.minenet.minigames.handler;
|
|||||||
|
|
||||||
import eu.mhsl.minenet.minigames.handler.global.AddEntityToInstanceEventListener;
|
import eu.mhsl.minenet.minigames.handler.global.AddEntityToInstanceEventListener;
|
||||||
import eu.mhsl.minenet.minigames.handler.global.ChatFormatHandler;
|
import eu.mhsl.minenet.minigames.handler.global.ChatFormatHandler;
|
||||||
|
import eu.mhsl.minenet.minigames.handler.global.PlayerFreezeHandler;
|
||||||
import eu.mhsl.minenet.minigames.handler.global.PlayerLeaveHandler;
|
import eu.mhsl.minenet.minigames.handler.global.PlayerLeaveHandler;
|
||||||
import eu.mhsl.minenet.minigames.handler.global.PlayerLoginHandler;
|
import eu.mhsl.minenet.minigames.handler.global.PlayerLoginHandler;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
@@ -11,6 +12,7 @@ public enum Listeners {
|
|||||||
SPAWN(new AddEntityToInstanceEventListener()),
|
SPAWN(new AddEntityToInstanceEventListener()),
|
||||||
LOGIN(new PlayerLoginHandler()),
|
LOGIN(new PlayerLoginHandler()),
|
||||||
LEAVE(new PlayerLeaveHandler()),
|
LEAVE(new PlayerLeaveHandler()),
|
||||||
|
FREEZE(new PlayerFreezeHandler()),
|
||||||
CHAT(new ChatFormatHandler());
|
CHAT(new ChatFormatHandler());
|
||||||
|
|
||||||
Listeners(EventListener<?> event) {
|
Listeners(EventListener<?> event) {
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.handler.global;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.event.EventListener;
|
||||||
|
import net.minestom.server.event.player.PlayerTickEvent;
|
||||||
|
import net.minestom.server.instance.Instance;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Weder Minestom noch MinestomPvP verwalten die TICKS_FROZEN-Metadata. Der 26.x-Client baut das
|
||||||
|
* Freeze-Overlay bei Powder-Snow-Kontakt zwar selbst auf, der Abbau ist aber server-authoritative —
|
||||||
|
* ohne diese Vanilla-Logik bleibt das Overlay dauerhaft haengen (auch ueber Instanzwechsel hinweg).
|
||||||
|
*/
|
||||||
|
public class PlayerFreezeHandler implements EventListener<PlayerTickEvent> {
|
||||||
|
private static final int TICKS_REQUIRED_TO_FREEZE = 140;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Class<PlayerTickEvent> eventType() {
|
||||||
|
return PlayerTickEvent.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Result run(@NotNull PlayerTickEvent event) {
|
||||||
|
Player p = event.getPlayer();
|
||||||
|
Instance instance = p.getInstance();
|
||||||
|
if(instance == null) return Result.SUCCESS;
|
||||||
|
|
||||||
|
Pos pos = p.getPosition();
|
||||||
|
boolean inPowderSnow = instance.getBlock(pos).compare(Block.POWDER_SNOW)
|
||||||
|
|| instance.getBlock(pos.add(0, 1, 0)).compare(Block.POWDER_SNOW);
|
||||||
|
|
||||||
|
int ticksFrozen = p.getEntityMeta().getTickFrozen();
|
||||||
|
if(inPowderSnow) {
|
||||||
|
p.getEntityMeta().setTickFrozen(Math.min(TICKS_REQUIRED_TO_FREEZE, ticksFrozen + 1));
|
||||||
|
} else if(ticksFrozen > 0) {
|
||||||
|
p.getEntityMeta().setTickFrozen(Math.max(0, ticksFrozen - 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,45 +1,66 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance;
|
package eu.mhsl.minenet.minigames.instance;
|
||||||
|
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.registry.DynamicRegistry;
|
import net.minestom.server.registry.RegistryKey;
|
||||||
import net.minestom.server.utils.NamespaceID;
|
import net.minestom.server.registry.RegistryTag;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.minestom.server.world.DimensionType;
|
import net.minestom.server.world.DimensionType;
|
||||||
|
import net.minestom.server.world.attribute.EnvironmentAttribute;
|
||||||
|
import net.minestom.server.world.clock.WorldClock;
|
||||||
|
import net.minestom.server.world.timeline.Timeline;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prebuilt dimensions
|
* Prebuilt dimensions
|
||||||
*/
|
*/
|
||||||
public enum Dimension {
|
public enum Dimension {
|
||||||
OVERWORLD(
|
OVERWORLD(
|
||||||
NamespaceID.from("minenet:fullbright_overworld"),
|
Key.key("minenet:fullbright_overworld"),
|
||||||
DimensionType
|
DimensionType
|
||||||
.builder()
|
.builder()
|
||||||
.ambientLight(2.0f)
|
// Fullbright: seit MC 26.1 laeuft die Grundhelligkeit ueber das Environment-Attribut
|
||||||
|
// AMBIENT_LIGHT_COLOR (Vanilla-Overworld: #0A0A0A); der alte ambientLight-2.0-Hack
|
||||||
|
// liegt ausserhalb der validen Range und bricht das Client-Rendering
|
||||||
|
.setAttribute(EnvironmentAttribute.AMBIENT_LIGHT_COLOR, NamedTextColor.WHITE)
|
||||||
|
// defaultClock noetig, damit Instance#setTime/#defaultClock funktionieren (sonst null); Timelines wie Vanilla-Overworld
|
||||||
|
.defaultClock(WorldClock.OVERWORLD)
|
||||||
|
.timelines(RegistryTag.direct(Timeline.DAY, Timeline.MOON, Timeline.EARLY_GAME, Timeline.VILLAGER_SCHEDULE))
|
||||||
.build()
|
.build()
|
||||||
),
|
),
|
||||||
|
|
||||||
NETHER(
|
NETHER(
|
||||||
NamespaceID.from("minenet:fullbright_nether"),
|
Key.key("minenet:fullbright_nether"),
|
||||||
DimensionType
|
DimensionType
|
||||||
.builder()
|
.builder()
|
||||||
.ambientLight(2.0f)
|
// Fullbright: seit MC 26.1 laeuft die Grundhelligkeit ueber das Environment-Attribut
|
||||||
.effects("minecraft:the_nether")
|
// AMBIENT_LIGHT_COLOR (Vanilla-Overworld: #0A0A0A); der alte ambientLight-2.0-Hack
|
||||||
|
// liegt ausserhalb der validen Range und bricht das Client-Rendering
|
||||||
|
.setAttribute(EnvironmentAttribute.AMBIENT_LIGHT_COLOR, NamedTextColor.WHITE)
|
||||||
|
.skybox(DimensionType.Skybox.NONE)
|
||||||
|
.defaultClock(WorldClock.OVERWORLD)
|
||||||
|
.timelines(RegistryTag.direct(Timeline.VILLAGER_SCHEDULE))
|
||||||
.build()
|
.build()
|
||||||
),
|
),
|
||||||
|
|
||||||
THE_END(
|
THE_END(
|
||||||
NamespaceID.from("minenet:fullbright_end"),
|
Key.key("minenet:fullbright_end"),
|
||||||
DimensionType
|
DimensionType
|
||||||
.builder()
|
.builder()
|
||||||
.ambientLight(2.0f)
|
// Fullbright: seit MC 26.1 laeuft die Grundhelligkeit ueber das Environment-Attribut
|
||||||
.effects("minecraft:the_end")
|
// AMBIENT_LIGHT_COLOR (Vanilla-Overworld: #0A0A0A); der alte ambientLight-2.0-Hack
|
||||||
|
// liegt ausserhalb der validen Range und bricht das Client-Rendering
|
||||||
|
.setAttribute(EnvironmentAttribute.AMBIENT_LIGHT_COLOR, NamedTextColor.WHITE)
|
||||||
|
.skybox(DimensionType.Skybox.END)
|
||||||
|
.defaultClock(WorldClock.THE_END)
|
||||||
|
.timelines(RegistryTag.direct(Timeline.VILLAGER_SCHEDULE))
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
public final DimensionType DIMENSION;
|
public final DimensionType DIMENSION;
|
||||||
public final NamespaceID namespaceID;
|
public final Key namespaceID;
|
||||||
public final DynamicRegistry.Key<DimensionType> key;
|
public final RegistryKey<DimensionType> key;
|
||||||
|
|
||||||
Dimension(NamespaceID namespaceID, DimensionType dimType) {
|
Dimension(Key namespaceID, DimensionType dimType) {
|
||||||
this.DIMENSION = dimType;
|
this.DIMENSION = dimType;
|
||||||
this.namespaceID = namespaceID;
|
this.namespaceID = namespaceID;
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,29 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance;
|
package eu.mhsl.minenet.minigames.instance;
|
||||||
|
|
||||||
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
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.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.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
import net.minestom.server.instance.InstanceContainer;
|
import net.minestom.server.instance.InstanceContainer;
|
||||||
import net.minestom.server.registry.DynamicRegistry;
|
import net.minestom.server.registry.RegistryKey;
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
import net.minestom.server.world.DimensionType;
|
import net.minestom.server.world.DimensionType;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class MineNetInstance extends InstanceContainer {
|
public class MineNetInstance extends InstanceContainer {
|
||||||
public MineNetInstance(DynamicRegistry.Key<DimensionType> type) {
|
public MineNetInstance(RegistryKey<DimensionType> type) {
|
||||||
super(UUID.randomUUID(), type);
|
this(UUID.randomUUID(), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eindeutiger Dimension-Name pro Instanz: Minestom entscheidet anhand dieses Namens (nicht des
|
||||||
|
// DimensionTypes), ob beim setInstance das volle Respawn-Protokoll gefahren wird. Ohne den Reset
|
||||||
|
// rendert der 26.x-Client nach einem Wechsel zwischen Instanzen gleicher Dimension keine Chunks.
|
||||||
|
private MineNetInstance(UUID uuid, RegistryKey<DimensionType> type) {
|
||||||
|
super(uuid, type, Key.key("minenet", "instance-" + uuid));
|
||||||
MinecraftServer.getInstanceManager().registerInstance(this);
|
MinecraftServer.getInstanceManager().registerInstance(this);
|
||||||
|
|
||||||
this.eventNode()
|
this.eventNode()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import net.minestom.server.event.item.ItemDropEvent;
|
|||||||
import net.minestom.server.event.player.PlayerBlockBreakEvent;
|
import net.minestom.server.event.player.PlayerBlockBreakEvent;
|
||||||
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
|
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
|
||||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
import net.minestom.server.registry.DynamicRegistry;
|
import net.minestom.server.registry.RegistryKey;
|
||||||
import net.minestom.server.timer.ExecutionType;
|
import net.minestom.server.timer.ExecutionType;
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
import net.minestom.server.world.DimensionType;
|
import net.minestom.server.world.DimensionType;
|
||||||
@@ -34,7 +34,7 @@ public abstract class Game extends MineNetInstance implements Spawnable {
|
|||||||
protected boolean isRunning = false;
|
protected boolean isRunning = false;
|
||||||
protected boolean isBeforeBeginning = true;
|
protected boolean isBeforeBeginning = true;
|
||||||
|
|
||||||
public Game(DynamicRegistry.Key<DimensionType> dimensionType) {
|
public Game(RegistryKey<DimensionType> dimensionType) {
|
||||||
super(dimensionType);
|
super(dimensionType);
|
||||||
|
|
||||||
MinecraftServer.getInstanceManager().registerInstance(this);
|
MinecraftServer.getInstanceManager().registerInstance(this);
|
||||||
|
|||||||
@@ -5,15 +5,19 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain.AcidRain
|
|||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle.BlockBattleFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace.BlockBreakRaceFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace.BlockBreakRaceFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace.BoatRaceFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace.BoatRaceFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.colorJump.ColorJumpFactory;
|
||||||
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.elytraRace.ElytraRaceFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge.FastbridgeFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge.FastbridgeFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.highGround.HighGroundFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.highGround.HighGroundFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive.JumpDiveFactory;
|
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.pillars.PillarsFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.PlayerRaceFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.spaceSnake.SpaceSnakeFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.spaceSnake.SpaceSnakeFactory;
|
||||||
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;
|
||||||
@@ -46,7 +50,11 @@ public enum GameList {
|
|||||||
FASTBRIDGE(new FastbridgeFactory(), GameType.OTHER),
|
FASTBRIDGE(new FastbridgeFactory(), GameType.OTHER),
|
||||||
BLOCKBREAKRACE(new BlockBreakRaceFactory(), GameType.OTHER),
|
BLOCKBREAKRACE(new BlockBreakRaceFactory(), GameType.OTHER),
|
||||||
SPACESNAKE(new SpaceSnakeFactory(), GameType.PVP),
|
SPACESNAKE(new SpaceSnakeFactory(), GameType.PVP),
|
||||||
BOATRACE(new BoatRaceFactory(), GameType.OTHER);
|
BOATRACE(new BoatRaceFactory(), GameType.OTHER),
|
||||||
|
PILLARS(new PillarsFactory(), GameType.PROTOTYPE),
|
||||||
|
BLOCKBATTLE(new BlockBattleFactory(), GameType.PVP),
|
||||||
|
COLORJUMP(new ColorJumpFactory(), GameType.JUMPNRUN),
|
||||||
|
PLAYERRACE(new PlayerRaceFactory(), GameType.JUMPNRUN);
|
||||||
|
|
||||||
private final GameFactory factory;
|
private final GameFactory factory;
|
||||||
private final GameType type;
|
private final GameType type;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import eu.mhsl.minenet.minigames.score.Score;
|
|||||||
import net.kyori.adventure.audience.Audience;
|
import net.kyori.adventure.audience.Audience;
|
||||||
import net.kyori.adventure.text.Component;
|
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.RegistryKey;
|
||||||
import net.minestom.server.timer.ExecutionType;
|
import net.minestom.server.timer.ExecutionType;
|
||||||
import net.minestom.server.timer.Task;
|
import net.minestom.server.timer.Task;
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
@@ -26,7 +26,7 @@ public class StatelessGame extends Game {
|
|||||||
private int timeLimit = 0;
|
private int timeLimit = 0;
|
||||||
private int timePlayed = 0;
|
private int timePlayed = 0;
|
||||||
|
|
||||||
public StatelessGame(DynamicRegistry.Key<DimensionType> dimensionType, String gameName, Score score) {
|
public StatelessGame(RegistryKey<DimensionType> dimensionType, String gameName, Score score) {
|
||||||
super(dimensionType);
|
super(dimensionType);
|
||||||
this.score = score;
|
this.score = score;
|
||||||
this.name = gameName;
|
this.name = gameName;
|
||||||
|
|||||||
+4
-4
@@ -14,9 +14,9 @@ import net.minestom.server.MinecraftServer;
|
|||||||
import net.minestom.server.entity.Player;
|
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.inventory.InventoryPreClickEvent;
|
||||||
import net.minestom.server.inventory.InventoryType;
|
import net.minestom.server.inventory.InventoryType;
|
||||||
import net.minestom.server.inventory.click.ClickType;
|
import net.minestom.server.inventory.click.Click;
|
||||||
import net.minestom.server.inventory.condition.InventoryConditionResult;
|
|
||||||
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.sound.SoundEvent;
|
import net.minestom.server.sound.SoundEvent;
|
||||||
@@ -106,8 +106,8 @@ public class GameConfigurationInventory extends InteractableInventory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
|
protected void onClick(Player player, int slot, Click click, InventoryPreClickEvent event) {
|
||||||
inventoryConditionResult.setCancel(true);
|
event.setCancelled(true);
|
||||||
|
|
||||||
if(!this.map.containsKey(slot)) return;
|
if(!this.map.containsKey(slot)) return;
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,7 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain;
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain;
|
||||||
|
|
||||||
import de.articdive.jnoise.JNoise;
|
import de.articdive.jnoise.generators.noisegen.opensimplex.FastSimplexNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
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;
|
||||||
@@ -28,9 +29,8 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
|
|
||||||
public class AcidRain extends StatelessGame {
|
public class AcidRain extends StatelessGame {
|
||||||
final JNoise noise = JNoise.newBuilder()
|
final JNoise noise = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.09)
|
||||||
.setFrequency(0.09)
|
|
||||||
.build();
|
.build();
|
||||||
final private int radius = 20;
|
final private int radius = 20;
|
||||||
final private int roofHeight = 55;
|
final private int roofHeight = 55;
|
||||||
@@ -105,7 +105,7 @@ public class AcidRain extends StatelessGame {
|
|||||||
for(int z = -radius; z <= radius; z++) {
|
for(int z = -radius; z <= radius; z++) {
|
||||||
batch.setBlock(x, this.roofHeight, z, Block.AIR);
|
batch.setBlock(x, this.roofHeight, z, Block.AIR);
|
||||||
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue;
|
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue;
|
||||||
if(this.noise.getNoise(x + offset, z + offset) > 0.4) continue;
|
if(this.noise.evaluateNoise(x + offset, z + offset) > 0.4) continue;
|
||||||
|
|
||||||
batch.setBlock(x, this.roofHeight, z, Block.OAK_PLANKS);
|
batch.setBlock(x, this.roofHeight, z, Block.OAK_PLANKS);
|
||||||
}
|
}
|
||||||
|
|||||||
+207
@@ -0,0 +1,207 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
|
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
|
||||||
|
import eu.mhsl.minenet.minigames.util.BatchUtil;
|
||||||
|
import io.github.togar2.pvp.events.FinalAttackEvent;
|
||||||
|
import io.github.togar2.pvp.feature.CombatFeatures;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.event.player.PlayerBlockBreakEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
|
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class BlockBattle extends StatelessGame {
|
||||||
|
private final Team teamBlue = new Team(new Pos(0,101,20).add(0.5).withView(180, 0), Team.Color.BLUE);
|
||||||
|
private final Team teamRed = new Team(new Pos(0, 101, -20).add(0.5), Team.Color.RED);
|
||||||
|
private final int itemCount;
|
||||||
|
|
||||||
|
private final Map<Player, Team> teams = new WeakHashMap<>();
|
||||||
|
|
||||||
|
public BlockBattle(int itemCount) {
|
||||||
|
super(Dimension.THE_END.key, "Block Battle", new FirstWinsScore());
|
||||||
|
|
||||||
|
this.itemCount = itemCount;
|
||||||
|
|
||||||
|
this.eventNode().addChild(
|
||||||
|
CombatFeatures.empty()
|
||||||
|
.add(CombatFeatures.VANILLA_ATTACK)
|
||||||
|
.add(CombatFeatures.VANILLA_DAMAGE)
|
||||||
|
.add(CombatFeatures.VANILLA_KNOCKBACK)
|
||||||
|
.build().createNode()
|
||||||
|
);
|
||||||
|
|
||||||
|
this.eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
|
||||||
|
if(this.isBeforeBeginning) finalAttackEvent.setCancelled(true);
|
||||||
|
finalAttackEvent.setBaseDamage(0);
|
||||||
|
((Player) finalAttackEvent.getTarget()).setHealth(20);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||||
|
this.generatePlatform(new Pos(0, 100, 0), Block.GOLD_BLOCK, Block.YELLOW_CONCRETE_POWDER);
|
||||||
|
this.generatePlatform(new Pos(0, 101, 0), Block.AIR, Block.SANDSTONE_SLAB);
|
||||||
|
this.generatePlatform(new Pos(0, 100, 20), Block.BLUE_CONCRETE, Block.BLUE_CONCRETE_POWDER);
|
||||||
|
this.generatePlatform(new Pos(0, 100, -20), Block.RED_CONCRETE, Block.RED_CONCRETE_POWDER);
|
||||||
|
this.generatePlatform(new Pos(-5, 101, -14), Block.RED_STAINED_GLASS, Block.AIR);
|
||||||
|
this.generatePlatform(new Pos(5, 101, 14), Block.BLUE_STAINED_GLASS, Block.AIR);
|
||||||
|
|
||||||
|
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||||
|
|
||||||
|
Pos[] positionsRedGlass = {
|
||||||
|
new Pos(2, 102, -9),
|
||||||
|
new Pos(-1, 103, -9),
|
||||||
|
new Pos(-2, 104, -6),
|
||||||
|
new Pos(-5, 103, -7),
|
||||||
|
new Pos(-7, 102, -10),
|
||||||
|
new Pos(3, 102, -12),
|
||||||
|
new Pos(5, 101, -15)
|
||||||
|
};
|
||||||
|
|
||||||
|
Pos[] positionsBlueGlass = {
|
||||||
|
new Pos(-5, 101, 15),
|
||||||
|
new Pos(-3, 102, 12),
|
||||||
|
new Pos(-2, 102, 9),
|
||||||
|
new Pos(1, 103, 9),
|
||||||
|
new Pos(2, 104, 6),
|
||||||
|
new Pos(5, 103, 7),
|
||||||
|
new Pos(7, 102, 10)
|
||||||
|
};
|
||||||
|
|
||||||
|
for(Pos pos : positionsRedGlass)
|
||||||
|
batch.setBlock(pos, Block.RED_STAINED_GLASS);
|
||||||
|
|
||||||
|
for(Pos pos : positionsBlueGlass)
|
||||||
|
batch.setBlock(pos, Block.BLUE_STAINED_GLASS);
|
||||||
|
|
||||||
|
BatchUtil.loadAndApplyBatch(batch, this, () -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {
|
||||||
|
Pos posGoldBlock = new Pos(playerBlockPlaceEvent.getBlockPosition()).sub(0, 1, 0);
|
||||||
|
Block goldBlock = playerBlockPlaceEvent.getInstance().getBlock(posGoldBlock);
|
||||||
|
|
||||||
|
playerBlockPlaceEvent.setCancelled(goldBlock != Block.GOLD_BLOCK);
|
||||||
|
|
||||||
|
playerBlockPlaceEvent.getInstance().scheduler().scheduleNextTick(() -> {
|
||||||
|
Pos middle = new Pos(0, 101, 0);
|
||||||
|
boolean validBlue = true;
|
||||||
|
boolean validRed = true;
|
||||||
|
|
||||||
|
for(int x = middle.blockX()-1; x < middle.blockX()+2; x++) {
|
||||||
|
for(int z = middle.blockZ()-1; z < middle.blockZ()+2; z++) {
|
||||||
|
if(playerBlockPlaceEvent.getInstance().getBlock(x, 101, z) != Block.BLUE_WOOL) {
|
||||||
|
validBlue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!validBlue)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = middle.blockX()-1; x < middle.blockX()+2; x++) {
|
||||||
|
for(int z = middle.blockZ()-1; z < middle.blockZ()+2; z++) {
|
||||||
|
if(playerBlockPlaceEvent.getInstance().getBlock(x, 101, z) != Block.RED_WOOL) {
|
||||||
|
validRed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!validRed)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!validBlue && !validRed) return;
|
||||||
|
var winningTeam = validBlue ? Team.Color.BLUE : Team.Color.RED;
|
||||||
|
var winningPlayers = this.teams.entrySet().stream()
|
||||||
|
.filter(entry -> entry.getValue().color().equals(winningTeam))
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
this.getScore().insertMultiple(winningPlayers);
|
||||||
|
super.stop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent playerBlockBreakEvent) {
|
||||||
|
boolean isAllowed = Arrays.stream(Team.Color.values())
|
||||||
|
.map(Team.Color::getMaterial)
|
||||||
|
.map(Material::block)
|
||||||
|
.toList()
|
||||||
|
.contains(playerBlockBreakEvent.getBlock());
|
||||||
|
if(!isAllowed) playerBlockBreakEvent.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
|
||||||
|
if(playerMoveEvent.getNewPosition().y() < 95) {
|
||||||
|
var player = playerMoveEvent.getPlayer();
|
||||||
|
|
||||||
|
player.teleport(
|
||||||
|
this.isBeforeBeginning
|
||||||
|
? this.getSpawn()
|
||||||
|
: this.teams.get(player).spawnPosition()
|
||||||
|
);
|
||||||
|
|
||||||
|
this.giveItems(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
this.setTeams();
|
||||||
|
this.getPlayers().forEach(player -> player.teleport(this.teams.get(player).spawnPosition()).thenRun(() -> {
|
||||||
|
this.giveItems(player);
|
||||||
|
player.setGameMode(GameMode.SURVIVAL);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generatePlatform(Pos center, Block inner, Block outer) {
|
||||||
|
for(int x = center.blockX()-2; x < center.blockX()+3; x++) {
|
||||||
|
for(int z = center.blockZ()-2; z < center.blockZ()+3; z++) {
|
||||||
|
this.setBlock(x, center.blockY(), z, outer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = center.blockX()-1; x < center.blockX()+2; x++) {
|
||||||
|
for(int z = center.blockZ()-1; z < center.blockZ()+2; z++) {
|
||||||
|
this.setBlock(x, center.blockY(), z, inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTeams() {
|
||||||
|
List<Player> players = new ArrayList<>(this.getPlayers());
|
||||||
|
Collections.shuffle(players);
|
||||||
|
int halfPlayers = players.size()/2;
|
||||||
|
players.subList(0, halfPlayers).forEach(player -> this.teams.put(player, this.teamBlue));
|
||||||
|
players.subList(halfPlayers, players.size()).forEach(player -> this.teams.put(player, this.teamRed));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pos getSpawn() {
|
||||||
|
return new Pos(0, 101, 0).add(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void giveItems(Player player) {
|
||||||
|
player.getInventory().clear();
|
||||||
|
ItemStack item = ItemStack.of(
|
||||||
|
this.teams.get(player).color().getMaterial(),
|
||||||
|
this.itemCount
|
||||||
|
);
|
||||||
|
player.getInventory().addItemStack(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle;
|
||||||
|
|
||||||
|
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 BlockBattleFactory implements GameFactory {
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent name() {
|
||||||
|
return TranslatedComponent.byId("game_BlockBattle#name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent description() {
|
||||||
|
return TranslatedComponent.byId("game_BlockBattle#description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigManager configuration() {
|
||||||
|
return new ConfigManager()
|
||||||
|
.addOption(new NumericOption("itemCount", Material.WHITE_WOOL, TranslatedComponent.byId("game_BlockBattle#itemCount"), 1, 2, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material symbol() {
|
||||||
|
return Material.GREEN_CONCRETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
|
return new BlockBattle(configuration.get("itemCount").getAsInt()).setParent(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
|
public record Team(Pos spawnPosition, Color color) {
|
||||||
|
public enum Color {
|
||||||
|
RED(Material.RED_WOOL),
|
||||||
|
BLUE(Material.BLUE_WOOL);
|
||||||
|
|
||||||
|
private final Material block;
|
||||||
|
|
||||||
|
Color(Material block) {
|
||||||
|
this.block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material getMaterial() {
|
||||||
|
return this.block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+176
@@ -0,0 +1,176 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.colorJump;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
|
import eu.mhsl.minenet.minigames.score.LastWinsScore;
|
||||||
|
import eu.mhsl.minenet.minigames.util.BatchUtil;
|
||||||
|
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.event.inventory.InventoryPreClickEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerSwapItemEvent;
|
||||||
|
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.timer.Scheduler;
|
||||||
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
public class ColorJump extends StatelessGame {
|
||||||
|
private final List<Block> blocks = List.of(
|
||||||
|
Block.RED_CONCRETE,
|
||||||
|
Block.ORANGE_CONCRETE,
|
||||||
|
Block.YELLOW_CONCRETE,
|
||||||
|
Block.LIME_CONCRETE,
|
||||||
|
Block.LIGHT_BLUE_CONCRETE,
|
||||||
|
Block.BLUE_CONCRETE,
|
||||||
|
Block.PURPLE_CONCRETE,
|
||||||
|
Block.PINK_CONCRETE
|
||||||
|
);
|
||||||
|
private Block currentBlock;
|
||||||
|
private Block blockLastRound;
|
||||||
|
private double roundTime = 5;
|
||||||
|
private final double multiplierNextRoundTime = 0.9;
|
||||||
|
|
||||||
|
public ColorJump() {
|
||||||
|
super(Dimension.THE_END.key, "ColorJump", new LastWinsScore());
|
||||||
|
this.getScore().setIgnoreLastPlayers(1);
|
||||||
|
|
||||||
|
this.setGenerator(new CircularPlateTerrainGenerator(100));
|
||||||
|
|
||||||
|
this.eventNode().addListener(
|
||||||
|
InventoryPreClickEvent.class,
|
||||||
|
inventoryPreClickEvent -> inventoryPreClickEvent.setCancelled(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.eventNode().addListener(
|
||||||
|
PlayerSwapItemEvent.class,
|
||||||
|
playerSwapItemEvent -> playerSwapItemEvent.setCancelled(true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||||
|
this.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
this.nextRound();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nextRound() {
|
||||||
|
this.generate();
|
||||||
|
do {
|
||||||
|
this.currentBlock = this.blocks.get(ThreadLocalRandom.current().nextInt(this.blocks.size()));
|
||||||
|
} while(this.currentBlock == this.blockLastRound);
|
||||||
|
this.blockLastRound = this.currentBlock;
|
||||||
|
|
||||||
|
ItemStack item = ItemStack.of(Objects.requireNonNull(this.currentBlock.registry().material()));
|
||||||
|
this.getPlayers().forEach(player -> {
|
||||||
|
player.getInventory().clear();
|
||||||
|
for(int i = 0; i < 9; i++) {
|
||||||
|
player.getInventory().setItemStack(i, item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var scheduler = MinecraftServer.getSchedulerManager();
|
||||||
|
TaskSchedule stop = TaskSchedule.stop();
|
||||||
|
|
||||||
|
scheduler.scheduleTask(() -> {
|
||||||
|
if(!this.isRunning) return stop;
|
||||||
|
this.destroyAllExcept(this.currentBlock);
|
||||||
|
|
||||||
|
scheduler.scheduleTask(() -> {
|
||||||
|
if(this.isRunning) this.nextRound();
|
||||||
|
return stop;
|
||||||
|
}, TaskSchedule.seconds(3));
|
||||||
|
return stop;
|
||||||
|
}, TaskSchedule.seconds((long) this.roundTime));
|
||||||
|
this.roundTime = this.roundTime * this.multiplierNextRoundTime;
|
||||||
|
if(this.roundTime <= 1) this.roundTime = 1;
|
||||||
|
|
||||||
|
long totalTicks = (long) (this.roundTime * 20);
|
||||||
|
this.scheduleExpUpdate(scheduler, totalTicks, totalTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleExpUpdate(Scheduler scheduler, long remainingTicks, long totalTicks) {
|
||||||
|
if (!this.isRunning) return;
|
||||||
|
|
||||||
|
if (remainingTicks <= 0) {
|
||||||
|
this.getPlayers().forEach(player -> {
|
||||||
|
player.setExp(0f);
|
||||||
|
player.setLevel(0);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float progress = (float) remainingTicks / totalTicks;
|
||||||
|
|
||||||
|
this.getPlayers().forEach(player -> {
|
||||||
|
player.setExp(progress);
|
||||||
|
player.setLevel((int) Math.ceil(remainingTicks / 20.0));
|
||||||
|
});
|
||||||
|
scheduler.scheduleTask(() -> {
|
||||||
|
this.scheduleExpUpdate(scheduler, remainingTicks -1, totalTicks);
|
||||||
|
return TaskSchedule.stop();
|
||||||
|
}, TaskSchedule.tick(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generate() {
|
||||||
|
int y = 30;
|
||||||
|
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||||
|
|
||||||
|
for (int x = -20; x <= 21; x += 2) {
|
||||||
|
for (int z = -11; z <= 10; z += 2) {
|
||||||
|
Block randomBlock = this.blocks.get(ThreadLocalRandom.current().nextInt(this.blocks.size()));
|
||||||
|
|
||||||
|
for (int dx = 0; dx < 2; dx++) {
|
||||||
|
for (int dz = 0; dz < 2; dz++) {
|
||||||
|
batch.setBlock(x + dx, y, z + dz, randomBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BatchUtil.loadAndApplyBatch(batch, this, () -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void destroyAllExcept(Block block) {
|
||||||
|
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||||
|
int y = 30;
|
||||||
|
|
||||||
|
for (int x = -20; x <= 21; x++) {
|
||||||
|
for(int z = -11; z <= 10; z++) {
|
||||||
|
Pos blockPos = new Pos(x, y, z);
|
||||||
|
if(this.getBlock(blockPos) != block)
|
||||||
|
batch.setBlock(blockPos, Block.AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BatchUtil.loadAndApplyBatch(batch, this, () -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pos getSpawn() {
|
||||||
|
return new Pos(0, 31, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
|
||||||
|
var player = playerMoveEvent.getPlayer();
|
||||||
|
|
||||||
|
if(playerMoveEvent.getNewPosition().y() >= 29)
|
||||||
|
return;
|
||||||
|
player.teleport(this.getSpawn());
|
||||||
|
if(this.isRunning) {
|
||||||
|
this.getScore().insertResult(player);
|
||||||
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.colorJump;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.Game;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.room.Room;
|
||||||
|
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ColorJumpFactory implements GameFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent name() {
|
||||||
|
return TranslatedComponent.byId("game_ColorJump#name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material symbol() {
|
||||||
|
return Material.PINK_CONCRETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent description() {
|
||||||
|
return TranslatedComponent.byId("game_ColorJump#description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
|
return new ColorJump().setParent(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-1
@@ -24,6 +24,7 @@ import net.minestom.server.event.player.PlayerMoveEvent;
|
|||||||
import net.minestom.server.event.player.PlayerStartFlyingWithElytraEvent;
|
import net.minestom.server.event.player.PlayerStartFlyingWithElytraEvent;
|
||||||
import net.minestom.server.event.player.PlayerStopFlyingWithElytraEvent;
|
import net.minestom.server.event.player.PlayerStopFlyingWithElytraEvent;
|
||||||
import net.minestom.server.event.player.PlayerUseItemEvent;
|
import net.minestom.server.event.player.PlayerUseItemEvent;
|
||||||
|
import net.minestom.server.instance.Chunk;
|
||||||
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;
|
||||||
@@ -209,7 +210,16 @@ public class ElytraRace extends StatelessGame {
|
|||||||
point -> batch.setBlock(point, Block.AIR)
|
point -> batch.setBlock(point, Block.AIR)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
int minChunkX = (ringPos.blockX() - 100) >> 4;
|
||||||
|
int maxChunkX = (ringPos.blockX() + 100) >> 4;
|
||||||
|
int chunkZ = ringPos.blockZ() >> 4;
|
||||||
|
|
||||||
BatchUtil.loadAndApplyBatch(batch, this, () -> {
|
BatchUtil.loadAndApplyBatch(batch, this, () -> {
|
||||||
|
for(int cx = minChunkX; cx <= maxChunkX; cx++) {
|
||||||
|
Chunk chunk = this.getChunk(cx, chunkZ);
|
||||||
|
if(chunk == null) continue;
|
||||||
|
this.getPlayers().forEach(chunk::sendChunk);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +239,7 @@ public class ElytraRace extends StatelessGame {
|
|||||||
if(data.currentCheckpoint == 0) checkpointPos = this.getSpawn().add(0, 3, 0);
|
if(data.currentCheckpoint == 0) checkpointPos = this.getSpawn().add(0, 3, 0);
|
||||||
p.setVelocity(Vec.ZERO);
|
p.setVelocity(Vec.ZERO);
|
||||||
p.setFlyingWithElytra(false);
|
p.setFlyingWithElytra(false);
|
||||||
p.teleport(Pos.fromPoint(checkpointPos).add(0.5, 0, 0.5));
|
p.teleport(new Pos(checkpointPos).add(0.5, 0, 0.5));
|
||||||
|
|
||||||
p.setFlying(true);
|
p.setFlying(true);
|
||||||
p.setFlyingSpeed(0);
|
p.setFlyingSpeed(0);
|
||||||
|
|||||||
+10
-1
@@ -8,6 +8,7 @@ import io.github.togar2.pvp.events.EntityKnockbackEvent;
|
|||||||
import io.github.togar2.pvp.events.FinalAttackEvent;
|
import io.github.togar2.pvp.events.FinalAttackEvent;
|
||||||
import io.github.togar2.pvp.events.PrepareAttackEvent;
|
import io.github.togar2.pvp.events.PrepareAttackEvent;
|
||||||
import io.github.togar2.pvp.feature.CombatFeatures;
|
import io.github.togar2.pvp.feature.CombatFeatures;
|
||||||
|
import io.github.togar2.pvp.feature.knockback.KnockbackSettings;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.event.instance.InstanceTickEvent;
|
import net.minestom.server.event.instance.InstanceTickEvent;
|
||||||
@@ -50,7 +51,15 @@ class HighGround extends StatelessGame {
|
|||||||
|
|
||||||
this.eventNode().addListener(
|
this.eventNode().addListener(
|
||||||
EntityKnockbackEvent.class,
|
EntityKnockbackEvent.class,
|
||||||
entityKnockbackEvent -> entityKnockbackEvent.setStrength(1.1f)
|
entityKnockbackEvent -> entityKnockbackEvent.setSettings(
|
||||||
|
KnockbackSettings.builder()
|
||||||
|
.horizontal(1.1)
|
||||||
|
.vertical(KnockbackSettings.DEFAULT.vertical())
|
||||||
|
.verticalLimit(KnockbackSettings.DEFAULT.verticalLimit())
|
||||||
|
.extraHorizontal(KnockbackSettings.DEFAULT.extraHorizontal())
|
||||||
|
.extraVertical(KnockbackSettings.DEFAULT.extraVertical())
|
||||||
|
.build()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.eventNode().addListener(InstanceTickEvent.class, instanceTickEvent -> {
|
this.eventNode().addListener(InstanceTickEvent.class, instanceTickEvent -> {
|
||||||
|
|||||||
+143
@@ -0,0 +1,143 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.pillars;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
|
import eu.mhsl.minenet.minigames.score.LastWinsScore;
|
||||||
|
import eu.mhsl.minenet.minigames.util.Position;
|
||||||
|
import io.github.togar2.pvp.feature.CombatFeatures;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.event.item.ItemDropEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerBlockBreakEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
class Pillars extends StatelessGame {
|
||||||
|
private int spawnPosx = 0;
|
||||||
|
private int spawnPosz = 0;
|
||||||
|
private final int pillarSpacing = 10;
|
||||||
|
private final int pillarRowCount = 5;
|
||||||
|
private final int timeToNextItem = 5;
|
||||||
|
|
||||||
|
private static final Set<String> IGNORED_SUFFIXES = Set.of(
|
||||||
|
"_SWORD", "_PICKAXE", "_AXE", "_SHOVEL", "_HOE",
|
||||||
|
"_HELMET", "_CHESTPLATE", "_LEGGINGS", "_BOOTS",
|
||||||
|
"_BOAT", "_MINECART", "_BUCKET", "_SPAWN_EGG",
|
||||||
|
"_BANNER", "_CANDLE", "_PRESSURE_PLATE", "_TEMPLATE",
|
||||||
|
"_BUTTON", "_HARNESS"
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Set<Material> IGNORED_EXACT = Set.of(
|
||||||
|
Material.BOW, Material.CROSSBOW, Material.TRIDENT, Material.MACE, Material.SHIELD,
|
||||||
|
Material.SHEARS, Material.FLINT_AND_STEEL, Material.FISHING_ROD, Material.SADDLE,
|
||||||
|
Material.TURTLE_HELMET, Material.ELYTRA,
|
||||||
|
Material.LADDER, Material.VINE, Material.SCAFFOLDING, Material.TWISTING_VINES, Material.WEEPING_VINES,
|
||||||
|
Material.BAMBOO_RAFT,
|
||||||
|
Material.TNT, Material.SPAWNER, Material.END_PORTAL_FRAME,
|
||||||
|
Material.COMMAND_BLOCK, Material.CHAIN_COMMAND_BLOCK, Material.REPEATING_COMMAND_BLOCK,
|
||||||
|
Material.STRUCTURE_BLOCK, Material.STRUCTURE_VOID, Material.JIGSAW,
|
||||||
|
Material.BARRIER, Material.LIGHT, Material.DEBUG_STICK, Material.KNOWLEDGE_BOOK,
|
||||||
|
Material.BEDROCK, Material.AIR
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Set<Material> IGNORED_MATERIALS = new HashSet<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (Material material : Material.values()) {
|
||||||
|
String id = material.key().asString();
|
||||||
|
|
||||||
|
for (String suffix : IGNORED_SUFFIXES) {
|
||||||
|
if (id.endsWith(suffix.toLowerCase())) {
|
||||||
|
IGNORED_MATERIALS.add(material);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pillars() {
|
||||||
|
super(Dimension.THE_END.key, "Pillars", new LastWinsScore());
|
||||||
|
this.getScore().setIgnoreLastPlayers(1);
|
||||||
|
|
||||||
|
this.eventNode().addChild(
|
||||||
|
CombatFeatures.empty()
|
||||||
|
.add(CombatFeatures.VANILLA_ATTACK)
|
||||||
|
.add(CombatFeatures.VANILLA_DAMAGE)
|
||||||
|
.add(CombatFeatures.VANILLA_KNOCKBACK)
|
||||||
|
.build().createNode()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onPlayerJoin(Player p) {
|
||||||
|
Pos pos = new Pos(this.spawnPosx * this.pillarSpacing, 100, this.spawnPosz * this.pillarSpacing);
|
||||||
|
this.setBlock(pos.sub(0, 1, 0), Block.BEDROCK);
|
||||||
|
|
||||||
|
if(this.spawnPosx >= this.pillarRowCount) {
|
||||||
|
this.spawnPosx = 0;
|
||||||
|
this.spawnPosz++;
|
||||||
|
}
|
||||||
|
this.spawnPosx++;
|
||||||
|
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> p.teleport(pos.add(0.5, 0, 0.5)));
|
||||||
|
|
||||||
|
return super.onPlayerJoin(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent playerBlockBreakEvent) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onItemDrop(@NotNull ItemDropEvent itemDropEvent) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pos getSpawn() {
|
||||||
|
return new Pos(0, 105, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
|
||||||
|
var player = playerMoveEvent.getPlayer();
|
||||||
|
|
||||||
|
if(this.isBeforeBeginning && Position.hasPositionChanged(player.getPosition(), playerMoveEvent.getNewPosition()))
|
||||||
|
playerMoveEvent.setCancelled(true);
|
||||||
|
|
||||||
|
if(playerMoveEvent.getNewPosition().y() < 80) {
|
||||||
|
this.getScore().insertResult(player);
|
||||||
|
player.teleport(this.getSpawn());
|
||||||
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
this.getPlayers().forEach(player -> player.setGameMode(GameMode.SURVIVAL));
|
||||||
|
|
||||||
|
MinecraftServer.getSchedulerManager().submitTask(() -> {
|
||||||
|
List<Material> materials = Material.values().stream()
|
||||||
|
.filter(material -> !IGNORED_EXACT.contains(material))
|
||||||
|
.filter(material -> !IGNORED_MATERIALS.contains(material))
|
||||||
|
.toList();
|
||||||
|
this.getPlayers().forEach(player -> {
|
||||||
|
ItemStack item = ItemStack.of(materials.get(ThreadLocalRandom.current().nextInt(materials.size())));
|
||||||
|
player.getInventory().addItemStack(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
return TaskSchedule.seconds(this.timeToNextItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.pillars;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.Game;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.room.Room;
|
||||||
|
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PillarsFactory implements GameFactory {
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent name() {
|
||||||
|
return TranslatedComponent.byId("game_Pillars#name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent description() {
|
||||||
|
return TranslatedComponent.byId("game_Pillars#description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material symbol() {
|
||||||
|
return Material.BEDROCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
|
return new Pillars().setParent(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
|
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
|
||||||
|
import eu.mhsl.minenet.minigames.util.BatchUtil;
|
||||||
|
import eu.mhsl.minenet.minigames.util.CommonProperties;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
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 org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class PlayerRace extends StatelessGame {
|
||||||
|
private final int height = 64;
|
||||||
|
private final Map<Player, Double> zLine = new WeakHashMap<>();
|
||||||
|
private final Map<Player, Double> zSpawnPoint = new WeakHashMap<>();
|
||||||
|
private final int obstacleCount;
|
||||||
|
|
||||||
|
public PlayerRace(int obstacleCount) {
|
||||||
|
super(Dimension.THE_END.key, "PlayerRace", new FirstWinsScore());
|
||||||
|
this.setGenerator(new PlayerRaceChunkgenerator(this.height, obstacleCount));
|
||||||
|
this.obstacleCount = obstacleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onPlayerJoin(Player p) {
|
||||||
|
p.setGameMode(GameMode.ADVENTURE);
|
||||||
|
this.zLine.put(p, 32.0);
|
||||||
|
this.zSpawnPoint.put(p, 14.5);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||||
|
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
batch.setBlock(x,this.height + 1, 15, Block.OAK_FENCE.withProperties(CommonProperties.fenceEastWest));
|
||||||
|
}BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
batch.setBlock(x,this.height + 1, 15, Block.AIR);
|
||||||
|
}BatchUtil.loadAndApplyBatch(batch, this, () -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pos getSpawn() {
|
||||||
|
return new Pos(8, this.height + 1.5, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pos getNewSpawn(Player player) {
|
||||||
|
return new Pos(8, this.height + 1.5, this.zSpawnPoint.get(player));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
|
||||||
|
var player = playerMoveEvent.getPlayer();
|
||||||
|
if(playerMoveEvent.getNewPosition().y() < this.height - 5) {
|
||||||
|
player.teleport(this.isBeforeBeginning ? this.getSpawn() : this.getNewSpawn(player));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(playerMoveEvent.getNewPosition().z() >= this.zLine.get(player) && this.isRunning) {
|
||||||
|
this.zLine.merge(player, 19.0, Double::sum);
|
||||||
|
this.zSpawnPoint.merge(player, 19.0, Double::sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(playerMoveEvent.getNewPosition().z() >= 16 + this.obstacleCount * 19 && this.isRunning) {
|
||||||
|
this.getScore().insertResult(player);
|
||||||
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(playerMoveEvent.getNewPosition().z() >= 16 && this.isBeforeBeginning)
|
||||||
|
player.teleport(this.getSpawn());
|
||||||
|
}
|
||||||
|
}
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles.Obstacle;
|
||||||
|
import eu.mhsl.minenet.minigames.util.GeneratorUtils;
|
||||||
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
|
import eu.mhsl.minenet.minigames.world.generator.featureEnriched.ValeGenerator;
|
||||||
|
import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.coordinate.Vec;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
public class PlayerRaceChunkgenerator extends BaseGenerator {
|
||||||
|
private static final int START_LENGTH = 16;
|
||||||
|
private static final int GAP_LENGTH = 3;
|
||||||
|
private static final int PERIOD = Obstacle.LENGTH + GAP_LENGTH;
|
||||||
|
|
||||||
|
public PlayerRaceChunkgenerator(int height, int obstacleCount) {
|
||||||
|
ValeGenerator vale = new ValeGenerator();
|
||||||
|
vale.setXShiftMultiplier(integer -> 0.5d);
|
||||||
|
vale.setHeightNoiseMultiplier(integer -> 2);
|
||||||
|
this.addMixIn(vale);
|
||||||
|
|
||||||
|
int finishStart = START_LENGTH + obstacleCount * PERIOD;
|
||||||
|
int finishEnd = finishStart + 16;
|
||||||
|
|
||||||
|
this.addMixIn(unit -> {
|
||||||
|
Point chunkStart = unit.absoluteStart();
|
||||||
|
if(
|
||||||
|
chunkStart.chunkX() != 0 ||
|
||||||
|
chunkStart.blockZ() + 16 <= 0 ||
|
||||||
|
chunkStart.blockZ() >= finishEnd
|
||||||
|
) return;
|
||||||
|
|
||||||
|
GeneratorUtils.foreachXZ(unit, point -> {
|
||||||
|
Block ground = groundBlockAt(point.blockZ(), finishStart, finishEnd);
|
||||||
|
if(ground != null) unit.modifier().setBlock(point.withY(height), ground);
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int i = 0; i < obstacleCount; i++) {
|
||||||
|
int obstacleZ = START_LENGTH + i * PERIOD;
|
||||||
|
if(obstacleZ < chunkStart.blockZ() || obstacleZ >= chunkStart.blockZ() + 16) continue;
|
||||||
|
|
||||||
|
GenerationUnit fork = unit.fork(
|
||||||
|
new Vec(chunkStart.blockX(), height - 8, obstacleZ),
|
||||||
|
new Vec(chunkStart.blockX() + 16, height + 16, obstacleZ + Obstacle.LENGTH)
|
||||||
|
);
|
||||||
|
Obstacle.getRandomObstacle().generate(fork, new Vec(chunkStart.blockX(), height, obstacleZ));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Block groundBlockAt(int z, int finishStart, int finishEnd) {
|
||||||
|
if(z < 0 || z >= finishEnd) return null;
|
||||||
|
if(z < START_LENGTH) return BlockPallet.GROUND.rnd();
|
||||||
|
if(z >= finishStart) return Block.DIAMOND_BLOCK;
|
||||||
|
|
||||||
|
int relative = (z - START_LENGTH) % PERIOD;
|
||||||
|
return relative >= Obstacle.LENGTH ? BlockPallet.GROUND.rnd() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace;
|
||||||
|
|
||||||
|
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 PlayerRaceFactory implements GameFactory {
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent name() {
|
||||||
|
return TranslatedComponent.byId("game_PlayerRace#name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigManager configuration() {
|
||||||
|
return new ConfigManager()
|
||||||
|
.addOption(new NumericOption("length", Material.RAIL, TranslatedComponent.byId("optionCommon#length"), 8, 12, 16, 20));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
|
return new PlayerRace(configuration.get("length").getAsInt()).setParent(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material symbol() {
|
||||||
|
return Material.DIRT_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent description() {
|
||||||
|
return TranslatedComponent.byId("game_PlayerRace#description");
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class BambooThicket extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(3) == 0 ? Block.PODZOL : Block.GRASS_BLOCK);
|
||||||
|
|
||||||
|
int z = relZ(point, start);
|
||||||
|
if(z < 2 || z > 13 || rnd.nextInt(100) >= 45) return;
|
||||||
|
|
||||||
|
int height = 3 + rnd.nextInt(3);
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
String leaves = y == height ? "large" : y == height - 1 ? "small" : "none";
|
||||||
|
unit.modifier().setBlock(
|
||||||
|
point.withY(start.blockY() + y),
|
||||||
|
Block.BAMBOO.withProperty("age", "1").withProperty("leaves", leaves)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.generators.noisegen.perlin.PerlinNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class BasaltPillars extends Obstacle {
|
||||||
|
private final JNoise ground = JNoise.newBuilder()
|
||||||
|
.perlin(PerlinNoiseGenerator.newBuilder().build())
|
||||||
|
.scale(0.13)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
double noise = this.ground.evaluateNoise(point.blockX(), point.blockZ());
|
||||||
|
Block floor = noise > 0.4 ? Block.SOUL_SOIL : noise < -0.4 ? Block.BASALT : Block.BLACKSTONE;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int i = 0; i < 16; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
int height = 2 + rnd.nextInt(3);
|
||||||
|
boolean thick = rnd.nextInt(3) == 0 && x < 15;
|
||||||
|
Block pillar = rnd.nextInt(3) == 0 ? Block.POLISHED_BASALT : Block.BASALT;
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
unit.modifier().setBlock(start.add(x, y, z), pillar);
|
||||||
|
if(thick) {
|
||||||
|
unit.modifier().setBlock(start.add(x + 1, y, z), pillar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(rnd.nextInt(3) == 0) {
|
||||||
|
unit.modifier().setBlock(start.add(x, height + 1, z), Block.SOUL_LANTERN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class BerryPatch extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int z = relZ(point, start);
|
||||||
|
int pathX = 7 + (int) Math.round(5 * Math.sin(z * Math.PI / 7.5));
|
||||||
|
boolean onPath = relX(point, start) == pathX || relX(point, start) == pathX + 1;
|
||||||
|
boolean overgrown = z == 8;
|
||||||
|
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), onPath ? Block.DIRT_PATH : Block.GRASS_BLOCK);
|
||||||
|
|
||||||
|
boolean bush = onPath ? overgrown : z >= 1 && z <= 14 && rnd.nextInt(100) < 45;
|
||||||
|
if(bush) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.SWEET_BERRY_BUSH.withProperty("age", "3"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class BoulderTrench extends Obstacle {
|
||||||
|
private static final int[] DEPTHS = {0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int depth = DEPTHS[relZ(point, start)];
|
||||||
|
for(int y = start.blockY() - 2; y < start.blockY() - depth; y++) {
|
||||||
|
unit.modifier().setBlock(point.withY(y), Block.STONE);
|
||||||
|
}
|
||||||
|
Block floor = depth == 0
|
||||||
|
? Block.GRASS_BLOCK
|
||||||
|
: rnd.nextBoolean() ? Block.COARSE_DIRT : Block.GRAVEL;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - depth), floor);
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int i = 0; i < 10; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 6 + rnd.nextInt(4);
|
||||||
|
unit.modifier().setBlock(start.add(x, -1, z), rnd.nextBoolean() ? Block.MOSSY_COBBLESTONE : Block.COBBLESTONE);
|
||||||
|
if(rnd.nextInt(3) == 0) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 0, z), Block.MOSSY_COBBLESTONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
unit.modifier().setBlock(start.add(rnd.nextInt(16), -1, 6 + rnd.nextInt(4)), Block.COBWEB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+65
@@ -0,0 +1,65 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class ChorusGrove extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
Block floor = rnd.nextInt(14) == 0 ? Block.PURPUR_BLOCK : Block.END_STONE;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
});
|
||||||
|
|
||||||
|
int[] rows = {5, 10};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 1 + rnd.nextInt(4) : 10 + rnd.nextInt(4);
|
||||||
|
|
||||||
|
boolean[] hasWall = new boolean[16];
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
hasWall[x] = x < gapStart || x >= gapStart + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(!hasWall[x]) continue;
|
||||||
|
boolean westConnected = x > 0 && hasWall[x - 1];
|
||||||
|
boolean eastConnected = x < 15 && hasWall[x + 1];
|
||||||
|
Block wall = Block.END_STONE_BRICK_WALL
|
||||||
|
.withProperty("west", westConnected ? "low" : "none")
|
||||||
|
.withProperty("east", eastConnected ? "low" : "none")
|
||||||
|
.withProperty("up", String.valueOf(!westConnected || !eastConnected || x % 4 == 0));
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), wall);
|
||||||
|
|
||||||
|
if(rnd.nextInt(6) == 0) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, rows[i]), Block.END_ROD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 15; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
if(z == 5 || z == 10) continue;
|
||||||
|
int height = 1 + rnd.nextInt(3);
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
unit.modifier().setBlock(start.add(x, y, z), Block.CHORUS_PLANT);
|
||||||
|
}
|
||||||
|
unit.modifier().setBlock(start.add(x, height + 1, z), Block.CHORUS_FLOWER.withProperty("age", "5"));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
if(z == 5 || z == 10) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, z), Block.PURPUR_BLOCK);
|
||||||
|
if(rnd.nextBoolean()) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, z), Block.PURPUR_BLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.generators.noisegen.perlin.PerlinNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class CobwebGrove extends Obstacle {
|
||||||
|
private final JNoise soil = JNoise.newBuilder()
|
||||||
|
.perlin(PerlinNoiseGenerator.newBuilder().build())
|
||||||
|
.scale(0.12)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
Block floor = this.soil.evaluateNoise(point.blockX(), point.blockZ()) > 0 ? Block.PODZOL : Block.COARSE_DIRT;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
|
||||||
|
int z = relZ(point, start);
|
||||||
|
if(z < 2 || z > 13) return;
|
||||||
|
|
||||||
|
int roll = rnd.nextInt(100);
|
||||||
|
if(roll < 28) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.COBWEB);
|
||||||
|
if(roll < 8) unit.modifier().setBlock(point.withY(start.blockY() + 2), Block.COBWEB);
|
||||||
|
} else if(roll < 36) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.FERN);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 3 + rnd.nextInt(10);
|
||||||
|
int height = 1 + rnd.nextInt(2);
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
unit.modifier().setBlock(start.add(x, y, z), Block.SPRUCE_LOG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class DripstoneSpikes extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point ->
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(6) == 0 ? Block.STONE : Block.DRIPSTONE_BLOCK));
|
||||||
|
|
||||||
|
int[] rows = {4, 8, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 2 + rnd.nextInt(4) : 9 + rnd.nextInt(4);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(x >= gapStart && x < gapStart + 2) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), Block.DRIPSTONE_BLOCK);
|
||||||
|
this.placeSpike(unit, start.add(0, 1, 0), x, rows[i], 1 + rnd.nextInt(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 12; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
if(z == 4 || z == 8 || z == 12) continue;
|
||||||
|
this.placeSpike(unit, start, x, z, 1 + rnd.nextInt(3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void placeSpike(GenerationUnit unit, Point start, int x, int z, int height) {
|
||||||
|
for(int y = 1; y <= height; y++) {
|
||||||
|
String thickness = y == height ? "tip" : y == height - 1 ? "frustum" : "base";
|
||||||
|
unit.modifier().setBlock(
|
||||||
|
start.add(x, y, z),
|
||||||
|
Block.POINTED_DRIPSTONE
|
||||||
|
.withProperty("thickness", thickness)
|
||||||
|
.withProperty("vertical_direction", "up")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class GlassPaneWeave extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point ->
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(5) == 0 ? Block.CALCITE : Block.QUARTZ_BLOCK));
|
||||||
|
|
||||||
|
int[] rows = {4, 8, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 2 + rnd.nextInt(3) : 11 + rnd.nextInt(3);
|
||||||
|
|
||||||
|
boolean[] hasPane = new boolean[16];
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
hasPane[x] = x < gapStart || x >= gapStart + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(!hasPane[x]) continue;
|
||||||
|
Block pane = (rnd.nextInt(6) == 0 ? Block.GRAY_STAINED_GLASS_PANE : Block.WHITE_STAINED_GLASS_PANE)
|
||||||
|
.withProperty("west", String.valueOf(x > 0 && hasPane[x - 1]))
|
||||||
|
.withProperty("east", String.valueOf(x < 15 && hasPane[x + 1]));
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), pane);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, rows[i]), pane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class HayHurdles extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), Block.GRASS_BLOCK);
|
||||||
|
if(relZ(point, start) % 3 != 0 && rnd.nextInt(8) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.SHORT_GRASS);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int[] rows = {3, 6, 9, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
boolean tall = i % 2 == 1;
|
||||||
|
int gapStart = rnd.nextInt(14);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(tall && (x == gapStart || x == gapStart + 1)) continue;
|
||||||
|
Block block = rnd.nextInt(12) == 0 ? Block.CARVED_PUMPKIN : Block.HAY_BLOCK;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), block);
|
||||||
|
if(tall) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, rows[i]), Block.HAY_BLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.generators.noisegen.perlin.PerlinNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class HoneyField extends Obstacle {
|
||||||
|
private final JNoise sticky = JNoise.newBuilder()
|
||||||
|
.perlin(PerlinNoiseGenerator.newBuilder().build())
|
||||||
|
.scale(0.2)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
boolean stickyFloor = this.sticky.evaluateNoise(point.blockX(), point.blockZ()) > 0.35;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), stickyFloor ? Block.HONEY_BLOCK : Block.HONEYCOMB_BLOCK);
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int wallZ : new int[]{5, 10}) {
|
||||||
|
int gapStart = wallZ == 5 ? 1 + rnd.nextInt(5) : 8 + rnd.nextInt(5);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(x >= gapStart && x < gapStart + 2) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, wallZ), Block.HONEY_BLOCK);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, wallZ), Block.HONEY_BLOCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.generators.noisegen.perlin.PerlinNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class IceRink extends Obstacle {
|
||||||
|
private final JNoise streaks = JNoise.newBuilder()
|
||||||
|
.perlin(PerlinNoiseGenerator.newBuilder().build())
|
||||||
|
.scale(0.15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
double noise = this.streaks.evaluateNoise(point.blockX(), point.blockZ());
|
||||||
|
Block floor = noise > 0.45 ? Block.BLUE_ICE : noise < -0.55 ? Block.ICE : Block.PACKED_ICE;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
|
||||||
|
if(relZ(point, start) >= 2 && relZ(point, start) <= 13 && rnd.nextInt(14) == 0) {
|
||||||
|
unit.modifier().setBlock(
|
||||||
|
point.withY(start.blockY() + 1),
|
||||||
|
Block.SNOW.withProperty("layers", String.valueOf(1 + rnd.nextInt(2)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int wallZ : new int[]{5, 10}) {
|
||||||
|
int gapStart = wallZ == 5 ? 1 + rnd.nextInt(4) : 9 + rnd.nextInt(4);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(x >= gapStart && x < gapStart + 3) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, wallZ), Block.PACKED_ICE);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, wallZ), Block.ICE);
|
||||||
|
if(rnd.nextInt(4) == 0) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 3, wallZ), Block.SNOW.withProperty("layers", "1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 5; i++) {
|
||||||
|
int x = rnd.nextInt(16);
|
||||||
|
int z = 2 + rnd.nextInt(12);
|
||||||
|
if(z == 5 || z == 10) continue;
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, z), Block.PACKED_ICE);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, z), Block.SNOW.withProperty("layers", "1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class LadderWall extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point ->
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), BlockPallet.STONE.rnd()));
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
boolean hasLadder = rnd.nextInt(3) != 0;
|
||||||
|
for(int y = 1; y <= 3; y++) {
|
||||||
|
for(int z = 7; z <= 8; z++) {
|
||||||
|
Block block = rnd.nextInt(3) == 0 ? Block.MOSSY_STONE_BRICKS : Block.STONE_BRICKS;
|
||||||
|
unit.modifier().setBlock(start.add(x, y, z), block);
|
||||||
|
}
|
||||||
|
if(hasLadder) {
|
||||||
|
unit.modifier().setBlock(start.add(x, y, 6), Block.LADDER.withProperty("facing", "north"));
|
||||||
|
}
|
||||||
|
unit.modifier().setBlock(start.add(x, y, 9), Block.LADDER.withProperty("facing", "south"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x % 5 == 2) {
|
||||||
|
unit.modifier().setBlock(start.add(x, 4, 7), Block.LANTERN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
class LadderWall2 extends Obstacle{
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
forEachColumn(start, point ->
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), BlockPallet.STREET.rnd()));
|
||||||
|
|
||||||
|
this.buildWall(unit, start,4, 4, false);
|
||||||
|
this.buildWall(unit, start,10, 8, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildWall(GenerationUnit unit, Point start, int z, int height, boolean lastRow) {
|
||||||
|
Random random = new Random();
|
||||||
|
int y = 1;
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
for(int wy = 0; wy <= height; wy++) {
|
||||||
|
unit.modifier().setBlock(start.add(x, y + wy, z), BlockPallet.STONE.rnd());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int wy = lastRow ? 2 : 0; wy <= height; wy++) {
|
||||||
|
|
||||||
|
Set<Integer> noLadder = new HashSet<>();
|
||||||
|
for(int i = 0; i < 5; i++) {
|
||||||
|
noLadder.add(random.nextInt(16));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(!noLadder.contains(x))
|
||||||
|
unit.modifier().setBlock(start.add(x, y + wy, z - 1), Block.LADDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!lastRow) {
|
||||||
|
for(int x = 7; x < 9; x++) {
|
||||||
|
unit.modifier().setBlock(start.add(x, y + wy, z + 1), Block.LADDER.withProperty("facing", "south"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class LeafHedges extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), Block.GRASS_BLOCK);
|
||||||
|
int z = relZ(point, start);
|
||||||
|
if(z % 4 != 0 && z >= 1 && z <= 14 && rnd.nextInt(10) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), BlockPallet.FLOWER.rnd());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int[] rows = {4, 8, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 11 + rnd.nextInt(3) : 1 + rnd.nextInt(3);
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(x >= gapStart && x < gapStart + 2) continue;
|
||||||
|
Block leaves = (rnd.nextInt(10) < 3 ? Block.FLOWERING_AZALEA_LEAVES : Block.AZALEA_LEAVES)
|
||||||
|
.withProperty("persistent", "true");
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), leaves);
|
||||||
|
unit.modifier().setBlock(start.add(x, 2, rows[i]), leaves);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.generators.noisegen.perlin.PerlinNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class MudPools extends Obstacle {
|
||||||
|
private final JNoise pools = JNoise.newBuilder()
|
||||||
|
.perlin(PerlinNoiseGenerator.newBuilder().build())
|
||||||
|
.scale(0.11)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int z = relZ(point, start);
|
||||||
|
double noise = this.pools.evaluateNoise(point.blockX(), point.blockZ());
|
||||||
|
boolean pool = z >= 1 && z <= 14 && noise > 0.05;
|
||||||
|
|
||||||
|
if(pool) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - 1), Block.MUD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block floor = noise > -0.3 ? Block.MUDDY_MANGROVE_ROOTS : Block.GRASS_BLOCK;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - 1), Block.MUD);
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), floor);
|
||||||
|
|
||||||
|
if(z >= 2 && z <= 13 && rnd.nextInt(6) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.MANGROVE_ROOTS);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.generators.noisegen.perlin.PerlinNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
class Mudpit extends Obstacle {
|
||||||
|
private final JNoise curves = JNoise.newBuilder()
|
||||||
|
.perlin(PerlinNoiseGenerator.newBuilder().build())
|
||||||
|
.scale(0.1)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
double relative = relZ(point, start);
|
||||||
|
double modifier = -1.5 * Math.cos(relative * Math.PI/7.5) + 1.5;
|
||||||
|
double heightAtBlock = start.blockY() + this.curves.evaluateNoise(point.blockX(), point.blockZ()) * modifier;
|
||||||
|
unit.modifier().setBlock(point.withY(heightAtBlock), Block.SOUL_SAND);
|
||||||
|
unit.modifier().setBlock(point.withY(heightAtBlock-1), Block.SOUL_SAND);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class MushroomRoofs extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), Block.MYCELIUM);
|
||||||
|
int z = relZ(point, start);
|
||||||
|
if(z >= 1 && z <= 14 && rnd.nextInt(20) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), rnd.nextBoolean() ? Block.RED_MUSHROOM : Block.BROWN_MUSHROOM);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for(int stemZ : new int[]{4, 8, 12}) {
|
||||||
|
int x = 4 + rnd.nextInt(8);
|
||||||
|
Block cap = rnd.nextBoolean() ? Block.RED_MUSHROOM_BLOCK : Block.BROWN_MUSHROOM_BLOCK;
|
||||||
|
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, stemZ), Block.MUSHROOM_STEM);
|
||||||
|
|
||||||
|
for(int capX = x - 3; capX <= x + 3; capX++) {
|
||||||
|
for(int capZ = stemZ - 1; capZ <= stemZ + 1; capZ++) {
|
||||||
|
if(capX < 0 || capX > 15 || capZ < 0 || capZ > 15) continue;
|
||||||
|
if(Math.abs(capX - x) == 3 && Math.abs(capZ - stemZ) == 1) continue;
|
||||||
|
unit.modifier().setBlock(start.add(capX, 2, capZ), cap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.util.GeneratorUtils;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public abstract class Obstacle {
|
||||||
|
public static final int LENGTH = 16;
|
||||||
|
|
||||||
|
@SuppressWarnings("StaticInitializerReferencesSubClass")
|
||||||
|
private static final List<Obstacle> obstacles = List.of(
|
||||||
|
new Mudpit(),
|
||||||
|
new IceRink(),
|
||||||
|
new HoneyField(),
|
||||||
|
new CobwebGrove(),
|
||||||
|
new BerryPatch(),
|
||||||
|
new WaterChannel(),
|
||||||
|
new HayHurdles(),
|
||||||
|
new SlimePatches(),
|
||||||
|
new MudPools(),
|
||||||
|
new PowderSnowField(),
|
||||||
|
new DripstoneSpikes(),
|
||||||
|
new ChorusGrove(),
|
||||||
|
new BasaltPillars(),
|
||||||
|
new WallSlalom(),
|
||||||
|
new LeafHedges(),
|
||||||
|
new MushroomRoofs(),
|
||||||
|
new SandDunes(),
|
||||||
|
new LadderWall(),
|
||||||
|
new LadderWall2(),
|
||||||
|
new GlassPaneWeave(),
|
||||||
|
new BoulderTrench(),
|
||||||
|
new BambooThicket()
|
||||||
|
);
|
||||||
|
|
||||||
|
public abstract void generate(GenerationUnit unit, Point start);
|
||||||
|
|
||||||
|
private static final List<Obstacle> remaining = new ArrayList<>();
|
||||||
|
|
||||||
|
public static synchronized Obstacle getRandomObstacle() {
|
||||||
|
if(remaining.isEmpty()) {
|
||||||
|
remaining.addAll(obstacles);
|
||||||
|
}
|
||||||
|
int index = ThreadLocalRandom.current().nextInt(remaining.size());
|
||||||
|
return remaining.remove(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void forEachColumn(Point start, Consumer<Point> callback) {
|
||||||
|
GeneratorUtils.foreachXZ(start, start.add(15, 0, LENGTH - 1), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int relX(Point point, Point start) {
|
||||||
|
return point.blockX() - start.blockX();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int relZ(Point point, Point start) {
|
||||||
|
return point.blockZ() - start.blockZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Random seededRandom(Point start) {
|
||||||
|
return new Random(start.blockX() * 341873128712L + start.blockZ() * 132897987541L);
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.generators.noisegen.perlin.PerlinNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class PowderSnowField extends Obstacle {
|
||||||
|
private final JNoise drifts = JNoise.newBuilder()
|
||||||
|
.perlin(PerlinNoiseGenerator.newBuilder().build())
|
||||||
|
.scale(0.14)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int z = relZ(point, start);
|
||||||
|
int laneX = 7 + (int) Math.round(3 * Math.sin(z * Math.PI / 7.5));
|
||||||
|
boolean onLane = relX(point, start) == laneX || relX(point, start) == laneX + 1;
|
||||||
|
double noise = this.drifts.evaluateNoise(point.blockX(), point.blockZ());
|
||||||
|
boolean drift = z >= 2 && z <= 13 && noise > (onLane ? 0.45 : 0.0);
|
||||||
|
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), onLane ? Block.PACKED_ICE : Block.SNOW_BLOCK);
|
||||||
|
|
||||||
|
if(drift) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.POWDER_SNOW);
|
||||||
|
if(noise > 0.6) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 2), Block.POWDER_SNOW);
|
||||||
|
}
|
||||||
|
} else if(!onLane && rnd.nextInt(6) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.SNOW.withProperty("layers", "1"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.generators.noisegen.perlin.PerlinNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class SandDunes extends Obstacle {
|
||||||
|
private final JNoise dunes = JNoise.newBuilder()
|
||||||
|
.perlin(PerlinNoiseGenerator.newBuilder().build())
|
||||||
|
.scale(0.08)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
double taper = -1.25 * Math.cos(relZ(point, start) * Math.PI / 7.5) + 1.25;
|
||||||
|
double noise = (this.dunes.evaluateNoise(point.blockX(), point.blockZ()) + 1) / 2;
|
||||||
|
int top = start.blockY() + (int) Math.round(noise * taper);
|
||||||
|
|
||||||
|
for(int y = start.blockY() - 1; y < top; y++) {
|
||||||
|
unit.modifier().setBlock(point.withY(y), Block.SANDSTONE);
|
||||||
|
}
|
||||||
|
unit.modifier().setBlock(point.withY(top), Block.SAND);
|
||||||
|
|
||||||
|
if(top > start.blockY() + 1 && rnd.nextInt(14) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(top + 1), Block.DEAD_BUSH);
|
||||||
|
} else if(top == start.blockY() && relZ(point, start) >= 2 && relZ(point, start) <= 13 && rnd.nextInt(22) == 0) {
|
||||||
|
int cactusHeight = 1 + rnd.nextInt(2);
|
||||||
|
for(int y = 1; y <= cactusHeight; y++) {
|
||||||
|
unit.modifier().setBlock(point.withY(top + y), Block.CACTUS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import de.articdive.jnoise.generators.noisegen.perlin.PerlinNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class SlimePatches extends Obstacle {
|
||||||
|
private final JNoise blobs = JNoise.newBuilder()
|
||||||
|
.perlin(PerlinNoiseGenerator.newBuilder().build())
|
||||||
|
.scale(0.18)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int z = relZ(point, start);
|
||||||
|
boolean slime = z >= 1 && z <= 14 && this.blobs.evaluateNoise(point.blockX(), point.blockZ()) > -0.2;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), slime ? Block.SLIME_BLOCK : Block.MOSS_BLOCK);
|
||||||
|
|
||||||
|
if(!slime && z >= 2 && z <= 13 && rnd.nextInt(18) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.AZALEA);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class WallSlalom extends Obstacle {
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point ->
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(4) == 0 ? Block.ANDESITE : Block.STONE));
|
||||||
|
|
||||||
|
int[] rows = {4, 8, 12};
|
||||||
|
for(int i = 0; i < rows.length; i++) {
|
||||||
|
int gapStart = i % 2 == 0 ? 1 + rnd.nextInt(3) : 10 + rnd.nextInt(3);
|
||||||
|
|
||||||
|
boolean[] hasWall = new boolean[16];
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
hasWall[x] = x < gapStart || x >= gapStart + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = 0; x < 16; x++) {
|
||||||
|
if(!hasWall[x]) continue;
|
||||||
|
boolean westConnected = x > 0 && hasWall[x - 1];
|
||||||
|
boolean eastConnected = x < 15 && hasWall[x + 1];
|
||||||
|
Block wall = Block.STONE_BRICK_WALL
|
||||||
|
.withProperty("west", westConnected ? "low" : "none")
|
||||||
|
.withProperty("east", eastConnected ? "low" : "none")
|
||||||
|
.withProperty("up", String.valueOf(!westConnected || !eastConnected || x % 4 == 0));
|
||||||
|
unit.modifier().setBlock(start.add(x, 1, rows[i]), wall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.playerRace.obstacles;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Point;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.instance.generator.GenerationUnit;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
class WaterChannel extends Obstacle {
|
||||||
|
private static final int[] DEPTHS = {0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, 0};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GenerationUnit unit, Point start) {
|
||||||
|
Random rnd = seededRandom(start);
|
||||||
|
|
||||||
|
forEachColumn(start, point -> {
|
||||||
|
int depth = DEPTHS[relZ(point, start)];
|
||||||
|
if(depth == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY()), rnd.nextInt(3) == 0 ? Block.SMOOTH_SANDSTONE : Block.SAND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block bottom = rnd.nextInt(5) == 0 ? Block.DARK_PRISMARINE : Block.PRISMARINE;
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - depth), bottom);
|
||||||
|
for(int y = start.blockY() - depth + 1; y <= start.blockY(); y++) {
|
||||||
|
unit.modifier().setBlock(point.withY(y), Block.WATER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(depth >= 2 && rnd.nextInt(4) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() - depth + 1), Block.SEAGRASS);
|
||||||
|
}
|
||||||
|
if(rnd.nextInt(20) == 0) {
|
||||||
|
unit.modifier().setBlock(point.withY(start.blockY() + 1), Block.LILY_PAD);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -125,7 +125,7 @@ public class SpaceSnake extends StatelessGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PlayState state = this.playerStates.get(playerBlockPlaceEvent.getPlayer());
|
PlayState state = this.playerStates.get(playerBlockPlaceEvent.getPlayer());
|
||||||
state.blocks.add(playerBlockPlaceEvent.getBlockPosition().asVec().asPosition());
|
state.blocks.add(new Pos(playerBlockPlaceEvent.getBlockPosition()));
|
||||||
state.cutToLength(pos -> this.setBlock(pos, Block.AIR));
|
state.cutToLength(pos -> this.setBlock(pos, Block.AIR));
|
||||||
|
|
||||||
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> this.updateInv(playerBlockPlaceEvent.getPlayer()));
|
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> this.updateInv(playerBlockPlaceEvent.getPlayer()));
|
||||||
|
|||||||
+3
-2
@@ -28,7 +28,8 @@ public class StickFightFactory implements GameFactory {
|
|||||||
@Override
|
@Override
|
||||||
public ConfigManager configuration() {
|
public ConfigManager configuration() {
|
||||||
return new ConfigManager()
|
return new ConfigManager()
|
||||||
.addOption(new NumericOption("length", Material.SANDSTONE, TranslatedComponent.byId("optionCommon#length"), 7, 10, 13, 16, 19));
|
.addOption(new NumericOption("length", Material.SANDSTONE, TranslatedComponent.byId("optionCommon#length"), 7, 10, 13, 16, 19))
|
||||||
|
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 30, 60, 90, 120));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -40,7 +41,7 @@ public class StickFightFactory implements GameFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
|
||||||
return new Stickfight(configuration.get("length").getAsInt()).setParent(parent);
|
return new Stickfight(configuration.get("length").getAsInt(), configuration.get("seconds").getAsInt()).setParent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+8
-1
@@ -24,10 +24,12 @@ public class Stickfight extends StatelessGame {
|
|||||||
private final WeakHashMap<Player, Pos> spawnPoints = new WeakHashMap<>();
|
private final WeakHashMap<Player, Pos> spawnPoints = new WeakHashMap<>();
|
||||||
private final Map<Player, Integer> scoreMap = new WeakHashMap<>();
|
private final Map<Player, Integer> scoreMap = new WeakHashMap<>();
|
||||||
private boolean countdownStarted = false;
|
private boolean countdownStarted = false;
|
||||||
|
private final int seconds;
|
||||||
|
|
||||||
public Stickfight(int length) {
|
public Stickfight(int length, int seconds) {
|
||||||
super(Dimension.OVERWORLD.key, "Stickfight", new LowestPointsWinScore());
|
super(Dimension.OVERWORLD.key, "Stickfight", new LowestPointsWinScore());
|
||||||
this.radius = length;
|
this.radius = length;
|
||||||
|
this.seconds = seconds;
|
||||||
|
|
||||||
this.eventNode().addChild(
|
this.eventNode().addChild(
|
||||||
CombatFeatures.empty()
|
CombatFeatures.empty()
|
||||||
@@ -88,6 +90,11 @@ public class Stickfight extends StatelessGame {
|
|||||||
super.start();
|
super.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
this.setTimeLimit(this.seconds);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
this.scoreMap.forEach((player, score) -> this.getScore().insertResult(player, score));
|
this.scoreMap.forEach((player, score) -> this.getScore().insertResult(player, score));
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ public class Sumo extends StatelessGame {
|
|||||||
super(Dimension.OVERWORLD.key, "Sumo", new LastWinsScore());
|
super(Dimension.OVERWORLD.key, "Sumo", new LastWinsScore());
|
||||||
this.getScore().setIgnoreLastPlayers(1);
|
this.getScore().setIgnoreLastPlayers(1);
|
||||||
this.setTime(6000);
|
this.setTime(6000);
|
||||||
this.setTimeRate(0);
|
this.defaultClock().pause();
|
||||||
|
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
this.health = health;
|
this.health = health;
|
||||||
|
|||||||
+30
-32
@@ -6,18 +6,20 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.Tetri
|
|||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.Tetromino;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.Tetromino;
|
||||||
import eu.mhsl.minenet.minigames.score.PointsWinScore;
|
import eu.mhsl.minenet.minigames.score.PointsWinScore;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.entity.Entity;
|
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.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.entity.metadata.display.BlockDisplayMeta;
|
||||||
import net.minestom.server.event.player.PlayerHandAnimationEvent;
|
import net.minestom.server.event.player.PlayerHandAnimationEvent;
|
||||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
|
||||||
import net.minestom.server.event.player.PlayerTickEvent;
|
import net.minestom.server.event.player.PlayerTickEvent;
|
||||||
import net.minestom.server.event.player.PlayerUseItemEvent;
|
import net.minestom.server.event.player.PlayerUseItemEvent;
|
||||||
|
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.potion.Potion;
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
import net.minestom.server.potion.PotionEffect;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -78,18 +80,24 @@ class Tetris extends StatelessGame {
|
|||||||
p.setGameMode(GameMode.SURVIVAL);
|
p.setGameMode(GameMode.SURVIVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void onPlayerInteract(@NotNull PlayerUseItemEvent event) {
|
||||||
protected void onPlayerMove(@NotNull PlayerMoveEvent event) {
|
event.setItemUseTime(0);
|
||||||
|
this.tetrisGames.get(event.getPlayer()).pressedButton(TetrisGame.Button.mouseRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onPlayerAttack(@NotNull PlayerHandAnimationEvent event) {
|
||||||
|
this.tetrisGames.get(event.getPlayer()).pressedButton(TetrisGame.Button.mouseLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onPlayerTick(PlayerTickEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
Pos currentPosition = event.getNewPosition();
|
|
||||||
|
|
||||||
TetrisGame tetrisGame = this.tetrisGames.get(player);
|
TetrisGame tetrisGame = this.tetrisGames.get(player);
|
||||||
|
if(tetrisGame == null) return;
|
||||||
if(tetrisGame == null) {
|
if(tetrisGame.lost) {
|
||||||
event.setCancelled(true);
|
this.letPlayerLoose(player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(tetrisGame.lost) return;
|
|
||||||
if(player.getGameMode() == GameMode.SPECTATOR) return;
|
if(player.getGameMode() == GameMode.SPECTATOR) return;
|
||||||
|
|
||||||
if(player.inputs().forward()) tetrisGame.pressedButton(TetrisGame.Button.W);
|
if(player.inputs().forward()) tetrisGame.pressedButton(TetrisGame.Button.W);
|
||||||
@@ -97,26 +105,6 @@ class Tetris extends StatelessGame {
|
|||||||
if(player.inputs().right()) tetrisGame.pressedButton(TetrisGame.Button.D);
|
if(player.inputs().right()) tetrisGame.pressedButton(TetrisGame.Button.D);
|
||||||
if(player.inputs().left()) tetrisGame.pressedButton(TetrisGame.Button.A);
|
if(player.inputs().left()) tetrisGame.pressedButton(TetrisGame.Button.A);
|
||||||
if(player.inputs().jump()) tetrisGame.pressedButton(TetrisGame.Button.space);
|
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) {
|
private void letPlayerLoose(Player player) {
|
||||||
@@ -124,6 +112,7 @@ class Tetris extends StatelessGame {
|
|||||||
if(!this.getScore().hasResult(player)) {
|
if(!this.getScore().hasResult(player)) {
|
||||||
player.setGameMode(GameMode.SPECTATOR);
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
player.setInvisible(true);
|
player.setInvisible(true);
|
||||||
|
if(player.getVehicle() != null) player.getVehicle().removePassenger(player);
|
||||||
this.getScore().insertResult(player, tetrisGame.getScore());
|
this.getScore().insertResult(player, tetrisGame.getScore());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +149,16 @@ class Tetris extends StatelessGame {
|
|||||||
|
|
||||||
p.teleport(tetrisGame.getPlayerSpawnPosition());
|
p.teleport(tetrisGame.getPlayerSpawnPosition());
|
||||||
tetrisGame.sidebar.addViewer(p);
|
tetrisGame.sidebar.addViewer(p);
|
||||||
p.addEffect(new Potion(PotionEffect.SLOWNESS, 4, Potion.INFINITE_DURATION));
|
|
||||||
|
MinecraftServer.getSchedulerManager().scheduleTask(() -> {
|
||||||
|
Entity ghostBlock = new Entity(EntityType.BLOCK_DISPLAY);
|
||||||
|
((BlockDisplayMeta) ghostBlock.getEntityMeta()).setBlockState(Block.AIR);
|
||||||
|
ghostBlock.setNoGravity(true);
|
||||||
|
ghostBlock.setInstance(this, tetrisGame.getPlayerSpawnPosition());
|
||||||
|
ghostBlock.addPassenger(p);
|
||||||
|
return TaskSchedule.stop();
|
||||||
|
}, TaskSchedule.nextTick());
|
||||||
|
|
||||||
|
|
||||||
return super.onPlayerJoin(p);
|
return super.onPlayerJoin(p);
|
||||||
}
|
}
|
||||||
|
|||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
|
||||||
|
|
||||||
|
public enum Orientation {
|
||||||
|
NONE,
|
||||||
|
RIGHT,
|
||||||
|
LEFT,
|
||||||
|
UPSIDE_DOWN;
|
||||||
|
|
||||||
|
public Orientation rotated(boolean clockwise) {
|
||||||
|
return switch(this) {
|
||||||
|
case NONE -> clockwise ? Orientation.RIGHT : Orientation.LEFT;
|
||||||
|
case RIGHT -> clockwise ? Orientation.UPSIDE_DOWN : Orientation.NONE;
|
||||||
|
case UPSIDE_DOWN -> clockwise ? Orientation.LEFT : Orientation.RIGHT;
|
||||||
|
case LEFT -> clockwise ? Orientation.NONE : Orientation.UPSIDE_DOWN;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public final class RotationChecker {
|
||||||
|
private static final Map<Orientation, int[][]> STANDARD_WALL_KICKS = Map.of(
|
||||||
|
Orientation.NONE, new int[][] {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}},
|
||||||
|
Orientation.RIGHT, new int[][] {{0,0}, {1,0}, {1,-1}, {0,2}, {1,2}},
|
||||||
|
Orientation.UPSIDE_DOWN, new int[][] {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}},
|
||||||
|
Orientation.LEFT, new int[][] {{0,0}, {-1,0}, {-1,-1}, {0,2}, {-1,2}}
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Map<Orientation, int[][]> I_WALL_KICKS = Map.of(
|
||||||
|
Orientation.NONE, new int[][] {{0,0}, {-1,0}, {2,0}, {-1,0}, {2,0}},
|
||||||
|
Orientation.RIGHT, new int[][] {{-1,0}, {0,0}, {0,0}, {0,1}, {0,-2}},
|
||||||
|
Orientation.UPSIDE_DOWN, new int[][] {{-1,1}, {1,1}, {-2,1}, {1,0}, {-2,0}},
|
||||||
|
Orientation.LEFT, new int[][] {{0,1}, {0,1}, {0,1}, {0,-1}, {0,2}}
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Map<Orientation, int[][]> O_WALL_KICKS = Map.of(
|
||||||
|
Orientation.NONE, new int[][] {{0,0}},
|
||||||
|
Orientation.RIGHT, new int[][] {{0,-1}},
|
||||||
|
Orientation.UPSIDE_DOWN, new int[][] {{-1,-1}},
|
||||||
|
Orientation.LEFT, new int[][] {{-1,0}}
|
||||||
|
);
|
||||||
|
|
||||||
|
public static int[][] getKicksArray(Orientation from, Orientation to, Tetromino.Shape shape) {
|
||||||
|
int[][] firstOffsets = getOffsetData(from, shape);
|
||||||
|
int[][] secondOffsets = getOffsetData(to, shape);
|
||||||
|
int[][] result = new int[firstOffsets.length][2];
|
||||||
|
|
||||||
|
for(int i = 0; i < firstOffsets.length; i++) {
|
||||||
|
result[i] = subtractInt(firstOffsets[i], secondOffsets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[] subtractInt(int[] first, int[] second) {
|
||||||
|
return IntStream.range(0, first.length)
|
||||||
|
.map(i -> first[i] - second[i])
|
||||||
|
.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[][] getOffsetData(Orientation orientation, Tetromino.Shape shape) {
|
||||||
|
return switch(shape) {
|
||||||
|
case J, L, S, T, Z -> STANDARD_WALL_KICKS.get(orientation);
|
||||||
|
case I -> I_WALL_KICKS.get(orientation);
|
||||||
|
case O -> O_WALL_KICKS.get(orientation);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
+92
-36
@@ -2,10 +2,9 @@ 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.instance.game.stateless.StatelessGame;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.scoreboard.Sidebar;
|
import net.minestom.server.scoreboard.Sidebar;
|
||||||
import net.minestom.server.timer.Scheduler;
|
import net.minestom.server.timer.Task;
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -23,6 +22,9 @@ public class TetrisGame {
|
|||||||
private final Map<Button, Long> lastPresses = new HashMap<>();
|
private final Map<Button, Long> lastPresses = new HashMap<>();
|
||||||
private final List<TetrisGame> otherTetrisGames = new ArrayList<>();
|
private final List<TetrisGame> otherTetrisGames = new ArrayList<>();
|
||||||
private final Random random;
|
private final Random random;
|
||||||
|
private Task tetrominoLockTask;
|
||||||
|
private int lockDelayResets;
|
||||||
|
private int currentTetrominoLowestY = Integer.MAX_VALUE;
|
||||||
public boolean lost = false;
|
public boolean lost = false;
|
||||||
public boolean paused = true;
|
public boolean paused = true;
|
||||||
public Tetromino currentTetromino;
|
public Tetromino currentTetromino;
|
||||||
@@ -54,24 +56,27 @@ public class TetrisGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void pressedButton(Button button) {
|
public void pressedButton(Button button) {
|
||||||
final int standardButtonDelay = 100;
|
final int standardButtonDelay = 95;
|
||||||
final int buttonDebounce = 70;
|
final int wsButtonDebounce = 70;
|
||||||
|
|
||||||
if(this.lastPresses.getOrDefault(button, 0L) >= System.currentTimeMillis() - standardButtonDelay) return;
|
if(this.lastPresses.getOrDefault(button, 0L) >= System.currentTimeMillis() - standardButtonDelay) return;
|
||||||
|
|
||||||
this.lastPresses.put(button, System.currentTimeMillis());
|
switch(button) {
|
||||||
if(button == Button.W) this.lastPresses.put(button, System.currentTimeMillis() + buttonDebounce);
|
case W -> this.lastPresses.put(button, System.currentTimeMillis() + wsButtonDebounce);
|
||||||
if(button == Button.S) this.lastPresses.put(button, System.currentTimeMillis() - buttonDebounce);
|
case S -> this.lastPresses.put(button, System.currentTimeMillis() - wsButtonDebounce);
|
||||||
|
case mouseLeft, mouseRight -> this.lastPresses.put(button, 0L);
|
||||||
|
default -> this.lastPresses.put(button, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
if(this.lost || this.paused) return;
|
if(this.lost || this.paused) return;
|
||||||
|
|
||||||
switch(button) {
|
switch(button) {
|
||||||
case A -> this.currentTetromino.moveLeft();
|
case A -> this.moveLeft();
|
||||||
case S -> this.moveDown();
|
case S -> this.moveDown();
|
||||||
case D -> this.currentTetromino.moveRight();
|
case D -> this.moveRight();
|
||||||
case W -> this.hardDrop();
|
case W -> this.hardDrop();
|
||||||
case mouseLeft -> this.currentTetromino.rotate(false);
|
case mouseLeft -> this.rotate(false);
|
||||||
case mouseRight -> this.currentTetromino.rotate(true);
|
case mouseRight -> this.rotate(true);
|
||||||
case space -> this.switchHold();
|
case space -> this.switchHold();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,8 +87,7 @@ public class TetrisGame {
|
|||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
this.paused = false;
|
this.paused = false;
|
||||||
Scheduler scheduler = MinecraftServer.getSchedulerManager();
|
this.instance.scheduler().submitTask(() -> {
|
||||||
scheduler.submitTask(() -> {
|
|
||||||
if(this.lost) return TaskSchedule.stop();
|
if(this.lost) return TaskSchedule.stop();
|
||||||
int standardTickDelay = 40;
|
int standardTickDelay = 40;
|
||||||
if(this.isFast) standardTickDelay = 20;
|
if(this.isFast) standardTickDelay = 20;
|
||||||
@@ -111,9 +115,12 @@ public class TetrisGame {
|
|||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if(this.lost || this.paused) return;
|
if(this.lost || this.paused) return;
|
||||||
if(!this.currentTetromino.moveDown()) {
|
if(this.currentTetromino.moveDown()) {
|
||||||
this.setActiveTetrominoDown();
|
this.stopTetrominoLockTask(this.currentTetromino.getYPosition() < this.currentTetrominoLowestY, false);
|
||||||
|
} else {
|
||||||
|
this.scheduleTetrominoLock();
|
||||||
}
|
}
|
||||||
|
this.currentTetrominoLowestY = Math.min(this.currentTetrominoLowestY, this.currentTetromino.getYPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScore() {
|
public int getScore() {
|
||||||
@@ -139,33 +146,43 @@ public class TetrisGame {
|
|||||||
this.lost = true;
|
this.lost = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean moveDown() {
|
private void moveDown() {
|
||||||
if(!this.currentTetromino.moveDown()) {
|
if(!this.currentTetromino.moveDown()) {
|
||||||
this.setActiveTetrominoDown();
|
this.scheduleTetrominoLock();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
this.stopTetrominoLockTask(this.currentTetromino.getYPosition() < this.currentTetrominoLowestY, false);
|
||||||
this.score += 1;
|
this.score += 1;
|
||||||
this.updateInfo();
|
this.updateInfo();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hardDrop() {
|
private void moveLeft() {
|
||||||
|
if(this.currentTetromino.moveLeft()) this.onSuccessfulMoveOrRotate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveRight() {
|
||||||
|
if(this.currentTetromino.moveRight()) this.onSuccessfulMoveOrRotate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rotate(boolean clockwise) {
|
||||||
|
if(this.currentTetromino.rotate(clockwise)) this.onSuccessfulMoveOrRotate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hardDrop() {
|
||||||
if(!this.currentTetromino.moveDown()) {
|
if(!this.currentTetromino.moveDown()) {
|
||||||
this.setActiveTetrominoDown();
|
this.lockActiveTetromino();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
this.score += 2;
|
do {
|
||||||
this.updateInfo();
|
|
||||||
while(this.currentTetromino.moveDown()) {
|
|
||||||
this.score += 2;
|
this.score += 2;
|
||||||
this.updateInfo();
|
} while(this.currentTetromino.moveDown());
|
||||||
}
|
this.updateInfo();
|
||||||
this.setActiveTetrominoDown();
|
this.lockActiveTetromino();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean switchHold() {
|
private void switchHold() {
|
||||||
if(!this.holdPossible) return false;
|
if(!this.holdPossible) return;
|
||||||
|
this.stopTetrominoLockTask(true);
|
||||||
|
|
||||||
Tetromino newCurrentTetromino;
|
Tetromino newCurrentTetromino;
|
||||||
if(this.holdTetromino == null) {
|
if(this.holdTetromino == null) {
|
||||||
@@ -181,6 +198,7 @@ public class TetrisGame {
|
|||||||
this.holdTetromino = new Tetromino(this.instance, this.currentTetromino.getShape());
|
this.holdTetromino = new Tetromino(this.instance, this.currentTetromino.getShape());
|
||||||
this.currentTetromino = newCurrentTetromino;
|
this.currentTetromino = newCurrentTetromino;
|
||||||
|
|
||||||
|
this.currentTetrominoLowestY = Integer.MAX_VALUE;
|
||||||
this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
|
this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
|
||||||
this.currentTetromino.draw();
|
this.currentTetromino.draw();
|
||||||
if(!this.currentTetromino.moveDown()) this.loose();
|
if(!this.currentTetromino.moveDown()) this.loose();
|
||||||
@@ -189,7 +207,12 @@ public class TetrisGame {
|
|||||||
this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0));
|
this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0));
|
||||||
this.holdTetromino.drawAsEntities();
|
this.holdTetromino.drawAsEntities();
|
||||||
this.holdPossible = false;
|
this.holdPossible = false;
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
private void onSuccessfulMoveOrRotate() {
|
||||||
|
if(!this.currentTetromino.isGrounded()) return;
|
||||||
|
this.stopTetrominoLockTask(false);
|
||||||
|
this.scheduleTetrominoLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateNextTetrominoes() {
|
private void updateNextTetrominoes() {
|
||||||
@@ -235,11 +258,39 @@ public class TetrisGame {
|
|||||||
this.sidebar.updateLineScore("2", this.level);
|
this.sidebar.updateLineScore("2", this.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setActiveTetrominoDown() {
|
private void scheduleTetrominoLock() {
|
||||||
|
if(this.tetrominoLockTask == null || !this.tetrominoLockTask.isAlive())
|
||||||
|
this.tetrominoLockTask = this.instance.scheduler().scheduleTask(() -> {
|
||||||
|
if(this.currentTetromino.isGrounded()) {
|
||||||
|
this.lockActiveTetromino();
|
||||||
|
} else {
|
||||||
|
this.stopTetrominoLockTask(false, false);
|
||||||
|
}
|
||||||
|
return TaskSchedule.stop();
|
||||||
|
}, TaskSchedule.millis(500));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopTetrominoLockTask(boolean resetHard) {
|
||||||
|
this.stopTetrominoLockTask(resetHard, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopTetrominoLockTask(boolean resetHard, boolean addToResets) {
|
||||||
|
if(resetHard) this.lockDelayResets = 0;
|
||||||
|
|
||||||
|
if(this.lockDelayResets >= 15 && addToResets) {
|
||||||
|
this.lockActiveTetromino();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(this.tetrominoLockTask != null) {
|
||||||
|
this.tetrominoLockTask.cancel();
|
||||||
|
this.tetrominoLockTask = null;
|
||||||
|
if(!resetHard && addToResets) this.lockDelayResets++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lockActiveTetromino() {
|
||||||
|
this.stopTetrominoLockTask(true);
|
||||||
this.currentTetromino.removeOwnEntities();
|
this.currentTetromino.removeOwnEntities();
|
||||||
this.currentTetromino = this.nextTetrominoes.removeFirst();
|
|
||||||
this.currentTetromino.remove();
|
|
||||||
this.updateNextTetrominoes();
|
|
||||||
|
|
||||||
int removedLines = this.playfield.removeFullLines();
|
int removedLines = this.playfield.removeFullLines();
|
||||||
int combatLines = 0;
|
int combatLines = 0;
|
||||||
@@ -297,6 +348,11 @@ public class TetrisGame {
|
|||||||
|
|
||||||
this.updateInfo();
|
this.updateInfo();
|
||||||
|
|
||||||
|
this.currentTetromino = this.nextTetrominoes.removeFirst();
|
||||||
|
this.currentTetromino.remove();
|
||||||
|
this.updateNextTetrominoes();
|
||||||
|
this.currentTetrominoLowestY = Integer.MAX_VALUE;
|
||||||
|
|
||||||
this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
|
this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
|
||||||
this.currentTetromino.draw();
|
this.currentTetromino.draw();
|
||||||
if(!this.currentTetromino.moveDown()) {
|
if(!this.currentTetromino.moveDown()) {
|
||||||
|
|||||||
+38
-23
@@ -8,14 +8,12 @@ import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
|||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.tag.Tag;
|
import net.minestom.server.tag.Tag;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class Tetromino {
|
public class Tetromino {
|
||||||
private final static EntityType ghostEntityType = EntityType.FALLING_BLOCK;
|
private final static EntityType ghostEntityType = EntityType.FALLING_BLOCK;
|
||||||
private final static Tag<String> uuidTag = Tag.String("uuid");
|
private final static Tag<String> uuidTag = Tag.String("uuid");
|
||||||
|
private Orientation orientation = Orientation.NONE;
|
||||||
private final Shape shape;
|
private final Shape shape;
|
||||||
private final StatelessGame instance;
|
private final StatelessGame instance;
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
@@ -28,10 +26,10 @@ public class Tetromino {
|
|||||||
this.uuid = UUID.randomUUID();
|
this.uuid = UUID.randomUUID();
|
||||||
|
|
||||||
switch(this.shape) {
|
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 I -> this.shapeArray = new int[][]{{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 1, 1, 1, 1}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}};
|
||||||
case J -> this.shapeArray = new int[][]{{1, 0, 0}, {1, 1, 1}, {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 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 O -> this.shapeArray = new int[][]{{0, 1, 1}, {0, 1, 1}, {0, 0, 0}};
|
||||||
case S -> this.shapeArray = new int[][]{{0, 1, 1}, {1, 1, 0}, {0, 0, 0}};
|
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 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}};
|
case Z -> this.shapeArray = new int[][]{{1, 1, 0}, {0, 1, 1}, {0, 0, 0}};
|
||||||
@@ -43,12 +41,23 @@ public class Tetromino {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setPosition(Pos newPosition) {
|
public void setPosition(Pos newPosition) {
|
||||||
this.position = newPosition;
|
this.position = new Pos(newPosition.x(), newPosition.y(), newPosition.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean rotate(boolean clockwise) {
|
public boolean rotate(boolean clockwise) {
|
||||||
int[][] newShapeArray = this.getTurnedShapeArray(clockwise);
|
int[][] newShapeArray = this.getTurnedShapeArray(clockwise);
|
||||||
return this.checkCollisionAndMove(this.position, newShapeArray);
|
Orientation newOrientation = this.orientation.rotated(clockwise);
|
||||||
|
|
||||||
|
int[][] kicksArray = RotationChecker.getKicksArray(this.orientation, newOrientation, this.shape);
|
||||||
|
for(int[] k : kicksArray) {
|
||||||
|
Pos candidate = new Pos(this.position.x() + k[0], this.position.y() + k[1], this.position.z());
|
||||||
|
if(this.checkCollisionAndMove(candidate, newShapeArray)) {
|
||||||
|
this.orientation = newOrientation;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean moveDown() {
|
public boolean moveDown() {
|
||||||
@@ -73,7 +82,7 @@ public class Tetromino {
|
|||||||
public void draw(boolean withGhost) {
|
public void draw(boolean withGhost) {
|
||||||
if(withGhost) {
|
if(withGhost) {
|
||||||
Pos ghostPos = this.position;
|
Pos ghostPos = this.position;
|
||||||
while(!this.checkCollision(ghostPos.sub(0, 1, 0), this.shapeArray)) {
|
while(!this.hasCollision(ghostPos.sub(0, 1, 0), this.shapeArray)) {
|
||||||
ghostPos = ghostPos.sub(0, 1, 0);
|
ghostPos = ghostPos.sub(0, 1, 0);
|
||||||
}
|
}
|
||||||
Pos positionChange = this.position.sub(ghostPos);
|
Pos positionChange = this.position.sub(ghostPos);
|
||||||
@@ -182,7 +191,7 @@ public class Tetromino {
|
|||||||
|
|
||||||
private boolean isPartOfTetromino(Pos position) {
|
private boolean isPartOfTetromino(Pos position) {
|
||||||
return this.getBlockPositions().stream()
|
return this.getBlockPositions().stream()
|
||||||
.anyMatch(pos -> pos.equals(position));
|
.anyMatch(pos -> pos.sameBlock(position));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Pos> getBlockPositions() {
|
private List<Pos> getBlockPositions() {
|
||||||
@@ -198,10 +207,10 @@ public class Tetromino {
|
|||||||
for(int x = 0; x < arrayLength; x++) {
|
for(int x = 0; x < arrayLength; x++) {
|
||||||
for(int y = 0; y < arrayLength; y++) {
|
for(int y = 0; y < arrayLength; y++) {
|
||||||
if(shapeArray[arrayLength - 1 - y][x] == 1) {
|
if(shapeArray[arrayLength - 1 - y][x] == 1) {
|
||||||
switch(this.shape) {
|
if(Objects.requireNonNull(this.shape) == Shape.I) {
|
||||||
case I -> returnList.add(position.add(x - 1, y - 2, 0));
|
returnList.add(position.add(x - 2, y - 2, 0));
|
||||||
case O -> returnList.add(position.add(x, y, 0));
|
} else {
|
||||||
default -> returnList.add(position.add(x - 1, y - 1, 0));
|
returnList.add(position.add(x - 1, y - 1, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,7 +219,7 @@ public class Tetromino {
|
|||||||
return returnList;
|
return returnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkCollision(Pos newPosition, int[][] newShapeArray) {
|
private boolean hasCollision(Pos newPosition, int[][] newShapeArray) {
|
||||||
List<Pos> newBlockPositions = this.getBlockPositions(newPosition, newShapeArray);
|
List<Pos> newBlockPositions = this.getBlockPositions(newPosition, newShapeArray);
|
||||||
|
|
||||||
for(Pos pos : newBlockPositions) {
|
for(Pos pos : newBlockPositions) {
|
||||||
@@ -222,15 +231,21 @@ public class Tetromino {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isGrounded() {
|
||||||
|
return this.hasCollision(this.position.sub(0, 1, 0), this.shapeArray);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkCollisionAndMove(Pos newPosition, int[][] newShapeArray) {
|
private boolean checkCollisionAndMove(Pos newPosition, int[][] newShapeArray) {
|
||||||
if(!this.checkCollision(newPosition, newShapeArray)) {
|
if(this.hasCollision(newPosition, newShapeArray)) return false;
|
||||||
this.remove();
|
this.remove();
|
||||||
this.shapeArray = Arrays.stream(newShapeArray).map(int[]::clone).toArray(int[][]::new);
|
this.shapeArray = Arrays.stream(newShapeArray).map(int[]::clone).toArray(int[][]::new);
|
||||||
this.setPosition(newPosition);
|
this.setPosition(newPosition);
|
||||||
this.draw();
|
this.draw();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
public int getYPosition() {
|
||||||
|
return Math.toIntExact(Math.round(this.position.y()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Shape {
|
public enum Shape {
|
||||||
|
|||||||
+6
-1
@@ -22,7 +22,12 @@ public class TowerdefenseRoom extends InstanceContainer {
|
|||||||
private final Towerdefense game;
|
private final Towerdefense game;
|
||||||
|
|
||||||
public TowerdefenseRoom(Player player, Towerdefense game) {
|
public TowerdefenseRoom(Player player, Towerdefense game) {
|
||||||
super(UUID.randomUUID(), Dimension.OVERWORLD.key);
|
this(UUID.randomUUID(), player, game);
|
||||||
|
}
|
||||||
|
|
||||||
|
// eindeutiger Dimension-Name pro Instanz, siehe MineNetInstance
|
||||||
|
private TowerdefenseRoom(UUID uuid, Player player, Towerdefense game) {
|
||||||
|
super(uuid, Dimension.OVERWORLD.key, net.kyori.adventure.key.Key.key("minenet", "instance-" + uuid));
|
||||||
MinecraftServer.getInstanceManager().registerInstance(this);
|
MinecraftServer.getInstanceManager().registerInstance(this);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.game = game;
|
this.game = game;
|
||||||
|
|||||||
+5
-5
@@ -1,6 +1,7 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace;
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace;
|
||||||
|
|
||||||
import de.articdive.jnoise.JNoise;
|
import de.articdive.jnoise.generators.noisegen.opensimplex.FastSimplexNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
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.FirstWinsScore;
|
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
|
||||||
@@ -49,9 +50,8 @@ class TrafficLightRace extends StatelessGame {
|
|||||||
@Override
|
@Override
|
||||||
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||||
final JNoise slowBatches = JNoise.newBuilder()
|
final JNoise slowBatches = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.1)
|
||||||
.setFrequency(0.1)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||||
@@ -62,7 +62,7 @@ class TrafficLightRace extends StatelessGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(int z = this.preRun; z <= this.length + this.preRun; z++) {
|
for(int z = this.preRun; z <= this.length + this.preRun; z++) {
|
||||||
batch.setBlock(x, 50, z, slowBatches.getNoise(x, z) > 0.6 ? Block.SOUL_SAND : BlockPallet.STREET.rnd());
|
batch.setBlock(x, 50, z, slowBatches.evaluateNoise(x, z) > 0.6 ? Block.SOUL_SAND : BlockPallet.STREET.rnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int z = this.preRun + this.length; z <= this.preRun + this.length + this.afterRun; z++) {
|
for(int z = this.preRun + this.length; z <= this.preRun + this.length + this.afterRun; z++) {
|
||||||
|
|||||||
+5
-11
@@ -15,8 +15,7 @@ import net.minestom.server.entity.EntityType;
|
|||||||
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.entity.metadata.other.FallingBlockMeta;
|
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
||||||
import net.minestom.server.event.player.PlayerStartSneakingEvent;
|
import net.minestom.server.event.player.PlayerInputEvent;
|
||||||
import net.minestom.server.event.player.PlayerStopSneakingEvent;
|
|
||||||
import net.minestom.server.event.player.PlayerTickEvent;
|
import net.minestom.server.event.player.PlayerTickEvent;
|
||||||
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;
|
||||||
@@ -45,8 +44,7 @@ class TurtleGame extends StatelessGame {
|
|||||||
|
|
||||||
this.eventNode()
|
this.eventNode()
|
||||||
.addListener(PlayerTickEvent.class, this::onPlayerTick)
|
.addListener(PlayerTickEvent.class, this::onPlayerTick)
|
||||||
.addListener(PlayerStartSneakingEvent.class, this::onPlayerStartSneak)
|
.addListener(PlayerInputEvent.class, this::onPlayerInput);
|
||||||
.addListener(PlayerStopSneakingEvent.class, this::onPlayerStopSneak);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -66,14 +64,10 @@ class TurtleGame extends StatelessGame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onPlayerStartSneak(@NotNull PlayerStartSneakingEvent event) {
|
private void onPlayerInput(@NotNull PlayerInputEvent event) {
|
||||||
Player p = event.getPlayer();
|
Player p = event.getPlayer();
|
||||||
this.turtlePlayerMap.get(p).boostSpeed();
|
if(event.hasPressedShiftKey()) this.turtlePlayerMap.get(p).boostSpeed();
|
||||||
}
|
if(event.hasReleasedShiftKey()) this.turtlePlayerMap.get(p).cancelBoost();
|
||||||
|
|
||||||
private void onPlayerStopSneak(@NotNull PlayerStopSneakingEvent event) {
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
this.turtlePlayerMap.get(p).cancelBoost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onPlayerTick(@NotNull PlayerTickEvent event) {
|
protected void onPlayerTick(@NotNull PlayerTickEvent event) {
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
package eu.mhsl.minenet.minigames.instance.game.stateless.types.turtleGame.gameObjects;
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.turtleGame.gameObjects;
|
||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.coordinate.Vec;
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.entity.Entity;
|
import net.minestom.server.entity.Entity;
|
||||||
import net.minestom.server.entity.EntityCreature;
|
import net.minestom.server.entity.EntityCreature;
|
||||||
@@ -52,7 +53,7 @@ public class Turtle extends EntityCreature {
|
|||||||
if(this.getInstance() == null) return;
|
if(this.getInstance() == null) return;
|
||||||
this.teleport(this.getPosition().withView(this.player.getPosition().withPitch(this.getPosition().pitch())));
|
this.teleport(this.getPosition().withView(this.player.getPosition().withPitch(this.getPosition().pitch())));
|
||||||
Vec lookingVector = this.player.getPosition().direction().withY(0).mul(100);
|
Vec lookingVector = this.player.getPosition().direction().withY(0).mul(100);
|
||||||
this.lookAt(this.getPosition().add(lookingVector.asPosition()));
|
this.lookAt(this.getPosition().add(new Pos(lookingVector)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void move() {
|
public void move() {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class Hub extends MineNetInstance implements Spawnable {
|
|||||||
this.setChunkLoader(new AnvilLoader(Path.of("maps/hub")));
|
this.setChunkLoader(new AnvilLoader(Path.of("maps/hub")));
|
||||||
|
|
||||||
this.setTime(18000);
|
this.setTime(18000);
|
||||||
this.setTimeRate(0);
|
this.defaultClock().pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
|
|||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
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.inventory.InventoryPreClickEvent;
|
||||||
import net.minestom.server.event.player.PlayerPacketEvent;
|
import net.minestom.server.event.player.PlayerPacketEvent;
|
||||||
import net.minestom.server.inventory.InventoryType;
|
import net.minestom.server.inventory.InventoryType;
|
||||||
import net.minestom.server.inventory.click.ClickType;
|
import net.minestom.server.inventory.click.Click;
|
||||||
import net.minestom.server.inventory.condition.InventoryConditionResult;
|
|
||||||
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.network.packet.client.play.ClientNameItemPacket;
|
import net.minestom.server.network.packet.client.play.ClientNameItemPacket;
|
||||||
@@ -45,9 +45,9 @@ public class JoinInventory extends InteractableInventory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
|
protected void onClick(Player player, int slot, Click click, InventoryPreClickEvent event) {
|
||||||
if(slot != 2) return;
|
if(slot != 2) return;
|
||||||
inventoryConditionResult.setCancel(true);
|
event.setCancelled(true);
|
||||||
player.closeInventory();
|
player.closeInventory();
|
||||||
|
|
||||||
this.typedText = this.formatInput(this.typedText);
|
this.typedText = this.formatInput(this.typedText);
|
||||||
|
|||||||
@@ -2,13 +2,8 @@ package eu.mhsl.minenet.minigames.message.type;
|
|||||||
|
|
||||||
import eu.mhsl.minenet.minigames.message.TranslatableMessage;
|
import eu.mhsl.minenet.minigames.message.TranslatableMessage;
|
||||||
import net.kyori.adventure.audience.Audience;
|
import net.kyori.adventure.audience.Audience;
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.title.Title;
|
import net.kyori.adventure.title.Title;
|
||||||
import net.kyori.adventure.title.TitlePart;
|
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -41,26 +36,6 @@ public class TitleMessage extends TranslatableMessage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(Player p) {
|
public void send(Player p) {
|
||||||
Audience.audience(p).showTitle(new Title() {
|
Audience.audience(p).showTitle(Title.title(this.build(p), this.subtitle.build(p), this.times));
|
||||||
@Override
|
|
||||||
public @NotNull Component title() {
|
|
||||||
return TitleMessage.this.build(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Component subtitle() {
|
|
||||||
return TitleMessage.this.subtitle.build(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable Times times() {
|
|
||||||
return TitleMessage.this.times;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> @UnknownNullability T part(@NotNull TitlePart<T> part) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ public abstract class Score {
|
|||||||
throw new NotImplementedException("This Score type is not able to process points");
|
throw new NotImplementedException("This Score type is not able to process points");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void insertMultiple(Set<Player> p) {
|
||||||
|
p.forEach(player -> this.insertResultProcessor(player, () -> {}));
|
||||||
|
this.insertResultImplementation(p);
|
||||||
|
}
|
||||||
|
|
||||||
public void insertResult(Player p) {
|
public void insertResult(Player p) {
|
||||||
this.insertResultProcessor(p, () -> this.insertResultImplementation(Set.of(p)));
|
this.insertResultProcessor(p, () -> this.insertResultImplementation(Set.of(p)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ public class Tournament {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new Rewards(
|
return new Rewards(
|
||||||
this.memorialConfiguration.memorialMaterial().namespace().value(),
|
this.memorialConfiguration.memorialMaterial().key().value(),
|
||||||
this.memorialConfiguration.memorialTitle(),
|
this.memorialConfiguration.memorialTitle(),
|
||||||
this.memorialConfiguration.memorialLore(),
|
this.memorialConfiguration.memorialLore(),
|
||||||
this.getGameScores().keySet().stream().map(Player::getUuid).toList(),
|
this.getGameScores().keySet().stream().map(Player::getUuid).toList(),
|
||||||
this.rewardConfiguration.item().namespace().value(),
|
this.rewardConfiguration.item().key().value(),
|
||||||
itemCount
|
itemCount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-11
@@ -2,24 +2,40 @@ package eu.mhsl.minenet.minigames.shared.inventory;
|
|||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.event.inventory.InventoryPreClickEvent;
|
||||||
import net.minestom.server.inventory.Inventory;
|
import net.minestom.server.inventory.Inventory;
|
||||||
import net.minestom.server.inventory.InventoryType;
|
import net.minestom.server.inventory.InventoryType;
|
||||||
import net.minestom.server.inventory.click.ClickType;
|
import net.minestom.server.inventory.click.Click;
|
||||||
import net.minestom.server.inventory.condition.InventoryConditionResult;
|
|
||||||
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 org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class InteractableInventory extends Inventory {
|
public class InteractableInventory extends Inventory {
|
||||||
|
private final Map<Integer, ClickAction> clickActions = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private record ClickAction(ItemStack item, Consumer<ItemClick> callback, boolean closeAfter) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines an Inventory with direct callbacks for ItemSlots
|
* Defines an Inventory with direct callbacks for ItemSlots
|
||||||
*/
|
*/
|
||||||
protected InteractableInventory(@NotNull InventoryType inventoryType, @NotNull Component title) {
|
protected InteractableInventory(@NotNull InventoryType inventoryType, @NotNull Component title) {
|
||||||
super(inventoryType, title);
|
super(inventoryType, title);
|
||||||
|
|
||||||
this.addInventoryCondition(this::onClick);
|
this.eventNode().addListener(InventoryPreClickEvent.class, event -> {
|
||||||
|
event.setCancelled(true);
|
||||||
|
this.onClick(event.getPlayer(), event.getSlot(), event.getClick(), event);
|
||||||
|
|
||||||
|
ClickAction action = this.clickActions.get(event.getSlot());
|
||||||
|
if(action == null) return;
|
||||||
|
|
||||||
|
if(action.closeAfter()) event.getPlayer().closeInventory();
|
||||||
|
action.callback().accept(new ItemClick(event.getPlayer(), this, event.getSlot(), action.item(), event.getClick()));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,13 +43,7 @@ public class InteractableInventory extends Inventory {
|
|||||||
*/
|
*/
|
||||||
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback, boolean closeAfter) {
|
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback, boolean closeAfter) {
|
||||||
this.setItemStack(slot, item);
|
this.setItemStack(slot, item);
|
||||||
this.addInventoryCondition((player, clickedSlot, clickType, inventoryConditionResult) -> {
|
this.clickActions.put(slot, new ClickAction(item, callback, closeAfter));
|
||||||
if(clickedSlot == slot) {
|
|
||||||
if(closeAfter) player.closeInventory();
|
|
||||||
callback.accept(new ItemClick(player, this, clickedSlot, item, clickType));
|
|
||||||
}
|
|
||||||
inventoryConditionResult.setCancel(true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback) {
|
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback) {
|
||||||
@@ -62,7 +72,7 @@ public class InteractableInventory extends Inventory {
|
|||||||
/**
|
/**
|
||||||
* You may want to Override this method to get more generic click events
|
* You may want to Override this method to get more generic click events
|
||||||
*/
|
*/
|
||||||
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
|
protected void onClick(Player player, int slot, Click click, InventoryPreClickEvent event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package eu.mhsl.minenet.minigames.shared.inventory;
|
|||||||
|
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.inventory.Inventory;
|
import net.minestom.server.inventory.Inventory;
|
||||||
import net.minestom.server.inventory.click.ClickType;
|
import net.minestom.server.inventory.click.Click;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
|
|
||||||
public class ItemClick {
|
public class ItemClick {
|
||||||
@@ -10,17 +10,17 @@ public class ItemClick {
|
|||||||
private final InteractableInventory inventory;
|
private final InteractableInventory inventory;
|
||||||
private final int clickedSlot;
|
private final int clickedSlot;
|
||||||
private final ItemStack item;
|
private final ItemStack item;
|
||||||
private final ClickType clickType;
|
private final Click click;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes a click on an Item from an IntractableInventory
|
* Describes a click on an Item from an IntractableInventory
|
||||||
*/
|
*/
|
||||||
public ItemClick(Player player, InteractableInventory inventory, int clickedSlot, ItemStack item, ClickType clickType) {
|
public ItemClick(Player player, InteractableInventory inventory, int clickedSlot, ItemStack item, Click click) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.inventory = inventory;
|
this.inventory = inventory;
|
||||||
this.clickedSlot = clickedSlot;
|
this.clickedSlot = clickedSlot;
|
||||||
this.item = item;
|
this.item = item;
|
||||||
this.clickType = clickType;
|
this.click = click;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getPlayer() {
|
public Player getPlayer() {
|
||||||
@@ -39,7 +39,7 @@ public class ItemClick {
|
|||||||
return this.item;
|
return this.item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClickType getClickType() {
|
public Click getClick() {
|
||||||
return this.clickType;
|
return this.click;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package eu.mhsl.minenet.minigames.util;
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import net.minestom.server.instance.InstanceContainer;
|
import net.minestom.server.instance.InstanceContainer;
|
||||||
|
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
||||||
import net.minestom.server.instance.batch.Batch;
|
import net.minestom.server.instance.batch.Batch;
|
||||||
import net.minestom.server.instance.batch.ChunkBatch;
|
import net.minestom.server.instance.batch.ChunkBatch;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
@@ -24,27 +25,19 @@ public class BatchUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadAndApplyBatch(Batch batch, InstanceContainer instance, Runnable onFinish) {
|
public static void loadAndApplyBatch(AbsoluteBlockBatch batch, InstanceContainer instance, Runnable onFinish) {
|
||||||
batch.awaitReady();
|
batch.awaitReady();
|
||||||
long[] affectedChunks = BatchUtil.getAffectedChunks(batch);
|
long[] affectedChunks = BatchUtil.getAffectedChunks(batch);
|
||||||
ChunkUtils.optionalLoadAll(instance, affectedChunks, null).thenRun(() -> batch.apply(instance, onFinish));
|
ChunkUtils.optionalLoadAll(instance, affectedChunks, null).thenRun(() -> batch.apply(instance, b -> onFinish.run()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadAndApplyBatchBlocking(Batch batch, InstanceContainer instance) {
|
public static void loadAndApplyBatchBlocking(AbsoluteBlockBatch batch, InstanceContainer instance) {
|
||||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||||
batch.awaitReady();
|
batch.awaitReady();
|
||||||
long[] affectedChunks = BatchUtil.getAffectedChunks(batch);
|
long[] affectedChunks = BatchUtil.getAffectedChunks(batch);
|
||||||
CompletableFuture<Void> loadChunksTask = ChunkUtils.optionalLoadAll(instance, affectedChunks, null);
|
CompletableFuture<Void> loadChunksTask = ChunkUtils.optionalLoadAll(instance, affectedChunks, null);
|
||||||
|
|
||||||
Runnable completerTask = () -> {
|
loadChunksTask.thenRun(() -> batch.apply(instance, b -> future.complete(null)));
|
||||||
System.out.println("COMPLETE");
|
|
||||||
future.complete(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
loadChunksTask.thenRun(() -> {
|
|
||||||
System.out.println("BEGIN");
|
|
||||||
batch.apply(instance, completerTask);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
future.get();
|
future.get();
|
||||||
|
|||||||
@@ -33,9 +33,15 @@ public class Position {
|
|||||||
public static List<Block> blocksBelowPlayer(Instance instance, Player p) {
|
public static List<Block> blocksBelowPlayer(Instance instance, Player p) {
|
||||||
Point playerPos = p.getPosition();
|
Point playerPos = p.getPosition();
|
||||||
List<Block> blocks = new ArrayList<>();
|
List<Block> blocks = new ArrayList<>();
|
||||||
GeneratorUtils.foreachXZ(playerPos.sub(0.5, 1, 0.5), playerPos.add(0.5, -1, 0.5), point -> {
|
GeneratorUtils.foreachXZ(
|
||||||
blocks.add(instance.getBlock(point));
|
playerPos.sub(0.5, 1, 0.5),
|
||||||
});
|
playerPos.add(0.5, -1, 0.5),
|
||||||
|
point -> blocks.add(instance.getBlock(point))
|
||||||
|
);
|
||||||
return blocks.stream().distinct().toList();
|
return blocks.stream().distinct().toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasPositionChanged(Pos oldPos, Pos newPos) {
|
||||||
|
return !oldPos.withView(0, 0).equals(newPos.withView(0, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-8
@@ -1,6 +1,7 @@
|
|||||||
package eu.mhsl.minenet.minigames.world.generator.featureEnriched;
|
package eu.mhsl.minenet.minigames.world.generator.featureEnriched;
|
||||||
|
|
||||||
import de.articdive.jnoise.JNoise;
|
import de.articdive.jnoise.generators.noisegen.opensimplex.FastSimplexNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
import eu.mhsl.minenet.minigames.util.NumberUtil;
|
import eu.mhsl.minenet.minigames.util.NumberUtil;
|
||||||
import eu.mhsl.minenet.minigames.world.generator.terrain.HeightTerrainGenerator;
|
import eu.mhsl.minenet.minigames.world.generator.terrain.HeightTerrainGenerator;
|
||||||
import net.minestom.server.coordinate.Point;
|
import net.minestom.server.coordinate.Point;
|
||||||
@@ -9,15 +10,13 @@ import java.util.function.Function;
|
|||||||
|
|
||||||
public class ValeGenerator extends HeightTerrainGenerator {
|
public class ValeGenerator extends HeightTerrainGenerator {
|
||||||
private final JNoise curves = JNoise.newBuilder()
|
private final JNoise curves = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.01)
|
||||||
.setFrequency(0.01)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private final JNoise largeCurves = JNoise.newBuilder()
|
private final JNoise largeCurves = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.001)
|
||||||
.setFrequency(0.001)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private Function<Integer, Double> xShiftMultiplier = multiplier -> 1d;
|
private Function<Integer, Double> xShiftMultiplier = multiplier -> 1d;
|
||||||
@@ -33,7 +32,7 @@ public class ValeGenerator extends HeightTerrainGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getXShiftAtZ(int z) {
|
public int getXShiftAtZ(int z) {
|
||||||
return (int) ((this.curves.getNoise(z) * 32 + this.largeCurves.getNoise(z) * 64) * this.xShiftMultiplier.apply(z) + this.xShiftOffset.apply(z));
|
return (int) ((this.curves.evaluateNoise(z) * 32 + this.largeCurves.evaluateNoise(z) * 64) * this.xShiftMultiplier.apply(z) + this.xShiftOffset.apply(z));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setXShiftMultiplier(Function<Integer, Double> xShiftMultiplier) {
|
public void setXShiftMultiplier(Function<Integer, Double> xShiftMultiplier) {
|
||||||
|
|||||||
+11
-13
@@ -1,6 +1,7 @@
|
|||||||
package eu.mhsl.minenet.minigames.world.generator.terrain;
|
package eu.mhsl.minenet.minigames.world.generator.terrain;
|
||||||
|
|
||||||
import de.articdive.jnoise.JNoise;
|
import de.articdive.jnoise.generators.noisegen.opensimplex.FastSimplexNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
import eu.mhsl.minenet.minigames.util.NumberUtil;
|
import eu.mhsl.minenet.minigames.util.NumberUtil;
|
||||||
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
import eu.mhsl.minenet.minigames.world.generator.PlateTerrainGenerator;
|
import eu.mhsl.minenet.minigames.world.generator.PlateTerrainGenerator;
|
||||||
@@ -17,19 +18,16 @@ public class CircularPlateTerrainGenerator extends PlateTerrainGenerator {
|
|||||||
protected final Random rnd = new Random();
|
protected final Random rnd = new Random();
|
||||||
private final int size;
|
private final int size;
|
||||||
private final JNoise base = JNoise.newBuilder()
|
private final JNoise base = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.01)
|
||||||
.setFrequency(0.01)
|
|
||||||
.build();
|
.build();
|
||||||
private final JNoise batches = JNoise.newBuilder()
|
private final JNoise batches = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.05)
|
||||||
.setFrequency(0.05)
|
|
||||||
.build();
|
.build();
|
||||||
private final JNoise peaks = JNoise.newBuilder()
|
private final JNoise peaks = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.1)
|
||||||
.setFrequency(0.1)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public CircularPlateTerrainGenerator(int size) {
|
public CircularPlateTerrainGenerator(int size) {
|
||||||
@@ -61,11 +59,11 @@ public class CircularPlateTerrainGenerator extends PlateTerrainGenerator {
|
|||||||
unit.modifier().setBlock(bottom, Block.GRASS_BLOCK);
|
unit.modifier().setBlock(bottom, Block.GRASS_BLOCK);
|
||||||
|
|
||||||
synchronized(this.base) {
|
synchronized(this.base) {
|
||||||
double baseNoise = this.base.getNoise(bottom.x(), bottom.z());
|
double baseNoise = this.base.evaluateNoise(bottom.x(), bottom.z());
|
||||||
double currentHeight = minTwo(NumberUtil.map(distance, 0, 400, -((double) this.size / 5), 200)) + baseNoise * 8;
|
double currentHeight = minTwo(NumberUtil.map(distance, 0, 400, -((double) this.size / 5), 200)) + baseNoise * 8;
|
||||||
|
|
||||||
synchronized(this.batches) {
|
synchronized(this.batches) {
|
||||||
double elementNoise = this.batches.getNoise(bottom.x(), bottom.z());
|
double elementNoise = this.batches.evaluateNoise(bottom.x(), bottom.z());
|
||||||
|
|
||||||
unit.modifier().fill(
|
unit.modifier().fill(
|
||||||
bottom,
|
bottom,
|
||||||
@@ -76,7 +74,7 @@ public class CircularPlateTerrainGenerator extends PlateTerrainGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized(this.peaks) {
|
synchronized(this.peaks) {
|
||||||
double peakNoise = this.peaks.getNoise(bottom.x(), bottom.z());
|
double peakNoise = this.peaks.evaluateNoise(bottom.x(), bottom.z());
|
||||||
|
|
||||||
if(peakNoise > 0.97 && bottom.distance(new Pos(0, 0, 0)) > (this.size + 20)) {
|
if(peakNoise > 0.97 && bottom.distance(new Pos(0, 0, 0)) > (this.size + 20)) {
|
||||||
|
|
||||||
|
|||||||
+11
-13
@@ -1,6 +1,7 @@
|
|||||||
package eu.mhsl.minenet.minigames.world.generator.terrain;
|
package eu.mhsl.minenet.minigames.world.generator.terrain;
|
||||||
|
|
||||||
import de.articdive.jnoise.JNoise;
|
import de.articdive.jnoise.generators.noisegen.opensimplex.FastSimplexNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
import eu.mhsl.minenet.minigames.util.GeneratorUtils;
|
import eu.mhsl.minenet.minigames.util.GeneratorUtils;
|
||||||
import eu.mhsl.minenet.minigames.util.NumberUtil;
|
import eu.mhsl.minenet.minigames.util.NumberUtil;
|
||||||
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
@@ -17,19 +18,16 @@ import java.util.function.Function;
|
|||||||
public class HeightTerrainGenerator extends BaseGenerator {
|
public class HeightTerrainGenerator extends BaseGenerator {
|
||||||
protected final Random rnd = new Random();
|
protected final Random rnd = new Random();
|
||||||
private final JNoise base = JNoise.newBuilder()
|
private final JNoise base = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.01)
|
||||||
.setFrequency(0.01)
|
|
||||||
.build();
|
.build();
|
||||||
private final JNoise batches = JNoise.newBuilder()
|
private final JNoise batches = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.05)
|
||||||
.setFrequency(0.05)
|
|
||||||
.build();
|
.build();
|
||||||
private final JNoise peaks = JNoise.newBuilder()
|
private final JNoise peaks = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.1)
|
||||||
.setFrequency(0.1)
|
|
||||||
.build();
|
.build();
|
||||||
private final BlockPallet blockPallet = BlockPallet.STONE;
|
private final BlockPallet blockPallet = BlockPallet.STONE;
|
||||||
protected Function<Point, Integer> heightNoiseMultiplier = (Point) -> 16;
|
protected Function<Point, Integer> heightNoiseMultiplier = (Point) -> 16;
|
||||||
@@ -43,13 +41,13 @@ public class HeightTerrainGenerator extends BaseGenerator {
|
|||||||
unit.modifier().setBlock(bottomPoint, this.blockPallet.rnd());
|
unit.modifier().setBlock(bottomPoint, this.blockPallet.rnd());
|
||||||
|
|
||||||
synchronized(this.base) {
|
synchronized(this.base) {
|
||||||
double heightNoise = this.base.getNoise(bottomPoint.x(), bottomPoint.z());
|
double heightNoise = this.base.evaluateNoise(bottomPoint.x(), bottomPoint.z());
|
||||||
double noiseModifier = heightNoise * this.heightNoiseMultiplier.apply(bottomPoint);
|
double noiseModifier = heightNoise * this.heightNoiseMultiplier.apply(bottomPoint);
|
||||||
double heightModifier = NumberUtil.clamp(this.calculateHeight.apply(bottomPoint) + noiseModifier, 1d, unit.size().y());
|
double heightModifier = NumberUtil.clamp(this.calculateHeight.apply(bottomPoint) + noiseModifier, 1d, unit.size().y());
|
||||||
if(heightModifier < 1) System.out.println("HEIGHT MODIFIER ILLEGAL");
|
if(heightModifier < 1) System.out.println("HEIGHT MODIFIER ILLEGAL");
|
||||||
|
|
||||||
synchronized(this.batches) {
|
synchronized(this.batches) {
|
||||||
double batchNoise = this.batches.getNoise(bottomPoint.x(), bottomPoint.z());
|
double batchNoise = this.batches.evaluateNoise(bottomPoint.x(), bottomPoint.z());
|
||||||
|
|
||||||
Block block = batchNoise < 0.9 ? batchNoise > -0.2 ? Block.GRASS_BLOCK : Block.SOUL_SAND : Block.STONE;
|
Block block = batchNoise < 0.9 ? batchNoise > -0.2 ? Block.GRASS_BLOCK : Block.SOUL_SAND : Block.STONE;
|
||||||
unit.modifier().fill(bottomPoint, bottomPoint.add(1, heightModifier, 1), block);
|
unit.modifier().fill(bottomPoint, bottomPoint.add(1, heightModifier, 1), block);
|
||||||
@@ -77,7 +75,7 @@ public class HeightTerrainGenerator extends BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized(this.peaks) {
|
synchronized(this.peaks) {
|
||||||
double peakNoise = this.peaks.getNoise(bottomPoint.x(), bottomPoint.z());
|
double peakNoise = this.peaks.evaluateNoise(bottomPoint.x(), bottomPoint.z());
|
||||||
|
|
||||||
if(peakNoise > 0.97 && bottomPoint.distance(new Pos(0, 0, 0)) > (50 + 20)) {
|
if(peakNoise > 0.97 && bottomPoint.distance(new Pos(0, 0, 0)) > (50 + 20)) {
|
||||||
|
|
||||||
|
|||||||
+11
-13
@@ -1,6 +1,7 @@
|
|||||||
package eu.mhsl.minenet.minigames.world.generator.terrain;
|
package eu.mhsl.minenet.minigames.world.generator.terrain;
|
||||||
|
|
||||||
import de.articdive.jnoise.JNoise;
|
import de.articdive.jnoise.generators.noisegen.opensimplex.FastSimplexNoiseGenerator;
|
||||||
|
import de.articdive.jnoise.pipeline.JNoise;
|
||||||
import eu.mhsl.minenet.minigames.util.NumberUtil;
|
import eu.mhsl.minenet.minigames.util.NumberUtil;
|
||||||
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
import eu.mhsl.minenet.minigames.world.BlockPallet;
|
||||||
import eu.mhsl.minenet.minigames.world.generator.PlateTerrainGenerator;
|
import eu.mhsl.minenet.minigames.world.generator.PlateTerrainGenerator;
|
||||||
@@ -21,19 +22,16 @@ public class SquarePlateTerrainGenerator extends PlateTerrainGenerator {
|
|||||||
private final int width;
|
private final int width;
|
||||||
private final int length;
|
private final int length;
|
||||||
private final JNoise base = JNoise.newBuilder()
|
private final JNoise base = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.01)
|
||||||
.setFrequency(0.01)
|
|
||||||
.build();
|
.build();
|
||||||
private final JNoise batches = JNoise.newBuilder()
|
private final JNoise batches = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.05)
|
||||||
.setFrequency(0.05)
|
|
||||||
.build();
|
.build();
|
||||||
private final JNoise peaks = JNoise.newBuilder()
|
private final JNoise peaks = JNoise.newBuilder()
|
||||||
.fastSimplex()
|
.fastSimplex(FastSimplexNoiseGenerator.newBuilder().setSeed(this.rnd.nextLong()).build())
|
||||||
.setSeed(this.rnd.nextLong())
|
.scale(0.1)
|
||||||
.setFrequency(0.1)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public SquarePlateTerrainGenerator(int width, int length) {
|
public SquarePlateTerrainGenerator(int width, int length) {
|
||||||
@@ -82,7 +80,7 @@ public class SquarePlateTerrainGenerator extends PlateTerrainGenerator {
|
|||||||
unit.modifier().setBlock(bottom, Block.GRASS_BLOCK);
|
unit.modifier().setBlock(bottom, Block.GRASS_BLOCK);
|
||||||
|
|
||||||
synchronized(this.base) {
|
synchronized(this.base) {
|
||||||
double baseNoise = this.base.getNoise(bottom.x(), bottom.z());
|
double baseNoise = this.base.evaluateNoise(bottom.x(), bottom.z());
|
||||||
double[] possibleHeights = {
|
double[] possibleHeights = {
|
||||||
minTwo(NumberUtil.map(bottom.distance(new Pos(0, 0, 0)), 0, 400, -((double) this.width / 5), 200)) + baseNoise * 8,
|
minTwo(NumberUtil.map(bottom.distance(new Pos(0, 0, 0)), 0, 400, -((double) this.width / 5), 200)) + baseNoise * 8,
|
||||||
minTwo(NumberUtil.map(bottom.distance(new Pos(this.width, 0, 0)), 0, 400, -((double) this.width / 5), 200)) + baseNoise * 8,
|
minTwo(NumberUtil.map(bottom.distance(new Pos(this.width, 0, 0)), 0, 400, -((double) this.width / 5), 200)) + baseNoise * 8,
|
||||||
@@ -93,7 +91,7 @@ public class SquarePlateTerrainGenerator extends PlateTerrainGenerator {
|
|||||||
double currentHeight = Arrays.stream(possibleHeights).min().getAsDouble();
|
double currentHeight = Arrays.stream(possibleHeights).min().getAsDouble();
|
||||||
|
|
||||||
synchronized(this.batches) {
|
synchronized(this.batches) {
|
||||||
double elementNoise = this.batches.getNoise(bottom.x(), bottom.z());
|
double elementNoise = this.batches.evaluateNoise(bottom.x(), bottom.z());
|
||||||
|
|
||||||
unit.modifier().fill(
|
unit.modifier().fill(
|
||||||
bottom,
|
bottom,
|
||||||
@@ -104,7 +102,7 @@ public class SquarePlateTerrainGenerator extends PlateTerrainGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized(this.peaks) {
|
synchronized(this.peaks) {
|
||||||
double peakNoise = this.peaks.getNoise(bottom.x(), bottom.z());
|
double peakNoise = this.peaks.evaluateNoise(bottom.x(), bottom.z());
|
||||||
|
|
||||||
if(peakNoise > 0.97 && bottom.distance(new Pos(0, 0, 0)) > (this.width + 20)) {
|
if(peakNoise > 0.97 && bottom.distance(new Pos(0, 0, 0)) > (this.width + 20)) {
|
||||||
|
|
||||||
|
|||||||
@@ -174,3 +174,20 @@ startSpeed;Start Speed;Startgeschwindigkeit
|
|||||||
ns:game_BoatRace#;;
|
ns:game_BoatRace#;;
|
||||||
name;Boatrace;Bootrennen
|
name;Boatrace;Bootrennen
|
||||||
description;;
|
description;;
|
||||||
|
;;
|
||||||
|
ns:game_Pillars#;;
|
||||||
|
name;Pillars;Pillars
|
||||||
|
description;Build yourself up with your random blocks to reach your opponents and push them down!;Baue dich mit deinen zufälligen Blöcken zu deinen Gegnern und schupse sie runter!
|
||||||
|
;;
|
||||||
|
ns:game_BlockBattle#;;
|
||||||
|
name;Block Battle;Block Kampf
|
||||||
|
description;The team that fills the center with their color first wins!;Das Team, welches als erstes die Mitte mit seiner Farbe gefüllt hat, gewinnt!
|
||||||
|
itemCount;Block Count;Block Anzahl
|
||||||
|
;;
|
||||||
|
ns:game_ColorJump#;;
|
||||||
|
name;Color Jump;Farbsprung
|
||||||
|
description;Jump on the right color!;Springe auf die richtige Farbe!
|
||||||
|
;;
|
||||||
|
ns:game_PlayerRace#;;
|
||||||
|
name;Player Race;Wettrennen
|
||||||
|
description;Get to the other side as quickly as possible!;Komme so schnell wie möglich auf die andere Seite!
|
||||||
|
Reference in New Issue
Block a user