1 Commits

Author SHA1 Message Date
535008a31e startet implementation of buildBattle 2025-04-11 10:21:59 +02:00
179 changed files with 1994 additions and 3692 deletions

148
.gitignore vendored
View File

@@ -1,120 +1,3 @@
# Created by https://www.toptal.com/developers/gitignore/api/gradle,intellij,java
# Edit at https://www.toptal.com/developers/gitignore?templates=gradle,intellij,java
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
### Java ###
# Compiled class file # Compiled class file
*.class *.class
@@ -140,35 +23,8 @@ fabric.properties
hs_err_pid* hs_err_pid*
replay_pid* replay_pid*
### Gradle ### .idea
.gradle .gradle
**/build/ build/*
!src/**/build/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Avoid ignore Gradle wrappper properties
!gradle-wrapper.properties
# Cache of project
.gradletasknamecache
# Eclipse Gradle plugin generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
### Gradle Patch ###
# Java heap dump
*.hprof
# End of https://www.toptal.com/developers/gitignore/api/gradle,intellij,java
/resources/ /resources/
/build/
/bin/

3
.idea/.gitignore generated vendored
View File

@@ -1,3 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@@ -1,16 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="JAVA">
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_TRY_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Minigames" />
</state>
</component>

6
.idea/compiler.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="25" />
</component>
</project>

View File

@@ -1,7 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="UnqualifiedFieldAccess" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnqualifiedMethodAccess" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven3" />
<option name="name" value="maven3" />
<option name="url" value="https://oss.sonatype.org/content/repositories/snapshots" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="https://repo.unnamed.team/repository/unnamed-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven4" />
<option name="name" value="maven4" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>

5
.idea/misc.xml generated
View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK" />
</project>

9
.idea/modules.xml generated
View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Minigames.main.iml" filepath="$PROJECT_DIR$/.idea/modules/Minigames.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Minigames.test.iml" filepath="$PROJECT_DIR$/.idea/modules/Minigames.test.iml" />
</modules>
</component>
</project>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>ADVENTURE</platformType>
</autoDetectTypes>
<projectReimportVersion>1</projectReimportVersion>
</configuration>
</facet>
</component>
</module>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>ADVENTURE</platformType>
</autoDetectTypes>
<projectReimportVersion>1</projectReimportVersion>
</configuration>
</facet>
</component>
</module>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>ADVENTURE</platformType>
</autoDetectTypes>
<projectReimportVersion>1</projectReimportVersion>
</configuration>
</facet>
</component>
</module>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>ADVENTURE</platformType>
</autoDetectTypes>
<projectReimportVersion>1</projectReimportVersion>
</configuration>
</facet>
</component>
</module>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -3,7 +3,7 @@
plugins { plugins {
id 'java' id 'java'
id "com.github.johnrengelman.shadow" version "8.1.1" id "com.github.johnrengelman.shadow" version "7.1.0"
} }
group 'eu.mhsl.minenet' group 'eu.mhsl.minenet'
@@ -35,7 +35,7 @@ allprojects {
java { java {
toolchain { toolchain {
languageVersion = JavaLanguageVersion.of(25) languageVersion = JavaLanguageVersion.of(21)
} }
} }
@@ -44,11 +44,11 @@ dependencies {
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
//https://jitpack.io/#Minestom/Minestom //https://jitpack.io/#Minestom/Minestom
implementation 'net.minestom:minestom:2025.10.11-1.21.10' implementation 'net.minestom:minestom-snapshots:fd51c8d17a'
//Tools //Tools
implementation 'de.articdive:jnoise:3.0.2' implementation 'de.articdive:jnoise:3.0.2'
implementation 'net.md-5:bungeecord-config:1.21-R0.3' implementation 'net.md-5:bungeecord-config:1.19-R0.1-SNAPSHOT'
implementation 'org.apache.commons:commons-text:1.10.0' implementation 'org.apache.commons:commons-text:1.10.0'
implementation 'org.spongepowered:configurate-yaml:4.1.2' implementation 'org.spongepowered:configurate-yaml:4.1.2'
implementation 'com.sparkjava:spark-core:2.9.4' implementation 'com.sparkjava:spark-core:2.9.4'
@@ -57,7 +57,7 @@ dependencies {
//PvP //PvP
implementation 'io.github.TogAr2:MinestomPvP:56a831b41cb2ec6db8da681ad5d212ed7c71e3ee' implementation 'io.github.TogAr2:MinestomPvP:PR62-SNAPSHOT'
// Hephaestus engine // Hephaestus engine
implementation("team.unnamed:hephaestus-api:0.2.1-SNAPSHOT") implementation("team.unnamed:hephaestus-api:0.2.1-SNAPSHOT")

Binary file not shown.

View File

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

View File

@@ -3,13 +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 io.github.togar2.pvp.MinestomPvP;
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,8 +24,7 @@ public class Main {
private final static Logger logger = Logger.getGlobal(); private final static Logger logger = Logger.getGlobal();
public static ConfigurationNode globalConfig; public static ConfigurationNode globalConfig;
@SuppressWarnings("ResultOfMethodCallIgnored") public static void main(String[] args) throws ConfigurateException {
static void main() 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
@@ -41,35 +39,29 @@ public class Main {
logger.info("Initialize Minecraft server..."); logger.info("Initialize Minecraft server...");
MinecraftServer server = null; MinecraftServer server = MinecraftServer.init();
if(serverConfig.node("open-to-lan").getBoolean()) OpenToLAN.open(); // MinestomPvP.init();
if(globalConfig.node("bungeecord", "enabled").getBoolean()) {
server = MinecraftServer.init(new Auth.Bungee());
}
if(globalConfig.node("velocity", "enabled").getBoolean()) {
server = MinecraftServer.init(new Auth.Velocity(Objects.requireNonNull(globalConfig.node("velocity", "secret").getString())));
}
if(server == null) server = MinecraftServer.init();
MinestomPvP.init();
MinecraftServer.setBrandName("mhsl.eu - minenet - credits to minestom"); MinecraftServer.setBrandName("mhsl.eu - minenet - credits to minestom");
MinecraftServer.setCompressionThreshold(serverConfig.node("compression-threshold").getInt(0)); MinecraftServer.setCompressionThreshold(serverConfig.node("compression-threshold").getInt(0));
System.setProperty("minestom.chunk-view-distance", String.valueOf(serverConfig.node("view-distance").getInt())); System.setProperty("minestom.chunk-view-distance", String.valueOf(serverConfig.node("view-distance").getInt()));
System.setProperty("minestom.registry.unsafe-ops", "true");
Commands.values(); Commands.values();
Listeners.values(); Listeners.values();
Dimension.values();
new HttpServer(); new HttpServer();
MinecraftServer.getSchedulerManager().scheduleTask(new TablistUpdateTask(), TaskSchedule.tick(20), TaskSchedule.tick(20)); MinecraftServer.getSchedulerManager().scheduleTask(new TablistUpdateTask(), TaskSchedule.tick(20), TaskSchedule.tick(20));
logger.info("Starting Minecraft server ... "); logger.info("Starting Minecraft server ... ");
if(serverConfig.node("open-to-lan").getBoolean()) OpenToLAN.open();
if(globalConfig.node("bungeecord", "enabled").getBoolean()) BungeeCordProxy.enable();
if(globalConfig.node("velocity", "enabled").getBoolean()) {
VelocityProxy.enable(Objects.requireNonNull(globalConfig.node("velocity", "secret").getString()));
}
server.start("0.0.0.0", serverConfig.node("port").getInt(25565)); server.start("0.0.0.0", serverConfig.node("port").getInt(25565));
System.gc(); System.gc();

View File

@@ -21,7 +21,6 @@ public enum Resource {
private final Path path; private final Path path;
private final String name; private final String name;
Resource(String name, boolean keepOutdated) { Resource(String name, boolean keepOutdated) {
this.name = name; this.name = name;
this.path = Path.of("resources/" + name); this.path = Path.of("resources/" + name);
@@ -29,7 +28,7 @@ public enum Resource {
try { try {
Logger.getLogger("ressource").info("extracting resource " + name + " ... "); Logger.getLogger("ressource").info("extracting resource " + name + " ... ");
ResourceUtils.extractResource(name, keepOutdated); ResourceUtils.extractResource(name, keepOutdated);
} catch(URISyntaxException | IOException e) { } catch (URISyntaxException | IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@@ -39,10 +38,10 @@ public enum Resource {
} }
public Path getPath() { public Path getPath() {
return this.path; return path;
} }
public String getName() { public String getName() {
return this.name; return name;
} }
} }

View File

@@ -12,11 +12,11 @@ public abstract class Controller<Q, R> implements Route {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Controller() { public Controller() {
this.requestType = ((Class<Q>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]); this.requestType = ((Class<Q>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
} }
@Override @Override
public Object handle(Request request, Response response) { public Object handle(Request request, Response response) throws Exception {
response.header("Access-Control-Allow-Origin", "*"); response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Methods", "*"); response.header("Access-Control-Allow-Methods", "*");
@@ -28,7 +28,7 @@ public abstract class Controller<Q, R> implements Route {
req = new Gson().fromJson(request.body(), this.requestType); req = new Gson().fromJson(request.body(), this.requestType);
} }
return new Gson().toJson(this.handle(req, response)); return new Gson().toJson(handle(req, response));
} }
public abstract R handle(Q request, Response response); public abstract R handle(Q request, Response response);

View File

@@ -10,7 +10,6 @@ import static spark.Spark.*;
public class HttpServer { public class HttpServer {
private static final ConfigurationNode apiConfig = Main.globalConfig.node("api"); private static final ConfigurationNode apiConfig = Main.globalConfig.node("api");
public HttpServer() { public HttpServer() {
if(!apiConfig.node("enabled").getBoolean()) return; if(!apiConfig.node("enabled").getBoolean()) return;

View File

@@ -6,12 +6,8 @@ import spark.Response;
import java.util.UUID; import java.util.UUID;
record Req(UUID room) { record Req(UUID room) {}
} record Resp() {}
record Resp() {
}
public class CloseRoom extends Controller<Req, Resp> { public class CloseRoom extends Controller<Req, Resp> {
@Override @Override
public Resp handle(Req request, Response response) { public Resp handle(Req request, Response response) {

View File

@@ -6,12 +6,8 @@ import spark.Response;
import java.util.UUID; import java.util.UUID;
record Req() { record Req() {}
} record Resp(UUID uuid) {}
record Resp(UUID uuid) {
}
public class CreateRoom extends Controller<Req, Resp> { public class CreateRoom extends Controller<Req, Resp> {
@Override @Override
public Resp handle(Req request, Response response) { public Resp handle(Req request, Response response) {

View File

@@ -8,12 +8,8 @@ import spark.Response;
import java.util.UUID; import java.util.UUID;
record Req(UUID player, UUID room) { record Req(UUID player, UUID room) {}
} record Resp(String error) {}
record Resp(String error) {
}
public class QueueRoom extends Controller<Req, Resp> { public class QueueRoom extends Controller<Req, Resp> {
@Override @Override
public Resp handle(Req request, Response response) { public Resp handle(Req request, Response response) {

View File

@@ -1,8 +1,9 @@
package eu.mhsl.minenet.minigames.command; package eu.mhsl.minenet.minigames.command;
import eu.mhsl.minenet.minigames.command.privileged.SkinCommand;
import eu.mhsl.minenet.minigames.command.privileged.*;
import eu.mhsl.minenet.minigames.command.anonymous.HubCommand; import eu.mhsl.minenet.minigames.command.anonymous.HubCommand;
import eu.mhsl.minenet.minigames.command.anonymous.LeaveCommand; import eu.mhsl.minenet.minigames.command.anonymous.LeaveCommand;
import eu.mhsl.minenet.minigames.command.privileged.*;
import eu.mhsl.minenet.minigames.message.Icon; import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage; import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
@@ -20,6 +21,7 @@ public enum Commands {
ROOM(new RoomCommand()), ROOM(new RoomCommand()),
UPDATE(new RefreshCommandsCommand()), UPDATE(new RefreshCommandsCommand()),
OP(new OpCommand()), OP(new OpCommand()),
FAKEPLAYER(new FakeplayerCommand()),
KICK(new KickCommand()), KICK(new KickCommand()),
SKIN(new SkinCommand()), SKIN(new SkinCommand()),
SETOWNER(new SetRoomOwnerCommand()), SETOWNER(new SetRoomOwnerCommand()),
@@ -32,18 +34,14 @@ public enum Commands {
PLAYERLIMIT(new PlayerLimitCommand()), PLAYERLIMIT(new PlayerLimitCommand()),
SETMEMORIAL(new SetMemorialCommand()); SETMEMORIAL(new SetMemorialCommand());
static {
MinecraftServer.getCommandManager().setUnknownCommandCallback((sender, command) -> {
if(command.isBlank()) return;
new ChatMessage(Icon.ERROR)
.appendTranslated("common#unknownCommand")
.appendSpace()
.quote(command)
.send(sender);
});
}
Commands(Command handler) { Commands(Command handler) {
MinecraftServer.getCommandManager().register(handler); MinecraftServer.getCommandManager().register(handler);
} }
static {
MinecraftServer.getCommandManager().setUnknownCommandCallback((sender, command) -> {
if(command.isBlank()) return;
new ChatMessage(Icon.ERROR).appendStatic("Unknown command: ").quote(command).send(sender);
});
}
} }

View File

@@ -11,21 +11,20 @@ import java.util.List;
public class PrivilegedCommand extends Command { public class PrivilegedCommand extends Command {
private final List<CommandCondition> conditions = new ArrayList<>(); private final List<CommandCondition> conditions = new ArrayList<>();
public PrivilegedCommand(@NotNull String name, @Nullable String... aliases) { public PrivilegedCommand(@NotNull String name, @Nullable String... aliases) {
super(name, aliases); super(name, aliases);
this.construct(); construct();
} }
public PrivilegedCommand(@NotNull String name) { public PrivilegedCommand(@NotNull String name) {
super(name); super(name);
this.construct(); construct();
} }
private void construct() { private void construct() {
this.addCondition(this.isPrivileged()); addCondition(isPrivileged());
this.setCondition((sender, commandString) -> this.conditions.parallelStream().allMatch(condition -> condition.canUse(sender, commandString))); setCondition((sender, commandString) -> conditions.parallelStream().allMatch(condition -> condition.canUse(sender, commandString)));
} }
protected CommandCondition isPrivileged() { protected CommandCondition isPrivileged() {
@@ -33,6 +32,6 @@ public class PrivilegedCommand extends Command {
} }
protected void addCondition(CommandCondition condition) { protected void addCondition(CommandCondition condition) {
this.conditions.add(condition); conditions.add(condition);
} }
} }

View File

@@ -1,8 +1,8 @@
package eu.mhsl.minenet.minigames.command.anonymous; package eu.mhsl.minenet.minigames.command.anonymous;
import eu.mhsl.minenet.minigames.util.MoveInstance;
import eu.mhsl.minenet.minigames.instance.hub.Hub; import eu.mhsl.minenet.minigames.instance.hub.Hub;
import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.util.MoveInstance;
import net.minestom.server.command.builder.Command; import net.minestom.server.command.builder.Command;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
@@ -10,12 +10,12 @@ public class HubCommand extends Command {
public HubCommand() { public HubCommand() {
super("hub"); super("hub");
this.setCondition( setCondition(
(sender, commandString) -> (sender, commandString) ->
((Player) sender).getInstance() instanceof Room room && !room.apiDriven ((Player) sender).getInstance() instanceof Room room && !room.apiDriven
); );
this.setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
if(Room.getRoom((Player) sender).orElseThrow().apiDriven) return; if(Room.getRoom((Player) sender).orElseThrow().apiDriven) return;
Room.unsetRoom((Player) sender); Room.unsetRoom((Player) sender);
MoveInstance.move((Player) sender, Hub.INSTANCE); MoveInstance.move((Player) sender, Hub.INSTANCE);

View File

@@ -9,8 +9,8 @@ public class LeaveCommand extends Command {
public LeaveCommand() { public LeaveCommand() {
super("leave"); super("leave");
this.setCondition((sender, commandString) -> ((Player) sender).getInstance() instanceof Game); setCondition((sender, commandString) -> ((Player) sender).getInstance() instanceof Game);
this.setDefaultExecutor((sender, context) -> Room.setOwnRoom((Player) sender)); setDefaultExecutor((sender, context) -> Room.setOwnRoom((Player) sender));
} }
} }

View File

@@ -14,15 +14,15 @@ public class DebugCommand extends PrivilegedCommand {
public DebugCommand() { public DebugCommand() {
super("debug"); super("debug");
this.setDefaultExecutor((sender, args) -> { setDefaultExecutor((sender, args) -> {
new ChatMessage(Icon.CHAT).appendTranslated("sample").send(sender); new ChatMessage(Icon.CHAT).appendTranslated("sample").send(sender);
new ActionBarMessage().appendTranslated("sample").send(sender); new ActionBarMessage().appendTranslated("sample").send(sender);
new TitleMessage().subtitle(subtitleMessage -> subtitleMessage.appendTranslated("sample")).appendTranslated("sample").send(sender); new TitleMessage().subtitle(subtitleMessage -> subtitleMessage.appendTranslated("sample")).appendTranslated("sample").send(sender);
List<String> testplayers = new ArrayList<>() { List<String> testplayers = new ArrayList<>() {
{ {
this.add("MineTec"); add("MineTec");
this.add("Goldi187"); add("Goldi187");
this.add("Test"); add("Test");
} }
}; };
new ChatMessage(Icon.STAR, true) new ChatMessage(Icon.STAR, true)

View File

@@ -0,0 +1,31 @@
package eu.mhsl.minenet.minigames.command.privileged;
import eu.mhsl.minenet.minigames.command.PrivilegedCommand;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.entity.Player;
import java.util.UUID;
public class FakeplayerCommand extends PrivilegedCommand {
public FakeplayerCommand() {
super("fakeplayer");
addSyntax((sender, context) -> {
if(sender instanceof Player p) {
if(p.getInstance() instanceof Room room) {
// FakePlayer.initPlayer( // TODO FakePlayer does no longer exists
// UUID.randomUUID(),
// context.getRaw("name"),
// new FakePlayerOption().setInTabList(true).setRegistered(true),
// fakePlayer -> Room.setRoom(fakePlayer, room)
// );
} else {
new ChatMessage(Icon.ERROR).appendStatic("Du musst dich in einer Raumlobby befinden!").send(sender);
}
}
}, ArgumentType.String("name"));
}
}

View File

@@ -8,7 +8,7 @@ public class FlyCommand extends PrivilegedCommand {
public FlyCommand() { public FlyCommand() {
super("fly"); super("fly");
this.setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
Player p = (Player) sender; Player p = (Player) sender;
p.setVelocity(new Vec(0, 5, 0)); p.setVelocity(new Vec(0, 5, 0));
p.setFlying(!p.isFlying()); p.setFlying(!p.isFlying());

View File

@@ -7,7 +7,7 @@ import net.minestom.server.entity.Player;
public class GameStartCommand extends PrivilegedCommand { public class GameStartCommand extends PrivilegedCommand {
public GameStartCommand() { public GameStartCommand() {
super("gameStart"); super("gameStart");
this.setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
Player player = (Player) sender; Player player = (Player) sender;
if(player.getInstance() instanceof StatelessGame game) { if(player.getInstance() instanceof StatelessGame game) {
game.startAccessor(); game.startAccessor();

View File

@@ -7,7 +7,7 @@ import net.minestom.server.entity.Player;
public class GameStopCommand extends PrivilegedCommand { public class GameStopCommand extends PrivilegedCommand {
public GameStopCommand() { public GameStopCommand() {
super("gameStop"); super("gameStop");
this.setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
Player player = (Player) sender; Player player = (Player) sender;
if(player.getInstance() instanceof StatelessGame game) { if(player.getInstance() instanceof StatelessGame game) {
game.stop(); game.stop();

View File

@@ -12,7 +12,7 @@ public class GameTimeoutCommand extends PrivilegedCommand {
ArgumentInteger timeout = ArgumentType.Integer("timeout"); ArgumentInteger timeout = ArgumentType.Integer("timeout");
this.addSyntax((sender, context) -> { addSyntax((sender, context) -> {
Player player = (Player) sender; Player player = (Player) sender;
if(player.getInstance() instanceof StatelessGame game) { if(player.getInstance() instanceof StatelessGame game) {
game.setTimeLimit(context.get(timeout)); game.setTimeLimit(context.get(timeout));

View File

@@ -11,7 +11,7 @@ public class GamemodeCommand extends PrivilegedCommand {
super("gamemode", "gm"); super("gamemode", "gm");
this.addSyntax((sender, context) -> ((Player) sender).setGameMode( addSyntax((sender, context) -> ((Player) sender).setGameMode(
context.get("target")), context.get("target")),
ArgumentType.Enum("target", GameMode.class).setFormat(ArgumentEnum.Format.LOWER_CASED) ArgumentType.Enum("target", GameMode.class).setFormat(ArgumentEnum.Format.LOWER_CASED)
); );

View File

@@ -1,18 +1,17 @@
package eu.mhsl.minenet.minigames.command.privileged; package eu.mhsl.minenet.minigames.command.privileged;
import eu.mhsl.minenet.minigames.command.PrivilegedCommand; import eu.mhsl.minenet.minigames.command.PrivilegedCommand;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage; import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.util.Monitoring; import eu.mhsl.minenet.minigames.util.Monitoring;
public class GcCommand extends PrivilegedCommand { public class GcCommand extends PrivilegedCommand {
private static long lastRun = System.currentTimeMillis(); private static long lastRun = System.currentTimeMillis();
public GcCommand() { public GcCommand() {
super("gc"); super("gc");
this.setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
long nextRun = (lastRun - (System.currentTimeMillis() - 30 * 1000)) / 1000; long nextRun = (lastRun - (System.currentTimeMillis() - 30*1000)) / 1000;
if(nextRun > 0) { if(nextRun > 0) {
new ChatMessage(Icon.ERROR).appendStatic("Please wait ").appendStatic(String.valueOf(nextRun)).appendStatic(" seconds before running GC again!").send(sender); new ChatMessage(Icon.ERROR).appendStatic("Please wait ").appendStatic(String.valueOf(nextRun)).appendStatic(" seconds before running GC again!").send(sender);
return; return;
@@ -27,7 +26,7 @@ public class GcCommand extends PrivilegedCommand {
new ChatMessage(Icon.SUCCESS).appendStatic("Garbage collector ran successfully!").newLine() new ChatMessage(Icon.SUCCESS).appendStatic("Garbage collector ran successfully!").newLine()
.appendStatic("before: ").appendStatic(String.valueOf(before)).appendStatic("MB").newLine() .appendStatic("before: ").appendStatic(String.valueOf(before)).appendStatic("MB").newLine()
.appendStatic("now: ").appendStatic(String.valueOf(after)).appendStatic("MB").newLine() .appendStatic("now: ").appendStatic(String.valueOf(after)).appendStatic("MB").newLine()
.appendStatic("difference: ").appendStatic(String.valueOf(before - after)).appendStatic("MB") .appendStatic("difference: ").appendStatic(String.valueOf(before-after)).appendStatic("MB")
.send(sender); .send(sender);
}); });
} }

View File

@@ -13,7 +13,7 @@ public class InstanceProxyMoveCommand extends PrivilegedCommand {
ArgumentWord serverArgument = new ArgumentWord("server"); ArgumentWord serverArgument = new ArgumentWord("server");
this.addSyntax((sender, context) -> { addSyntax((sender, context) -> {
Instance room = ((Player) sender).getInstance(); Instance room = ((Player) sender).getInstance();
room.getPlayers().forEach(player -> { room.getPlayers().forEach(player -> {
Room.unsetRoom(player); Room.unsetRoom(player);

View File

@@ -11,15 +11,15 @@ public class KickCommand extends PrivilegedCommand {
public KickCommand() { public KickCommand() {
super("kick"); super("kick");
this.addSyntax( addSyntax(
(sender, context) -> (sender, context) ->
this.kick(context.getRaw("player"), ""), kick(context.getRaw("player"), ""),
ArgumentType.Entity("player").onlyPlayers(true) ArgumentType.Entity("player").onlyPlayers(true)
); );
this.addSyntax( addSyntax(
(sender, context) -> (sender, context) ->
this.kick(context.getRaw("player"), context.getRaw("reason")), kick(context.getRaw("player"), context.getRaw("reason")),
ArgumentType.Entity("player").onlyPlayers(true), ArgumentType.Entity("player").onlyPlayers(true),
ArgumentType.String("reason") ArgumentType.String("reason")
); );

View File

@@ -1,8 +1,8 @@
package eu.mhsl.minenet.minigames.command.privileged; package eu.mhsl.minenet.minigames.command.privileged;
import eu.mhsl.minenet.minigames.command.PrivilegedCommand; import eu.mhsl.minenet.minigames.command.PrivilegedCommand;
import eu.mhsl.minenet.minigames.lang.Lang;
import eu.mhsl.minenet.minigames.lang.Languages; import eu.mhsl.minenet.minigames.lang.Languages;
import eu.mhsl.minenet.minigames.lang.Lang;
import eu.mhsl.minenet.minigames.message.Icon; import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.TranslatableMessage; import eu.mhsl.minenet.minigames.message.TranslatableMessage;
import eu.mhsl.minenet.minigames.message.type.ChatMessage; import eu.mhsl.minenet.minigames.message.type.ChatMessage;
@@ -13,11 +13,11 @@ public class LangTestCommand extends PrivilegedCommand {
public LangTestCommand() { public LangTestCommand() {
super("langtest"); super("langtest");
this.setDefaultExecutor((sender, context) -> this.sendMessage(Languages.getInstance().getLanguage((Player) sender), "sample").send(sender)); setDefaultExecutor((sender, context) -> sendMessage(Languages.getInstance().getLanguage((Player) sender), "sample").send(sender));
var targetString = ArgumentType.String("mapId"); var targetString = ArgumentType.String("mapId");
this.addSyntax((sender, context) -> this.sendMessage(Languages.getInstance().getLanguage((Player) sender), context.get("mapId")).send(sender), targetString); addSyntax((sender, context) -> sendMessage(Languages.getInstance().getLanguage((Player) sender), context.get("mapId")).send(sender), targetString);
} }
private TranslatableMessage sendMessage(Lang lang, String mapId) { private TranslatableMessage sendMessage(Lang lang, String mapId) {

View File

@@ -11,7 +11,7 @@ public class OpCommand extends PrivilegedCommand {
public OpCommand() { public OpCommand() {
super("op"); super("op");
this.addSyntax((sender, context) -> { addSyntax((sender, context) -> {
Player target = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("target")); Player target = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("target"));
if(target != null) { if(target != null) {
target.setPermissionLevel(4); target.setPermissionLevel(4);

View File

@@ -10,9 +10,8 @@ public class PlayerLimitCommand extends PrivilegedCommand {
ArgumentInteger count = ArgumentType.Integer("count"); ArgumentInteger count = ArgumentType.Integer("count");
this.addSyntax((sender, context) -> System.setProperty( addSyntax((sender, context) -> {
"minenet.playerlimit", System.setProperty("minenet.playerlimit", String.valueOf(context.get(count)));
String.valueOf(context.get(count)) }, count);
), count);
} }
} }

View File

@@ -13,11 +13,10 @@ import java.net.http.HttpResponse;
public class PublishRewardCommand extends PrivilegedCommand { public class PublishRewardCommand extends PrivilegedCommand {
private final HttpClient rewardPublishClient = HttpClient.newHttpClient(); private final HttpClient rewardPublishClient = HttpClient.newHttpClient();
public PublishRewardCommand() { public PublishRewardCommand() {
super("publishReward"); super("publishReward");
this.setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
try { try {
Room room = Room.getRoom((Player) sender).orElseThrow(); Room room = Room.getRoom((Player) sender).orElseThrow();
TournamentDisplay world = new TournamentDisplay(room.getTournament()); TournamentDisplay world = new TournamentDisplay(room.getTournament());
@@ -30,9 +29,9 @@ public class PublishRewardCommand extends PrivilegedCommand {
.build(); .build();
room.getTournament().getRewards(); room.getTournament().getRewards();
HttpResponse<Void> rawResponse = this.rewardPublishClient.send(giveRewardsRequest, HttpResponse.BodyHandlers.discarding()); HttpResponse<Void> rawResponse = rewardPublishClient.send(giveRewardsRequest, HttpResponse.BodyHandlers.discarding());
sender.sendMessage(String.format("Rewards published: HTTP %s", rawResponse.statusCode())); sender.sendMessage(String.format("Rewards published: HTTP %s", rawResponse.statusCode()));
} catch(Exception e) { } catch (Exception e) {
sender.sendMessage(e.getMessage()); sender.sendMessage(e.getMessage());
} }
}); });

View File

@@ -1,8 +1,8 @@
package eu.mhsl.minenet.minigames.command.privileged; package eu.mhsl.minenet.minigames.command.privileged;
import eu.mhsl.minenet.minigames.command.PrivilegedCommand; import eu.mhsl.minenet.minigames.command.PrivilegedCommand;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage; import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.message.Icon;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
@@ -10,7 +10,7 @@ public class RefreshCommandsCommand extends PrivilegedCommand {
public RefreshCommandsCommand() { public RefreshCommandsCommand() {
super("refreshCommands"); super("refreshCommands");
this.setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(Player::refreshCommands); MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(Player::refreshCommands);
new ChatMessage(Icon.SUCCESS).appendStatic("Updated command syntax!").send(sender); new ChatMessage(Icon.SUCCESS).appendStatic("Updated command syntax!").send(sender);
}); });

View File

@@ -1,10 +1,10 @@
package eu.mhsl.minenet.minigames.command.privileged; package eu.mhsl.minenet.minigames.command.privileged;
import eu.mhsl.minenet.minigames.command.PrivilegedCommand; import eu.mhsl.minenet.minigames.command.PrivilegedCommand;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.Icon; import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.TranslatableMessage; import eu.mhsl.minenet.minigames.message.TranslatableMessage;
import eu.mhsl.minenet.minigames.message.type.ChatMessage; import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.instance.room.Room;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -13,7 +13,7 @@ public class RoomCommand extends PrivilegedCommand {
public RoomCommand() { public RoomCommand() {
super("room"); super("room");
this.setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
TranslatableMessage out = new ChatMessage(Icon.SCIENCE).appendStatic("Rooms:").newLine(); TranslatableMessage out = new ChatMessage(Icon.SCIENCE).appendStatic("Rooms:").newLine();
Room.getAllRooms().forEach((roomInstance) -> out Room.getAllRooms().forEach((roomInstance) -> out

View File

@@ -20,22 +20,22 @@ public class SetMemorialCommand extends PrivilegedCommand {
ArgumentString titleArgument = ArgumentType.String("title"); ArgumentString titleArgument = ArgumentType.String("title");
ArgumentString loreArgument = ArgumentType.String("lore"); ArgumentString loreArgument = ArgumentType.String("lore");
materialArgument.setSuggestionCallback( materialArgument.setSuggestionCallback((sender, context, suggestion) -> {
(_, _, suggestion) -> Material Material
.values() .values()
.stream() .stream()
.map(material -> new SuggestionEntry(material.name(), Component.text(material.name()))) .map(material -> new SuggestionEntry(material.name(), Component.text(material.name())))
.forEach(suggestion::addEntry) .forEach(suggestion::addEntry);
); });
this.addSyntax((sender, context) -> { addSyntax((sender, context) -> {
Room Room
.getRoom((Player) sender) .getRoom((Player) sender)
.orElseThrow() .orElseThrow()
.getTournament() .getTournament()
.setMemorialConfiguration( .setMemorialConfiguration(
new MemorialConfiguration( new MemorialConfiguration(
Material.fromKey(context.get(materialArgument)), Material.fromNamespaceId(context.get(materialArgument)),
context.get(titleArgument), context.get(titleArgument),
context.get(loreArgument) context.get(loreArgument)
) )

View File

@@ -22,22 +22,22 @@ public class SetRewardCommand extends PrivilegedCommand {
ArgumentWord materialArgument = ArgumentType.Word("material"); ArgumentWord materialArgument = ArgumentType.Word("material");
ArgumentStringArray amountsArgument = ArgumentType.StringArray("amount"); ArgumentStringArray amountsArgument = ArgumentType.StringArray("amount");
materialArgument.setSuggestionCallback( materialArgument.setSuggestionCallback((sender, context, suggestion) -> {
(_, _, suggestion) -> Material Material
.values() .values()
.stream() .stream()
.map(material -> new SuggestionEntry(material.name(), Component.text(material.name()))) .map(material -> new SuggestionEntry(material.name(), Component.text(material.name())))
.forEach(suggestion::addEntry) .forEach(suggestion::addEntry);
); });
this.addSyntax((sender, context) -> { addSyntax((sender, context) -> {
Room Room
.getRoom((Player) sender) .getRoom((Player) sender)
.orElseThrow() .orElseThrow()
.getTournament() .getTournament()
.setRewardConfiguration( .setRewardConfiguration(
new RewardConfiguration( new RewardConfiguration(
Material.fromKey(context.get(materialArgument)), Material.fromNamespaceId(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())
) )
); );

View File

@@ -15,20 +15,21 @@ public class SetRoomOwnerCommand extends PrivilegedCommand {
public SetRoomOwnerCommand() { public SetRoomOwnerCommand() {
super("setRoomOwner"); super("setRoomOwner");
this.addCondition((sender, commandString) -> ((Player) sender).getInstance() instanceof Room); addCondition((sender, commandString) -> ((Player) sender).getInstance() instanceof Room);
this.setDefaultExecutor((sender, context) -> { setDefaultExecutor((sender, context) -> {
if(sender instanceof Player p) { if(sender instanceof Player p) {
Room.getRoom(p).orElseThrow().setOwner(p); Room.getRoom(p).orElseThrow().setOwner(p);
new ChatMessage(Icon.SUCCESS).appendTranslated("room#ownerSelf").send(sender); new ChatMessage(Icon.SUCCESS).appendStatic("You are now the owner of this room!").send(sender);
} }
}); });
this.addSyntax((sender, context) -> { addSyntax((sender, context) -> {
System.out.println("Test");
if(sender instanceof Player p) { if(sender instanceof Player p) {
Player newOwner = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("player")); Player newOwner = MinecraftServer.getConnectionManager().getOnlinePlayerByUsername(context.getRaw("player"));
Room.getRoom(p).orElseThrow().setOwner(Objects.requireNonNull(newOwner)); Room.getRoom(p).orElseThrow().setOwner(Objects.requireNonNull(newOwner));
new ChatMessage(Icon.SUCCESS).appendTranslated("room#ownerSet").send(sender); new ChatMessage(Icon.SUCCESS).appendStatic("The new owner has been set!").send(sender);
} }
}, ArgumentType.Entity("player").onlyPlayers(true)); }, ArgumentType.Entity("player").onlyPlayers(true));
} }

View File

@@ -9,7 +9,7 @@ public class SkinCommand extends PrivilegedCommand {
public SkinCommand() { public SkinCommand() {
super("skin"); super("skin");
this.addSyntax((sender, context) -> { addSyntax((sender, context) -> {
if(sender instanceof Player p) { if(sender instanceof Player p) {
p.setSkin(PlayerSkin.fromUsername(context.getRaw("target"))); p.setSkin(PlayerSkin.fromUsername(context.getRaw("target")));
} }

View File

@@ -1,17 +1,13 @@
package eu.mhsl.minenet.minigames.handler; package eu.mhsl.minenet.minigames.handler;
import eu.mhsl.minenet.minigames.handler.global.AddEntityToInstanceEventListener; import eu.mhsl.minenet.minigames.handler.global.*;
import eu.mhsl.minenet.minigames.handler.global.ChatFormatHandler;
import eu.mhsl.minenet.minigames.handler.global.PlayerLeaveHandler;
import eu.mhsl.minenet.minigames.handler.global.PlayerLoginHandler;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.event.EventListener; import net.minestom.server.event.EventListener;
public enum Listeners { public enum Listeners {
SPAWN(new AddEntityToInstanceEventListener()), SPAWN(new AddEntityToInstanceEventListener()),
LOGIN(new PlayerLoginHandler()), LOGIN(new PlayerLoginHandler()),
LEAVE(new PlayerLeaveHandler()), LEAVE(new PlayerLeaveHandler());
CHAT(new ChatFormatHandler());
Listeners(EventListener<?> event) { Listeners(EventListener<?> event) {
MinecraftServer.getGlobalEventHandler().addListener(event); MinecraftServer.getGlobalEventHandler().addListener(event);

View File

@@ -1,20 +0,0 @@
package eu.mhsl.minenet.minigames.handler.global;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import net.minestom.server.event.EventListener;
import net.minestom.server.event.player.PlayerChatEvent;
import org.jetbrains.annotations.NotNull;
public class ChatFormatHandler implements EventListener<PlayerChatEvent> {
@Override
public @NotNull Class<PlayerChatEvent> eventType() {
return PlayerChatEvent.class;
}
@Override
public @NotNull Result run(@NotNull PlayerChatEvent event) {
event.setFormattedMessage(new ChatMessage(Icon.CHAT).appendStatic(event.getRawMessage()).build(event.getPlayer()));
return Result.SUCCESS;
}
}

View File

@@ -1,9 +1,5 @@
package eu.mhsl.minenet.minigames.handler.global; package eu.mhsl.minenet.minigames.handler.global;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.EventListener; import net.minestom.server.event.EventListener;
import net.minestom.server.event.player.PlayerDisconnectEvent; import net.minestom.server.event.player.PlayerDisconnectEvent;
@@ -18,11 +14,7 @@ public class PlayerLeaveHandler implements EventListener<PlayerDisconnectEvent>
@Override @Override
public @NotNull Result run(@NotNull PlayerDisconnectEvent event) { public @NotNull Result run(@NotNull PlayerDisconnectEvent event) {
Player p = event.getPlayer(); Player p = event.getPlayer();
new ChatMessage(Icon.LEAVE) // new ChatMessage(Icon.SCIENCE).appendStatic("unübersetzter Leavetext: ").appendStatic(p.getDisplayName()).send(MinecraftServer.getConnectionManager().getOnlinePlayers());
.appendStatic(p.getName().color(NamedTextColor.GRAY))
.appendSpace()
.appendTranslated("common#leave", NamedTextColor.DARK_GRAY)
.send(MinecraftServer.getConnectionManager().getOnlinePlayers());
return Result.SUCCESS; return Result.SUCCESS;
} }
} }

View File

@@ -2,13 +2,13 @@ package eu.mhsl.minenet.minigames.handler.global;
import eu.mhsl.minenet.minigames.Main; import eu.mhsl.minenet.minigames.Main;
import eu.mhsl.minenet.minigames.api.QueuedPlayerRooms; import eu.mhsl.minenet.minigames.api.QueuedPlayerRooms;
import eu.mhsl.minenet.minigames.instance.hub.Hub;
import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.instance.transfer.Transfer; import eu.mhsl.minenet.minigames.instance.transfer.Transfer;
import eu.mhsl.minenet.minigames.skin.SkinCache; import eu.mhsl.minenet.minigames.skin.SkinCache;
import eu.mhsl.minenet.minigames.util.MoveInstance; import eu.mhsl.minenet.minigames.util.MoveInstance;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import eu.mhsl.minenet.minigames.instance.hub.Hub;
import net.minestom.server.event.EventListener; import net.minestom.server.event.EventListener;
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
import net.minestom.server.network.packet.server.play.TeamsPacket; import net.minestom.server.network.packet.server.play.TeamsPacket;
@@ -61,11 +61,12 @@ public class PlayerLoginHandler implements EventListener<AsyncPlayerConfiguratio
if(Objects.requireNonNull(Main.globalConfig.node("admins").getList(String.class)).stream().anyMatch(s -> s.equalsIgnoreCase(p.getUsername()))) { if(Objects.requireNonNull(Main.globalConfig.node("admins").getList(String.class)).stream().anyMatch(s -> s.equalsIgnoreCase(p.getUsername()))) {
p.setPermissionLevel(4); p.setPermissionLevel(4);
} }
} catch(SerializationException | NullPointerException ignored) { } catch (SerializationException | NullPointerException ignored) {}
}
Logger.getLogger("user").info(p.getUsername() + " joined"); Logger.getLogger("user").info(p.getUsername() + " joined");
// new ChatMessage(Icon.SCIENCE).appendStatic("unübersetzter Jointext: ").appendStatic(p.getUsername()).send(MinecraftServer.getConnectionManager().getOnlinePlayers());
return Result.SUCCESS; return Result.SUCCESS;
} }
} }

View File

@@ -1,50 +1,48 @@
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.RegistryKey; import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.world.DimensionType; import net.minestom.server.world.DimensionType;
import org.jetbrains.annotations.NotNull;
/** /**
* Prebuilt dimensions * Prebuilt dimensions
*/ */
public enum Dimension { public enum Dimension {
OVERWORLD( OVERWORLD(
Key.key("minenet:fullbright_overworld"), NamespaceID.from("minenet:fullbright_overworld"),
DimensionType DimensionType
.builder() .builder()
.ambientLight(1.0f) .ambientLight(2.0f)
.build() .build()
), ),
NETHER( NETHER(
Key.key("minenet:fullbright_nether"), NamespaceID.from("minenet:fullbright_nether"),
DimensionType DimensionType
.builder() .builder()
.ambientLight(1.0f) .ambientLight(2.0f)
.effects("minecraft:the_nether") .effects("minecraft:the_nether")
.build() .build()
), ),
THE_END( THE_END(
Key.key("minenet:fullbright_end"), NamespaceID.from("minenet:fullbright_end"),
DimensionType DimensionType
.builder() .builder()
.ambientLight(1.0f) .ambientLight(2.0f)
.effects("minecraft:the_end") .effects("minecraft:the_end")
.build() .build()
); );
public final DimensionType DIMENSION; public final DimensionType DIMENSION;
public final Key namespaceID; public final NamespaceID namespaceID;
public final RegistryKey<@NotNull DimensionType> key; public final DynamicRegistry.Key<DimensionType> key;
Dimension(NamespaceID namespaceID, DimensionType dimType) {
Dimension(Key namespaceID, DimensionType dimType) {
this.DIMENSION = dimType; this.DIMENSION = dimType;
this.namespaceID = namespaceID; this.namespaceID = namespaceID;
this.key = MinecraftServer.getDimensionTypeRegistry().register(this.namespaceID, this.DIMENSION); this.key = MinecraftServer.getDimensionTypeRegistry().register(namespaceID, DIMENSION);
} }
} }

View File

@@ -7,19 +7,19 @@ 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.RegistryKey; import net.minestom.server.instance.InstanceManager;
import net.minestom.server.registry.DynamicRegistry;
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 org.jetbrains.annotations.NotNull;
import java.util.UUID; import java.util.UUID;
public class MineNetInstance extends InstanceContainer { public class MineNetInstance extends InstanceContainer {
public MineNetInstance(RegistryKey<@NotNull DimensionType> type) { public MineNetInstance(DynamicRegistry.Key<DimensionType> type) {
super(UUID.randomUUID(), type); super(UUID.randomUUID(), type);
MinecraftServer.getInstanceManager().registerInstance(this); MinecraftServer.getInstanceManager().registerInstance(this);
this.eventNode() eventNode()
.addListener(AddEntityToInstanceEvent.class, this::onEntityAdd) .addListener(AddEntityToInstanceEvent.class, this::onEntityAdd)
.addListener(RemoveEntityFromInstanceEvent.class, this::onEntityRemove); .addListener(RemoveEntityFromInstanceEvent.class, this::onEntityRemove);
} }
@@ -38,7 +38,6 @@ public class MineNetInstance extends InstanceContainer {
/** /**
* Called when Player joins this instance * Called when Player joins this instance
*
* @param p player who is joining * @param p player who is joining
* @return setCanceled * @return setCanceled
*/ */
@@ -48,15 +47,18 @@ public class MineNetInstance extends InstanceContainer {
/** /**
* Called when Player leaves this instance * Called when Player leaves this instance
*
* @param p player who is leaving * @param p player who is leaving
*/ */
protected void onPlayerLeave(Player p) { protected void onPlayerLeave(Player p) {
} }
/**
*
* @param target
*/
public void destroy(Instance target) { public void destroy(Instance target) {
this.getPlayers().forEach(player -> { getPlayers().forEach(player -> {
if(target != null) if(target != null)
player.setInstance(target); player.setInstance(target);
else else

View File

@@ -1,14 +1,14 @@
package eu.mhsl.minenet.minigames.instance.game; package eu.mhsl.minenet.minigames.instance.game;
import eu.mhsl.minenet.minigames.instance.MineNetInstance; import eu.mhsl.minenet.minigames.instance.MineNetInstance;
import eu.mhsl.minenet.minigames.instance.Spawnable;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option; import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.Icon; import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage; import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.score.Score; import eu.mhsl.minenet.minigames.score.Score;
import eu.mhsl.minenet.minigames.util.CommonEventHandles; import eu.mhsl.minenet.minigames.util.CommonEventHandles;
import eu.mhsl.minenet.minigames.instance.Spawnable;
import eu.mhsl.minenet.minigames.instance.room.Room;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
@@ -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.RegistryKey; import net.minestom.server.registry.DynamicRegistry;
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;
@@ -28,56 +28,64 @@ import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger; import java.util.logging.Logger;
public abstract class Game extends MineNetInstance implements Spawnable { public abstract class Game extends MineNetInstance implements Spawnable {
protected final Random rnd = new Random();
protected final Logger logger;
protected Room parentRoom; protected Room parentRoom;
protected boolean isRunning = false; protected boolean isRunning = false;
protected boolean isBeforeBeginning = true; protected boolean isBeforeBeginning = true;
public Game(RegistryKey<@NotNull DimensionType> dimensionType) { protected final Random rnd = new Random(); //TODO better way than ths?
protected final Logger logger;
public Game(DynamicRegistry.Key<DimensionType> dimensionType) {
super(dimensionType); super(dimensionType);
MinecraftServer.getInstanceManager().registerInstance(this); MinecraftServer.getInstanceManager().registerInstance(this);
this.logger = Logger.getLogger("Game:" + this.getUuid()); logger = Logger.getLogger("Game:" + getUuid());
this.eventNode() eventNode()
.addListener(PlayerMoveEvent.class, this::onPlayerMove) .addListener(PlayerMoveEvent.class, this::onPlayerMove)
.addListener(PlayerBlockBreakEvent.class, this::onBlockBreak) .addListener(PlayerBlockBreakEvent.class, this::onBlockBreak)
.addListener(PlayerBlockPlaceEvent.class, this::onBlockPlace) .addListener(PlayerBlockPlaceEvent.class, this::onBlockPlace)
.addListener(ItemDropEvent.class, this::onItemDrop); .addListener(ItemDropEvent.class, this::onItemDrop);
} }
public static void initialize(GameFactory factory, List<Option<?>> options, Player owner) {
try {
Room originRoom = Room.getRoom(owner).orElseThrow();
Game game = factory.manufacture(originRoom, options);
game.load();
originRoom.moveMembersToInstance(game);
new ChatMessage(Icon.INFO)
.appendTranslated(factory.name())
.newLine()
.appendTranslated(factory.description())
.send(originRoom.getAllMembers());
} catch(Exception e) {
new ChatMessage(Icon.ERROR).appendStatic("Instance crashed: " + e.getMessage()).send(owner);
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> Room.getRoom(owner).orElseThrow().moveMembersToRoomLobby());
e.printStackTrace(System.err);
}
}
public Game setParent(Room parentRoom) { public Game setParent(Room parentRoom) {
this.parentRoom = parentRoom; this.parentRoom = parentRoom;
return this; return this;
} }
public static void initialize(GameFactory factory, List<Option<?>> options, Player owner) {
try {
Game game = factory.manufacture(Room.getRoom(owner).orElseThrow(), options);
game.load();
Room.getRoom(owner).orElseThrow().moveMembersToInstance(game);
MinecraftServer.getSchedulerManager().scheduleTask(() -> {
game.getPlayers().forEach(player -> new ChatMessage(Icon.SCIENCE)
.appendStatic(factory.name().getAssembled(player).asComponent())
.newLine()
.appendStatic(factory.description().getAssembled(player).asComponent())
.send(player));
return TaskSchedule.stop();
}, TaskSchedule.seconds(3));
} catch (Exception e) {
new ChatMessage(Icon.ERROR).appendStatic("Instance crashed: " + e.getMessage()).send(owner);
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> Room.getRoom(owner).orElseThrow().moveMembersToRoomLobby());
e.printStackTrace(System.err);
}
}
/** /**
* Load and start countdown * Load and start countdown
*/ */
public void load() { public void load() {
this.scheduler().submitTask(() -> { scheduler().submitTask(() -> {
CompletableFuture<Void> callback = new CompletableFuture<>(); CompletableFuture<Void> callback = new CompletableFuture<>();
this.onLoad(callback); this.onLoad(callback);
// callback.whenComplete((unused, throwable) -> this.start()); // callback.whenComplete((unused, throwable) -> this.start());
@@ -87,13 +95,13 @@ public abstract class Game extends MineNetInstance implements Spawnable {
} }
protected void start() { protected void start() {
this.isRunning = true; isRunning = true;
this.isBeforeBeginning = false; isBeforeBeginning = false;
this.onStart(); this.onStart();
} }
public void stop() { public void stop() {
this.isRunning = false; isRunning = false;
this.onStop(); this.onStop();
this.unload(); this.unload();
} }
@@ -101,12 +109,12 @@ public abstract class Game extends MineNetInstance implements Spawnable {
public void unload() { public void unload() {
this.onUnload(); this.onUnload();
this.getPlayers().forEach(Room::setOwnRoom); getPlayers().forEach(Room::setOwnRoom);
this.scheduler().scheduleTask(() -> { scheduler().scheduleTask(() -> {
this.logger.info("stopping game instance " + this.uuid); logger.info("stopping game instance " + this.uuid);
this.getPlayers().forEach(player -> player.kick("timeout")); getPlayers().forEach(player -> player.kick("timeout"));
MinecraftServer.getInstanceManager().unregisterInstance(this); MinecraftServer.getInstanceManager().unregisterInstance(this);
@@ -117,14 +125,9 @@ public abstract class Game extends MineNetInstance implements Spawnable {
callback.complete(null); callback.complete(null);
} }
protected void onStart() { protected void onStart() {}
} protected void onStop() {}
protected void onUnload() {}
protected void onStop() {
}
protected void onUnload() {
}
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
@@ -148,7 +151,7 @@ public abstract class Game extends MineNetInstance implements Spawnable {
} }
protected void checkAbandoned() { protected void checkAbandoned() {
this.scheduleNextTick((instance) -> { scheduleNextTick((instance) -> {
if(instance.getPlayers().isEmpty()) this.unload(); if(instance.getPlayers().isEmpty()) this.unload();
}); });
} }
@@ -158,10 +161,10 @@ public abstract class Game extends MineNetInstance implements Spawnable {
} }
public boolean isRunning() { public boolean isRunning() {
return this.isRunning; return isRunning;
} }
public Pos getSpawn() { public Pos getSpawn() {
return new Pos(0, 50, 0); return new Pos(0,50,0);
} }
} }

View File

@@ -1,27 +1,22 @@
package eu.mhsl.minenet.minigames.instance.game; package eu.mhsl.minenet.minigames.instance.game;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain.AcidRainFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle.BuildBattleFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.elytraRace.ElytraRaceFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace.BlockBreakRaceFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain.AcidRainFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube.DeathcubeFactory;
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.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.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;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.sumo.SumoFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.TetrisFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.TetrisFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tntrun.TntRunFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.tntrun.TntRunFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.TowerdefenseFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.towerdefense.TowerdefenseFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace.TrafficLightRaceFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.types.trafficlightrace.TrafficLightRaceFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.turtleGame.TurtleGameFactory;
public enum GameList { public enum GameList {
DEATHCUBE(new DeathcubeFactory(), GameType.JUMPNRUN), DEATHCUBE(new DeathcubeFactory(), GameType.JUMPNRUN),
@@ -36,29 +31,22 @@ public enum GameList {
TNTRUN(new TntRunFactory(), GameType.OTHER), TNTRUN(new TntRunFactory(), GameType.OTHER),
ANVILRUN(new AnvilRunFactory(), GameType.PVE), ANVILRUN(new AnvilRunFactory(), GameType.PVE),
ACIDRAIN(new AcidRainFactory(), GameType.PVE), ACIDRAIN(new AcidRainFactory(), GameType.PVE),
TURTLEGAME(new TurtleGameFactory(), GameType.PVE),
ELYTRARACE(new ElytraRaceFactory(), GameType.PVP), ELYTRARACE(new ElytraRaceFactory(), GameType.PVP),
SPLEEF(new SpleefFactory(), GameType.PVP), SPLEEF(new SpleefFactory(), GameType.PVP),
JUMPDIVE(new JumpDiveFactory(), GameType.JUMPNRUN), JUMPDIVE(new JumpDiveFactory(), GameType.JUMPNRUN),
SUMO(new SumoFactory(), GameType.PVP), BUILDBATTLE(new BuildBattleFactory(), GameType.OTHER);
HIGHGROUND(new HighGroundFactory(), GameType.PVP),
FASTBRIDGE(new FastbridgeFactory(), GameType.OTHER),
BLOCKBREAKRACE(new BlockBreakRaceFactory(), GameType.OTHER),
SPACESNAKE(new SpaceSnakeFactory(), GameType.PVP);
private final GameFactory factory; private final GameFactory factory;
private final GameType type; private final GameType type;
GameList(GameFactory factory, GameType type) { GameList(GameFactory factory, GameType type) {
this.factory = factory; this.factory = factory;
this.type = type; this.type = type;
} }
public GameFactory getFactory() { public GameFactory getFactory() {
return this.factory; return this.factory;
} }
public GameType getType() { public GameType getType() {
return this.type; return type;
} }
} }

View File

@@ -22,15 +22,15 @@ public enum GameType {
} }
public Material getIcon() { public Material getIcon() {
return this.icon; return icon;
} }
public TranslatedComponent getTitle() { public TranslatedComponent getTitle() {
return this.title; return title;
} }
public TranslatedComponent getDescription() { public TranslatedComponent getDescription() {
return this.description; return description;
} }

View File

@@ -9,12 +9,11 @@ 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.RegistryKey; import net.minestom.server.registry.DynamicRegistry;
import net.minestom.server.timer.ExecutionType; import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.Task; import net.minestom.server.timer.Task;
import net.minestom.server.timer.TaskSchedule; import net.minestom.server.timer.TaskSchedule;
import net.minestom.server.world.DimensionType; import net.minestom.server.world.DimensionType;
import org.jetbrains.annotations.NotNull;
import java.time.Duration; import java.time.Duration;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -27,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(RegistryKey<@NotNull DimensionType> dimensionType, String gameName, Score score) { public StatelessGame(DynamicRegistry.Key<DimensionType> dimensionType, String gameName, Score score) {
super(dimensionType); super(dimensionType);
this.score = score; this.score = score;
this.name = gameName; this.name = gameName;
@@ -38,7 +37,7 @@ public class StatelessGame extends Game {
} }
public String getName() { public String getName() {
return this.name; return name;
} }
public void setTimeLimit(int limit) { public void setTimeLimit(int limit) {
@@ -48,23 +47,20 @@ public class StatelessGame extends Game {
this.timePlayed = 0; this.timePlayed = 0;
} }
if(this.timeLimit > 0) { if(this.timeLimit > 0) {
this.timeLimitTask = this.scheduler().submitTask(() -> { this.timeLimitTask = scheduler().submitTask(() -> {
if(!this.isRunning || this.timeLimit == 0) return TaskSchedule.stop(); if(!isRunning || timeLimit == 0) return TaskSchedule.stop();
if(this.timeLimit <= this.timePlayed) { if(timeLimit <= timePlayed) {
this.stop(); stop();
return TaskSchedule.stop(); return TaskSchedule.stop();
} }
int timeLeft = this.timeLimit - this.timePlayed; int timeLeft = timeLimit - timePlayed;
switch(timeLeft) { switch (timeLeft) {
case 90, 60, 30, 10, 5, 4, 3, 2, 1 -> new ChatMessage(Icon.TIME) case 90, 60, 30, 10, 5, 4, 3, 2, 1 ->
.appendStatic(String.valueOf(timeLeft)) new ChatMessage(Icon.SCIENCE).appendStatic("Noch " + timeLeft + " Sekunden!").send(getPlayers());
.appendSpace()
.appendTranslated(timeLeft == 1 ? "common#secondsLeft_singular" : "common#secondsLeft_plural")
.send(this.getPlayers());
} }
this.timePlayed++; timePlayed++;
return TaskSchedule.seconds(1); return TaskSchedule.seconds(1);
}, ExecutionType.TICK_START); }, ExecutionType.TICK_START);
@@ -81,48 +77,37 @@ public class StatelessGame extends Game {
* When overriding make sure to call this::start after countdown! * When overriding make sure to call this::start after countdown!
*/ */
protected CompletableFuture<Void> countdownStart() { protected CompletableFuture<Void> countdownStart() {
Duration fadeIn = Duration.ofMillis(300); return new Countdown(TitleMessage.class)
Duration stay = Duration.ofMillis(700); .countdown(Audience.audience(getPlayers()), 5, countdownModifier -> countdownModifier.message = new TitleMessage(Duration.ofMillis(300), Duration.ofMillis(700))
.subtitle(subtitleMessage -> subtitleMessage.appendStatic(Component.text("in ", NamedTextColor.DARK_GREEN))
return new Countdown() .appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN))
.countdown( .appendStatic(Component.text(" seconds", NamedTextColor.DARK_GREEN))));
Audience.audience(this.getPlayers()),
5,
modifier -> modifier.message = new TitleMessage(fadeIn, stay)
.subtitle(subtitleMessage -> subtitleMessage
.appendTranslated("common#startIn", NamedTextColor.DARK_GREEN)
.appendSpace()
.appendStatic(Component.text(modifier.timeLeft, NamedTextColor.GREEN))
.appendSpace()
.appendTranslated(modifier.timeLeft == 1 ? "common#second" : "common#seconds", NamedTextColor.DARK_GREEN)
)
);
} }
public void startAccessor() { public void startAccessor() {
this.start(); this.start();
} }
@Override @Override
protected void start() { protected void start() {
this.score.setInstance(this); score.setInstance(this);
this.score.attachListeners(); score.attachListeners();
this.countdownStart().thenRun(super::start); countdownStart().thenRun(super::start);
} }
@Override @Override
public void stop() { public void stop() {
this.isRunning = false; isRunning = false;
this.onStop(); this.onStop();
this.getScore().insertRemainingPlayers(this.getPlayers()); getScore().insertRemainingPlayers(getPlayers());
this.publishScore(this.getScore()); this.publishScore(getScore());
this.countdownUnload(); countdownUnload();
} }
private void countdownUnload() { private void countdownUnload() {
new TitleMessage(Duration.ofSeconds(1)).appendTranslated("score#done").send(this.getPlayers()); new TitleMessage(Duration.ofSeconds(1)).appendTranslated("score#done").send(getPlayers());
this.scheduler().scheduleTask(this::unload, TaskSchedule.seconds(5), TaskSchedule.stop()); scheduler().scheduleTask(this::unload, TaskSchedule.seconds(5), TaskSchedule.stop());
} }
} }

View File

@@ -5,12 +5,12 @@ import java.util.ArrayList;
public class ConfigManager { public class ConfigManager {
private final ArrayList<Option<?>> items = new ArrayList<>(); private final ArrayList<Option<?>> items = new ArrayList<>();
public ConfigManager addOption(Option<?> option) { public ConfigManager addOption(Option option) {
this.items.add(option); items.add(option);
return this; return this;
} }
public ArrayList<Option<?>> getAll() { public ArrayList<Option<?>> getAll() {
return this.items; return items;
} }
} }

View File

@@ -4,18 +4,20 @@ import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.Restriction; import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.Restriction;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionData; import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionData;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler; import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent; import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory; import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
import eu.mhsl.minenet.minigames.util.InventoryItemAlignment; import eu.mhsl.minenet.minigames.util.InventoryItemAlignment;
import eu.mhsl.minenet.minigames.instance.room.Room;
import net.kyori.adventure.sound.Sound; import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.EventListener;
import net.minestom.server.event.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.inventory.InventoryType; import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.click.Click; import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.inventory.condition.InventoryConditionResult;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.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;
@@ -38,12 +40,12 @@ public class GameConfigurationInventory extends InteractableInventory {
this.factory = factory; this.factory = factory;
room.eventNode() room.eventNode()
.addListener(AddEntityToInstanceEvent.class, _ -> MinecraftServer.getSchedulerManager().scheduleNextTick(this::updatePlayButton)) .addListener(AddEntityToInstanceEvent.class, addEntityToInstanceEvent -> MinecraftServer.getSchedulerManager().scheduleNextTick(this::updatePlayButton))
.addListener(RemoveEntityFromInstanceEvent.class, _ -> MinecraftServer.getSchedulerManager().scheduleNextTick(this::updatePlayButton)); .addListener(RemoveEntityFromInstanceEvent.class, removeEntityFromInstanceEvent -> MinecraftServer.getSchedulerManager().scheduleNextTick(this::updatePlayButton));
ConfigManager config = factory.configuration(); ConfigManager config = factory.configuration();
this.setClickableItem( setClickableItem(
ItemStack.builder(Material.RED_WOOL) ItemStack.builder(Material.RED_WOOL)
.customName( .customName(
TranslatedComponent.byId("common#back") TranslatedComponent.byId("common#back")
@@ -52,13 +54,13 @@ public class GameConfigurationInventory extends InteractableInventory {
) )
.build(), .build(),
0, 0,
itemClick -> itemClick.player().closeInventory(), itemClick -> itemClick.getPlayer().closeInventory(),
true true
); );
this.setDummyItem(Material.BLACK_STAINED_GLASS_PANE, 1); setDummyItem(Material.BLACK_STAINED_GLASS_PANE,1);
this.setDummyItem( setDummyItem(
ItemStack.builder(Material.NAME_TAG) ItemStack.builder(Material.NAME_TAG)
.customName( .customName(
factory.name().setColor(NamedTextColor.GOLD).getAssembled(p) factory.name().setColor(NamedTextColor.GOLD).getAssembled(p)
@@ -67,16 +69,16 @@ public class GameConfigurationInventory extends InteractableInventory {
4 4
); );
this.setDummyItem(Material.BLACK_STAINED_GLASS_PANE, 7); setDummyItem(Material.BLACK_STAINED_GLASS_PANE,7);
this.updatePlayButton(); updatePlayButton();
for(int i = 9; i <= 17; i++) { for(int i = 9; i <= 17; i++) {
this.setDummyItem(Material.BLACK_STAINED_GLASS_PANE, i); setDummyItem(Material.BLACK_STAINED_GLASS_PANE, i);
} }
if(config == null) { if(config == null) {
this.setDummyItem( setDummyItem(
ItemStack.builder(Material.BARRIER) ItemStack.builder(Material.BARRIER)
.customName( .customName(
TranslatedComponent.byId("room#noOption").setColor(NamedTextColor.RED).getAssembled(p) TranslatedComponent.byId("room#noOption").setColor(NamedTextColor.RED).getAssembled(p)
@@ -93,9 +95,9 @@ public class GameConfigurationInventory extends InteractableInventory {
InventoryItemAlignment itemAlignment = new InventoryItemAlignment(config.getAll().size(), 3); InventoryItemAlignment itemAlignment = new InventoryItemAlignment(config.getAll().size(), 3);
for(Option<?> item : config.getAll()) { for(Option<?> item : config.getAll()) {
InventoryItemAlignment.ItemOffset current = itemAlignment.next(); InventoryItemAlignment.ItemOffset current = itemAlignment.next();
this.map.put(offset + current.get(), item); map.put(offset + current.get(), item);
this.setDummyItem( setDummyItem(
item.getCurrent(p), item.getCurrent(p),
offset + current.get() offset + current.get()
); );
@@ -105,61 +107,62 @@ public class GameConfigurationInventory extends InteractableInventory {
} }
@Override @Override
protected void onClick(Player player, int slot, Click clickType) { protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
inventoryConditionResult.setCancel(true);
if(!this.map.containsKey(slot)) return; if(!map.containsKey(slot)) return;
Option<?> item = this.map.get(slot); Option<?> item = map.get(slot);
this.setDummyItem( setDummyItem(
item.getNext(this.p), item.getNext(p),
slot slot
); );
this.update(); update();
} }
private void updatePlayButton() { private void updatePlayButton() {
RestrictionHandler restrictionHandler = this.factory.globalRestrictions(); RestrictionHandler restrictionHandler = factory.globalRestrictions();
RestrictionData restrictionData = new RestrictionData(this.room); RestrictionData restrictionData = new RestrictionData(room);
if(restrictionHandler.canPlay(restrictionData)) { if(restrictionHandler.canPlay(restrictionData)) {
this.setClickableItem( setClickableItem(
ItemStack.builder(!restrictionHandler.getWarnings(restrictionData).isEmpty() ? Material.YELLOW_WOOL : Material.GREEN_WOOL) ItemStack.builder(restrictionHandler.getWarnings(restrictionData).size() > 0 ? Material.YELLOW_WOOL : Material.GREEN_WOOL)
.customName(TranslatedComponent.byId("restriction#success").setColor(NamedTextColor.GREEN).getAssembled(this.p)) .customName(TranslatedComponent.byId("restriction#success").setColor(NamedTextColor.GREEN).getAssembled(p))
.lore(restrictionHandler.getWarnings(restrictionData).stream().map(translatedComponent -> translatedComponent.getAssembled(this.p)).collect(Collectors.toList())) .lore(restrictionHandler.getWarnings(restrictionData).stream().map(translatedComponent -> translatedComponent.getAssembled(p)).collect(Collectors.toList()))
.build(), .build(),
8, 8,
itemClick -> Game.initialize(this.factory, this.map.values().stream().toList(), itemClick.player()), itemClick -> Game.initialize(factory, map.values().stream().toList(), itemClick.getPlayer()),
true true
); );
} else { } else {
this.setClickableItem( setClickableItem(
ItemStack.builder(Material.RED_WOOL) ItemStack.builder(Material.RED_WOOL)
.customName(TranslatedComponent.byId("restriction#fail").setColor(NamedTextColor.RED).getAssembled(this.p)) .customName(TranslatedComponent.byId("restriction#fail").setColor(NamedTextColor.RED).getAssembled(p))
.lore( .lore(
restrictionHandler.getRestrictions() restrictionHandler.getRestrictions()
.stream() .stream()
.filter(iRestriction -> iRestriction.calculate(restrictionData).type().equals(Restriction.Type.FAIL)) .filter(iRestriction -> iRestriction.calculate(restrictionData).type().equals(Restriction.Type.FAIL))
.map(iRestriction -> iRestriction.calculate(restrictionData).description().getAssembled(this.p)) .map(iRestriction -> iRestriction.calculate(restrictionData).description().getAssembled(p))
.collect(Collectors.toList())) .collect(Collectors.toList()))
.build(), .build(),
8, 8,
itemClick -> { itemClick -> {
if(restrictionHandler.canPlay(restrictionData)) { if(restrictionHandler.canPlay(restrictionData)) {
this.updatePlayButton(); updatePlayButton();
return; return;
} }
itemClick.player().playSound(Sound.sound(SoundEvent.ENTITY_SILVERFISH_DEATH, Sound.Source.AMBIENT, 1f, 1f)); itemClick.getPlayer().playSound(Sound.sound(SoundEvent.ENTITY_SILVERFISH_DEATH, Sound.Source.AMBIENT, 1f, 1f));
}, },
false false
); );
} }
this.update(); update();
} }
} }

View File

@@ -12,11 +12,9 @@ import java.util.Map;
public interface GameFactory { public interface GameFactory {
TranslatedComponent name(); TranslatedComponent name();
default ConfigManager configuration() { default ConfigManager configuration() {
return null; return null;
} }
default RestrictionHandler globalRestrictions() { default RestrictionHandler globalRestrictions() {
return new RestrictionHandler(); return new RestrictionHandler();
} }
@@ -24,7 +22,6 @@ public interface GameFactory {
default Material symbol() { default Material symbol() {
return Material.GRASS_BLOCK; return Material.GRASS_BLOCK;
} }
default TranslatedComponent description() { default TranslatedComponent description() {
return TranslatedComponent.byId("GameFactory#missingDescription"); return TranslatedComponent.byId("GameFactory#missingDescription");
} }
@@ -32,17 +29,17 @@ public interface GameFactory {
Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception; Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception;
default Game manufacture(Room parent, List<Option<?>> configuration) throws Exception { default Game manufacture(Room parent, List<Option<?>> configuration) throws Exception {
if(configuration == null) return this.manufacture(parent); if(configuration == null) return manufacture(parent);
Map<String, Option<?>> cnf = new HashMap<>(); Map<String, Option<?>> cnf = new HashMap<>();
configuration.forEach(option -> cnf.put(option.getId(), option)); configuration.forEach(option -> cnf.put(option.getId(), option));
return this.manufacture(parent, cnf); return manufacture(parent, cnf);
} }
default Game manufacture(Room parent) throws Exception { default Game manufacture(Room parent) throws Exception {
if(this.configuration() == null) return this.manufacture(parent, List.of()); if(this.configuration() == null) return manufacture(parent, List.of());
return this.manufacture(parent, this.configuration().getAll()); return manufacture(parent, this.configuration().getAll());
} }
} }

View File

@@ -12,12 +12,12 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
public abstract class Option<T> { public abstract class Option<T> {
private RestrictionHandler restrictionHandler;
private final Material item; private final Material item;
private final TranslatedComponent name; private final TranslatedComponent name;
private final String id; private final String id;
private final List<T> options;
protected T currentValue; protected T currentValue;
private RestrictionHandler restrictionHandler; private final List<T> options;
private int pointer = 0; private int pointer = 0;
public Option(String id, Material item, TranslatedComponent name, List<T> options) { public Option(String id, Material item, TranslatedComponent name, List<T> options) {
@@ -26,45 +26,46 @@ public abstract class Option<T> {
this.name = name; this.name = name;
this.options = options; this.options = options;
this.currentValue = options.getFirst(); currentValue = options.getFirst();
}
public RestrictionHandler getRestrictionHandler() {
return this.restrictionHandler;
} }
public void setRestrictionHandler(RestrictionHandler restrictionHandler) { public void setRestrictionHandler(RestrictionHandler restrictionHandler) {
this.restrictionHandler = restrictionHandler; this.restrictionHandler = restrictionHandler;
} }
public RestrictionHandler getRestrictionHandler() {
return restrictionHandler;
}
public ItemStack getNext(Player p) { public ItemStack getNext(Player p) {
if(++this.pointer >= this.options.size()) this.pointer = 0; if(++pointer >= options.size()) pointer = 0;
this.currentValue = this.options.get(this.pointer); currentValue = options.get(pointer);
return this.getCurrent(p); return getCurrent(p);
} }
public ItemStack getCurrent(Player p) { public ItemStack getCurrent(Player p) {
String value = this.options.get(this.pointer).toString(); String value = options.get(pointer).toString();
return ItemStack.builder(this.item) return ItemStack.builder(item)
.customName(this.name.getAssembled(p)) .customName(name.getAssembled(p))
.lore(TranslatedComponent.byId("optionCommon#value").setColor(NamedTextColor.GOLD).getAssembled(p) .lore(TranslatedComponent.byId("optionCommon#value").setColor(NamedTextColor.GOLD).getAssembled(p)
.append(Component.text(": ")).append(Component.text(value))) .append(Component.text(": ")).append(Component.text(value)))
.build(); .build();
} }
public int getAsInt() { public int getAsInt() {
return Integer.parseInt(this.getAsString()); return Integer.parseInt(getAsString());
} }
public boolean getAsBoolean() { public boolean getAsBoolean() {
return Objects.equals(this.getAsString(), "true") || Objects.equals(this.getAsString(), "1"); return Objects.equals(getAsString(), "true") || Objects.equals(getAsString(), "1");
} }
public String getAsString() { public String getAsString() {
return this.currentValue.toString(); return currentValue.toString();
} }
public String getId() { public String getId() {
return this.id; return id;
} }
} }

View File

@@ -10,7 +10,7 @@ public record Restriction(TranslatedComponent name, TranslatedComponent descript
this.warnMessage = warnMessage; this.warnMessage = warnMessage;
this.type = type; this.type = type;
if(this.warnMessage == null && this.type.equals(Type.WARN)) { if (this.warnMessage == null && this.type.equals(Type.WARN)) {
throw new IllegalStateException("warnMessage cannot be null when RestrictionType is WARN"); throw new IllegalStateException("warnMessage cannot be null when RestrictionType is WARN");
} }
} }

View File

@@ -22,18 +22,18 @@ public class RestrictionHandler {
} }
public List<IRestriction> getRestrictions() { public List<IRestriction> getRestrictions() {
return this.restrictions; return restrictions;
} }
public boolean canPlay(RestrictionData data) { public boolean canPlay(RestrictionData data) {
if(this.restrictions.isEmpty()) return true; if(restrictions.size() < 1) return true;
return this.restrictions.stream() return this.restrictions.stream()
.noneMatch(iRestriction -> iRestriction.calculate(data).type().equals(Restriction.Type.FAIL)); .noneMatch(iRestriction -> iRestriction.calculate(data).type().equals(Restriction.Type.FAIL));
} }
public List<TranslatedComponent> getWarnings(RestrictionData data) { public List<TranslatedComponent> getWarnings(RestrictionData data) {
List<TranslatedComponent> warnings = new ArrayList<>(); List<TranslatedComponent> warnings = new ArrayList<>();
for(IRestriction r : this.restrictions) { for (IRestriction r : this.restrictions) {
Restriction calculated = r.calculate(data); Restriction calculated = r.calculate(data);
if(!calculated.type().equals(Restriction.Type.WARN)) continue; if(!calculated.type().equals(Restriction.Type.WARN)) continue;

View File

@@ -27,26 +27,26 @@ import java.util.concurrent.CompletableFuture;
public class AcidRain extends StatelessGame { public class AcidRain extends StatelessGame {
final private int radius = 20;
private int generationOffset = 0;
final private int roofHeight = 55;
private int difficulty = 0;
final JNoise noise = JNoise.newBuilder() final JNoise noise = JNoise.newBuilder()
.fastSimplex() .fastSimplex()
.setSeed(this.rnd.nextLong()) .setSeed(rnd.nextLong())
.setFrequency(0.09) .setFrequency(0.09)
.build(); .build();
final private int radius = 20;
final private int roofHeight = 55;
private int generationOffset = 0;
private int difficulty = 0;
public AcidRain() { public AcidRain() {
super(Dimension.OVERWORLD.key, "acidRain", new LastWinsScore()); super(Dimension.OVERWORLD.key, "acidRain", new LastWinsScore());
this.setGenerator( setGenerator(
new CircularPlateTerrainGenerator(this.radius) new CircularPlateTerrainGenerator(radius)
.setPlateHeight(50) .setPlateHeight(50)
.setPlatePallet(BlockPallet.STONE) .setPlatePallet(BlockPallet.STONE)
); );
this.eventNode().addListener(PlayerTickEvent.class, this::onPlayerTick); eventNode().addListener(PlayerTickEvent.class, this::onPlayerTick);
} }
@Override @Override
@@ -61,40 +61,39 @@ public class AcidRain extends StatelessGame {
MinecraftServer.getSchedulerManager().submitTask(() -> { MinecraftServer.getSchedulerManager().submitTask(() -> {
this.getPlayers().forEach(player -> { getPlayers().forEach(player -> {
player.sendPacket(new ParticlePacket(Particle.SNEEZE, 0, 60, 0, this.radius, this.radius, this.radius, 1f, 500)); player.sendPacket(new ParticlePacket(Particle.SNEEZE, 0, 60, 0, radius, radius, radius, 1f, 500));
player.sendPacket(new ParticlePacket(Particle.ITEM_SLIME, 0, 60, 0, this.radius, this.radius, this.radius, 1f, 500)); player.sendPacket(new ParticlePacket(Particle.ITEM_SLIME, 0, 60, 0, radius, radius, radius, 1f, 500));
}); });
if(!this.isRunning) return TaskSchedule.stop(); if(!isRunning) return TaskSchedule.stop();
return TaskSchedule.millis(100); return TaskSchedule.millis(100);
}, ExecutionType.TICK_END); }, ExecutionType.TICK_END);
MinecraftServer.getSchedulerManager().submitTask(() -> { MinecraftServer.getSchedulerManager().submitTask(() -> {
this.generationOffset++; generationOffset++;
this.generatePlatform(this.generationOffset); generatePlatform(generationOffset);
if(!this.isRunning) return TaskSchedule.stop(); if(!isRunning) return TaskSchedule.stop();
return TaskSchedule.millis((long) NumberUtil.map(50 - this.difficulty, 0, 50, 100, 1000)); return TaskSchedule.millis((long) NumberUtil.map(50 - difficulty, 0, 50, 100, 1000));
}, ExecutionType.TICK_END); }, ExecutionType.TICK_END);
MinecraftServer.getSchedulerManager().submitTask(() -> { MinecraftServer.getSchedulerManager().submitTask(() -> {
this.difficulty++; difficulty++;
if(this.difficulty >= 50) return TaskSchedule.stop(); if(difficulty >= 50) return TaskSchedule.stop();
return TaskSchedule.seconds(3); return TaskSchedule.seconds(3);
}); });
} }
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(playerMoveEvent.getNewPosition().y() < 50) this.playerDeath(playerMoveEvent.getPlayer()); if(playerMoveEvent.getNewPosition().y() < 50) playerDeath(playerMoveEvent.getPlayer());
} }
private void onPlayerTick(PlayerTickEvent playerTickEvent) { private void onPlayerTick(PlayerTickEvent playerTickEvent) {
if(this.isBeforeBeginning) return; if(isBeforeBeginning) return;
if(this.getBlock(playerTickEvent.getPlayer().getPosition().withY(this.roofHeight)).isAir()) if(getBlock(playerTickEvent.getPlayer().getPosition().withY(roofHeight)).isAir()) playerDeath(playerTickEvent.getPlayer());
this.playerDeath(playerTickEvent.getPlayer());
} }
private void generatePlatform(long offset) { private void generatePlatform(long offset) {
@@ -103,20 +102,19 @@ public class AcidRain extends StatelessGame {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = -radius; x <= radius; x++) { for(int x = -radius; x <= radius; x++) {
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, 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(noise.getNoise(x + offset, z + offset) > 0.4) continue;
batch.setBlock(x, this.roofHeight, z, Block.OAK_PLANKS); batch.setBlock(x, roofHeight, z, Block.OAK_PLANKS);
} }
} }
BatchUtil.loadAndApplyBatch(batch, this, () -> { BatchUtil.loadAndApplyBatch(batch, this, () -> {});
});
} }
private void playerDeath(Player p) { private void playerDeath(Player p) {
p.setGameMode(GameMode.SPECTATOR); p.setGameMode(GameMode.SPECTATOR);
this.getScore().insertResult(p); getScore().insertResult(p);
} }
@Override @Override

View File

@@ -1,8 +1,8 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun; package eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.LastWinsScore; import eu.mhsl.minenet.minigames.score.LastWinsScore;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.util.BatchUtil; import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
@@ -27,10 +27,10 @@ class AnvilRun extends StatelessGame {
final int spawnHeight = 30; final int spawnHeight = 30;
final int radius; final int radius;
int anvilsPerSecond;
final int seconds; final int seconds;
final int anvilHeight = 200; final int anvilHeight = 200;
final List<Pos> anvilSpawnPositions = new ArrayList<>(); final List<Pos> anvilSpawnPositions = new ArrayList<>();
int anvilsPerSecond;
public AnvilRun(int radius, int seconds) { public AnvilRun(int radius, int seconds) {
super(Dimension.OVERWORLD.key, "Anvil Run", new LastWinsScore()); super(Dimension.OVERWORLD.key, "Anvil Run", new LastWinsScore());
@@ -38,25 +38,25 @@ class AnvilRun extends StatelessGame {
this.seconds = seconds; this.seconds = seconds;
this.setGenerator(new CircularPlateTerrainGenerator(radius)); this.setGenerator(new CircularPlateTerrainGenerator(radius));
this.eventNode().addListener(EntityTickEvent.class, this::onEntityTick); eventNode().addListener(EntityTickEvent.class, this::onEntityTick);
} }
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = -this.radius; x <= this.radius; x++) { for(int x = -radius; x <= radius; x++) {
for(int z = -this.radius; z <= this.radius; z++) { for (int z = -radius; z <= radius; z++) {
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > this.radius) continue; if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue;
this.anvilSpawnPositions.add(new Pos(x + 0.5, this.anvilHeight, z + 0.5)); anvilSpawnPositions.add(new Pos(x+0.5, anvilHeight, z+0.5));
batch.setBlock(x, this.spawnHeight - 1, z, Block.SNOW_BLOCK); batch.setBlock(x, spawnHeight-1, z, Block.SNOW_BLOCK);
} }
} }
this.anvilsPerSecond = this.anvilSpawnPositions.size() / this.seconds; this.anvilsPerSecond = anvilSpawnPositions.size() / this.seconds;
Collections.shuffle(this.anvilSpawnPositions); Collections.shuffle(anvilSpawnPositions);
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null)); BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
} }
@@ -72,12 +72,12 @@ class AnvilRun extends StatelessGame {
super.onStart(); super.onStart();
Scheduler scheduler = MinecraftServer.getSchedulerManager(); Scheduler scheduler = MinecraftServer.getSchedulerManager();
for(int i = 0; i < this.anvilSpawnPositions.size(); i++) { for(int i=0; i<this.anvilSpawnPositions.size(); i++) {
final int j = i; final int j = i;
scheduler.scheduleTask( scheduler.scheduleTask(
() -> this.spawnAnvil(this.anvilSpawnPositions.get(j)), () -> spawnAnvil(this.anvilSpawnPositions.get(j)),
TaskSchedule.millis( TaskSchedule.millis(
(long) Math.floor((double) i / this.anvilsPerSecond * 1000) (long) Math.floor((double) i/this.anvilsPerSecond * 1000)
), ),
TaskSchedule.stop() TaskSchedule.stop()
); );
@@ -87,26 +87,25 @@ class AnvilRun extends StatelessGame {
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
super.onPlayerMove(playerMoveEvent); super.onPlayerMove(playerMoveEvent);
if(this.isBeforeBeginning && playerMoveEvent.getNewPosition().y() < this.spawnHeight - 2) { if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() < spawnHeight - 2) {
playerMoveEvent.setCancelled(true); playerMoveEvent.setCancelled(true);
playerMoveEvent.getPlayer().teleport(this.getSpawn()); playerMoveEvent.getPlayer().teleport(getSpawn());
return; return;
} }
if(playerMoveEvent.getNewPosition().y() < this.spawnHeight - 2) if(playerMoveEvent.getNewPosition().y() < spawnHeight - 2) getScore().insertResult(playerMoveEvent.getPlayer());
this.getScore().insertResult(playerMoveEvent.getPlayer());
} }
protected void onEntityTick(@NotNull EntityTickEvent entityTickEvent) { protected void onEntityTick(@NotNull EntityTickEvent entityTickEvent) {
if(!entityTickEvent.getEntity().getEntityType().equals(EntityType.FALLING_BLOCK)) return; if(!entityTickEvent.getEntity().getEntityType().equals(EntityType.FALLING_BLOCK)) return;
Pos anvilPosition = entityTickEvent.getEntity().getPosition(); Pos anvilPosition = entityTickEvent.getEntity().getPosition();
if(anvilPosition.y() > this.spawnHeight + 0.5) return; if(anvilPosition.y() > spawnHeight + 0.5) return;
if(anvilPosition.y() < this.spawnHeight - 3) entityTickEvent.getEntity().remove(); if(anvilPosition.y() < spawnHeight - 3) entityTickEvent.getEntity().remove();
if(this.getBlock(anvilPosition.withY(this.spawnHeight - 1)).isAir()) return; if(this.getBlock(anvilPosition.withY(spawnHeight-1)).isAir()) return;
this.setBlock(anvilPosition.withY(this.spawnHeight - 1), Block.AIR); this.setBlock(anvilPosition.withY(spawnHeight-1), Block.AIR);
} }
@Override @Override
public Pos getSpawn() { public Pos getSpawn() {
return new Pos(0, this.spawnHeight, 0); return new Pos(0, spawnHeight, 0);
} }
} }

View File

@@ -1,9 +1,9 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun; package eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun;
import eu.mhsl.minenet.minigames.instance.game.Game; 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.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option; import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption; import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent; import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
@@ -26,7 +26,7 @@ public class AnvilRunFactory implements GameFactory {
public ConfigManager configuration() { public ConfigManager configuration() {
return new ConfigManager() return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 5, 10, 15, 20, 25, 30)) .addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 5, 10, 15, 20, 25, 30))
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 10, 30, 60, 90, 120)); .addOption(new NumericOption("seconds", Material.STICK, TranslatedComponent.byId("optionCommon#seconds"), 10, 30, 60, 90, 120));
} }
@Override @Override

View File

@@ -10,7 +10,7 @@ public class Backrooms extends StatelessGame {
public Backrooms() { public Backrooms() {
super(Dimension.NETHER.key, "Backrooms", new NoScore()); super(Dimension.NETHER.key, "Backrooms", new NoScore());
BackroomsGenerator generator = new BackroomsGenerator(); BackroomsGenerator generator = new BackroomsGenerator();
this.setGenerator(unit -> generator.generateRoom(unit, 50)); setGenerator(unit -> generator.generateRoom(unit, 50));
} }
@Override @Override

View File

@@ -3,7 +3,6 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.generator.GenerationUnit; import net.minestom.server.instance.generator.GenerationUnit;
import net.minestom.server.instance.generator.UnitModifier; import net.minestom.server.instance.generator.UnitModifier;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public class BackroomsGenerator { public class BackroomsGenerator {
@@ -12,8 +11,8 @@ public class BackroomsGenerator {
var start = unit.absoluteStart(); var start = unit.absoluteStart();
var yPos = start.blockY() + y; var yPos = start.blockY() + y;
for(int x = 0; x < unit.size().blockX(); x++) { for (int x = 0; x < unit.size().blockX(); x++) {
for(int z = 0; z < unit.size().blockZ(); z++) { for (int z = 0; z < unit.size().blockZ(); z++) {
var xPos = start.blockX() + x; var xPos = start.blockX() + x;
var zPos = start.blockZ() + z; var zPos = start.blockZ() + z;
@@ -24,7 +23,7 @@ public class BackroomsGenerator {
modifier.setBlock(xPos, yPos + 4, zPos, Block.SMOOTH_STONE_SLAB); modifier.setBlock(xPos, yPos + 4, zPos, Block.SMOOTH_STONE_SLAB);
// idk man... dont ask about this // idk man... dont ask about this
if( if (
(x - 2) % 4 == 0 && ( (x - 2) % 4 == 0 && (
((z - 2) % 8 == 0) || ((z - 2) % 8 == 0) ||
((z - 2) % 8 == 1) || ((z - 2) % 8 == 1) ||
@@ -37,14 +36,14 @@ public class BackroomsGenerator {
} }
} }
this.generateWalls(modifier, start.blockX(), yPos + 1, start.blockZ()); generateWalls(modifier, start.blockX() + 0, yPos + 1, start.blockZ() + 0);
this.generateWalls(modifier, start.blockX() + 8, yPos + 1, start.blockZ()); generateWalls(modifier, start.blockX() + 8, yPos + 1, start.blockZ() + 0);
this.generateWalls(modifier, start.blockX(), yPos + 1, start.blockZ() + 8); generateWalls(modifier, start.blockX() + 0, yPos + 1, start.blockZ() + 8);
this.generateWalls(modifier, start.blockX() + 8, yPos + 1, start.blockZ() + 8); generateWalls(modifier, start.blockX() + 8, yPos + 1, start.blockZ() + 8);
} }
private void generateWalls(UnitModifier modifier, int xPos, int yPos, int zPos) { private void generateWalls(UnitModifier modifier, int xPos, int yPos, int zPos) {
this.generatePillar(modifier, xPos, yPos, zPos, Block.CHISELED_SANDSTONE); generatePillar(modifier, xPos, yPos, zPos, Block.CHISELED_SANDSTONE);
var random = ThreadLocalRandom.current(); var random = ThreadLocalRandom.current();
@@ -56,31 +55,31 @@ public class BackroomsGenerator {
var door1pos = random.nextInt(2, 6); var door1pos = random.nextInt(2, 6);
var door2pos = random.nextInt(2, 6); var door2pos = random.nextInt(2, 6);
if(wall1) { if (wall1) {
for(int x = xPos; x < xPos + 8; x++) { for (int x = xPos; x < xPos + 8; x++) {
this.generatePillar(modifier, x, yPos, zPos, Block.SMOOTH_SANDSTONE); generatePillar(modifier, x, yPos, zPos, Block.SMOOTH_SANDSTONE);
} }
} }
if(wall2) { if (wall2) {
for(int z = zPos; z < zPos + 8; z++) { for (int z = zPos; z < zPos + 8; z++) {
this.generatePillar(modifier, xPos, yPos, z, Block.SMOOTH_SANDSTONE); generatePillar(modifier, xPos, yPos, z, Block.SMOOTH_SANDSTONE);
} }
} }
if(door1 && wall1) { if (door1 && wall1) {
this.generatePillar(modifier, xPos + door1pos, yPos, zPos, Block.AIR); generatePillar(modifier, xPos + door1pos, yPos, zPos, Block.AIR);
this.generatePillar(modifier, xPos + door1pos + 1, yPos, zPos, Block.AIR); generatePillar(modifier, xPos + door1pos + 1, yPos, zPos, Block.AIR);
} }
if(door2 && wall2) { if (door2 && wall2) {
this.generatePillar(modifier, xPos, yPos, zPos + door2pos, Block.AIR); generatePillar(modifier, xPos, yPos, zPos + door2pos, Block.AIR);
this.generatePillar(modifier, xPos, yPos, zPos + door2pos + 1, Block.AIR); generatePillar(modifier, xPos, yPos, zPos + door2pos + 1, Block.AIR);
} }
} }
private void generatePillar(UnitModifier modifier, int xPos, int yPos, int zPos, Block material) { private void generatePillar(UnitModifier modifier, int xPos, int yPos, int zPos, Block material) {
for(int y = yPos; y < yPos + 3; y++) { for (int y = yPos; y < yPos + 3; y++) {
modifier.setBlock(xPos, y, zPos, material); modifier.setBlock(xPos, y, zPos, material);
} }
} }

View File

@@ -29,9 +29,7 @@ import net.minestom.server.timer.TaskSchedule;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.List;
public class Bedwars extends StatelessGame { public class Bedwars extends StatelessGame {
@@ -41,13 +39,13 @@ public class Bedwars extends StatelessGame {
public Bedwars() throws IOException { public Bedwars() throws IOException {
super(Dimension.OVERWORLD.key, "Bedwars", new LastWinsScore()); super(Dimension.OVERWORLD.key, "Bedwars", new LastWinsScore());
this.setChunkLoader(new AnvilLoader(Resource.GAME_MAP.getPath().resolve("bedwars/test"))); setChunkLoader(new AnvilLoader(Resource.GAME_MAP.getPath().resolve("bedwars/test")));
Configuration config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(Resource.GAME_MAP.getPath().resolve("bedwars/test/config.yml").toFile()); Configuration config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(Resource.GAME_MAP.getPath().resolve("bedwars/test/config.yml").toFile());
List<String> teamNames = config.getStringList("setup.teams"); List<String> teamNames = config.getStringList("setup.teams");
teamNames.forEach(teamName -> { teamNames.forEach(teamName -> {
String path = "teams." + teamName; String path = "teams." + teamName;
this.teams.add(new BedwarsTeam( teams.add(new BedwarsTeam(
config.getString(path + ".name"), config.getString(path + ".name"),
Position.getPosFromCommaSeparated(config.getString(path + ".pos.spawn")), Position.getPosFromCommaSeparated(config.getString(path + ".pos.spawn")),
Position.getPosFromCommaSeparated(config.getString(path + ".pos.spawner")), Position.getPosFromCommaSeparated(config.getString(path + ".pos.spawner")),
@@ -56,7 +54,7 @@ public class Bedwars extends StatelessGame {
)); ));
}); });
this.eventNode().addListener(PickupItemEvent.class, pickupItemEvent -> { eventNode().addListener(PickupItemEvent.class, pickupItemEvent -> {
if(pickupItemEvent.getEntity() instanceof Player p) { if(pickupItemEvent.getEntity() instanceof Player p) {
p.getInventory().addItemStack(pickupItemEvent.getItemStack()); p.getInventory().addItemStack(pickupItemEvent.getItemStack());
} }
@@ -70,10 +68,10 @@ public class Bedwars extends StatelessGame {
@Override @Override
protected void onStart() { protected void onStart() {
this.scheduler().submitTask(() -> { scheduler().submitTask(() -> {
if(!this.isRunning) return TaskSchedule.stop(); if(!isRunning) return TaskSchedule.stop();
this.teams.forEach(bedwarsTeam -> { teams.forEach(bedwarsTeam -> {
ItemEntity item = new ItemEntity(ItemStack.of(bedwarsTeam.getBlock())); ItemEntity item = new ItemEntity(ItemStack.of(bedwarsTeam.getBlock()));
item.setNoGravity(true); item.setNoGravity(true);
item.setInstance(this, bedwarsTeam.getSpawner()); item.setInstance(this, bedwarsTeam.getSpawner());
@@ -86,17 +84,16 @@ public class Bedwars extends StatelessGame {
@Override @Override
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) { protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {
this.placedBlocks.add(playerBlockPlaceEvent.getBlockPosition()); placedBlocks.add(playerBlockPlaceEvent.getBlockPosition());
} }
@Override @Override
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent playerBlockBreakEvent) { protected void onBlockBreak(@NotNull PlayerBlockBreakEvent playerBlockBreakEvent) {
if(!this.placedBlocks.contains(playerBlockBreakEvent.getBlockPosition())) if(!placedBlocks.contains(playerBlockBreakEvent.getBlockPosition())) playerBlockBreakEvent.setCancelled(true);
playerBlockBreakEvent.setCancelled(true);
this.teams.forEach(bedwarsTeam -> { teams.forEach(bedwarsTeam -> {
if(Arrays.stream(bedwarsTeam.getBed()).anyMatch(pos -> pos.sameBlock(playerBlockBreakEvent.getBlockPosition()))) if(Arrays.stream(bedwarsTeam.getBed()).anyMatch(pos -> pos.sameBlock(playerBlockBreakEvent.getBlockPosition())))
this.breakBed(bedwarsTeam); breakBed(bedwarsTeam);
}); });
if(playerBlockBreakEvent.isCancelled()) if(playerBlockBreakEvent.isCancelled())
@@ -105,13 +102,13 @@ public class Bedwars extends StatelessGame {
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(playerMoveEvent.getNewPosition().y() < 0) this.death(playerMoveEvent.getPlayer()); if(playerMoveEvent.getNewPosition().y() < 0) death(playerMoveEvent.getPlayer());
} }
private void breakBed(BedwarsTeam team) { private void breakBed(BedwarsTeam team) {
team.removeBed(); team.removeBed();
for(Pos blockPos : team.getBed()) { for (Pos blockPos : team.getBed()) {
this.setBlock(blockPos, Material.AIR.block()); setBlock(blockPos, Material.AIR.block());
} }
} }

View File

@@ -8,12 +8,16 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class BedwarsTeam { public class BedwarsTeam {
private List<Player> members = new ArrayList<>();
private final String name; private final String name;
private final Pos spawn; private final Pos spawn;
private final Pos spawner; private final Pos spawner;
private final Pos[] bed; private final Pos[] bed;
private final Material block; private final Material block;
private List<Player> members = new ArrayList<>();
private boolean hasBed = true; private boolean hasBed = true;
public BedwarsTeam(String name, Pos spawn, Pos spawner, Pos[] bed, Material block) { public BedwarsTeam(String name, Pos spawn, Pos spawner, Pos[] bed, Material block) {
@@ -29,11 +33,11 @@ public class BedwarsTeam {
} }
public boolean isHasBed() { public boolean isHasBed() {
return this.hasBed; return hasBed;
} }
public List<Player> getMembers() { public List<Player> getMembers() {
return this.members; return members;
} }
public void setMembers(List<Player> members) { public void setMembers(List<Player> members) {
@@ -41,22 +45,22 @@ public class BedwarsTeam {
} }
public String getName() { public String getName() {
return this.name; return name;
} }
public Pos getSpawn() { public Pos getSpawn() {
return this.spawn; return spawn;
} }
public Pos getSpawner() { public Pos getSpawner() {
return this.spawner; return spawner;
} }
public Pos[] getBed() { public Pos[] getBed() {
return this.bed; return bed;
} }
public Material getBlock() { public Material getBlock() {
return this.block; return block;
} }
} }

View File

@@ -1,79 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class BlockBreakRace extends StatelessGame {
private final int height;
private int spawnCount = 0;
public BlockBreakRace(int height) {
super(Dimension.OVERWORLD.key, "blockBreakRace", new FirstWinsScore());
this.height = height;
this.setGenerator(new BlockBreakRaceGenerator(height));
}
@Override
protected boolean onPlayerJoin(Player p) {
PlayerInventory inv = p.getInventory();
inv.addItemStack(ItemStack.of(Material.DIAMOND_PICKAXE));
inv.addItemStack(ItemStack.of(Material.DIAMOND_AXE));
inv.addItemStack(ItemStack.of(Material.DIAMOND_SHOVEL));
return super.onPlayerJoin(p);
}
@Override
protected void onStart() {
this.getPlayers().forEach(player -> player.setGameMode(GameMode.SURVIVAL));
}
@Override
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent event) {
List<Material> allowedMaterials = List.of(Material.STONE, Material.OAK_PLANKS, Material.DIRT);
if(!allowedMaterials.contains(event.getBlock().registry().material())) event.setCancelled(true);
if(this.isBeforeBeginning) event.setCancelled(true);
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(this.isBeforeBeginning) return;
if(playerMoveEvent.getNewPosition().y() < BlockBreakRaceGenerator.BOTTOM_Y) {
Player player = playerMoveEvent.getPlayer();
this.getScore().insertResult(player);
player.setGameMode(GameMode.SPECTATOR);
player.getInventory().clear();
}
}
@Override
public Pos getSpawn() {
int idx = this.spawnCount++;
int cols = BlockBreakRaceGenerator.ROW_OFFSETS_X.length;
int rows = BlockBreakRaceGenerator.ROW_OFFSETS_Z.length;
int perChunk = cols * rows;
int zChunk = idx / perChunk;
int gridIndex = idx % perChunk;
int xIndex = gridIndex % cols;
int zIndex = gridIndex / cols;
int localX = BlockBreakRaceGenerator.ROW_OFFSETS_X[xIndex];
int localZ = BlockBreakRaceGenerator.ROW_OFFSETS_Z[zIndex];
int absZ = (zChunk * 16) + localZ;
return new Pos(localX, BlockBreakRaceGenerator.BOTTOM_Y + this.height + 1, absZ).add(0.5);
}
}

View File

@@ -1,40 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace;
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 BlockBreakRaceFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_BlockBreakRace#name");
}
@Override
public Material symbol() {
return Material.DIAMOND_PICKAXE;
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_BlockBreakRace#description");
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("height", Material.SCAFFOLDING, TranslatedComponent.byId("optionCommon#height"), 20, 30, 40, 50));
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new BlockBreakRace(configuration.get("height").getAsInt()).setParent(parent);
}
}

View File

@@ -1,65 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace;
import eu.mhsl.minenet.minigames.world.generator.featureEnriched.ValeGenerator;
import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.generator.GenerationUnit;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public class BlockBreakRaceGenerator extends BaseGenerator {
public static final int BOTTOM_Y = 50;
public static final int[] ROW_OFFSETS_X = {4, 8, 12};
public static final int[] ROW_OFFSETS_Z = {4, 8, 12};
private static final Block[] FILL_BLOCKS = {
Block.STONE,
Block.DIRT,
Block.OAK_PLANKS
};
public final int TOP_Y;
private final Random random = ThreadLocalRandom.current();
public BlockBreakRaceGenerator(int height) {
this.TOP_Y = BOTTOM_Y + height;
ValeGenerator vale = new ValeGenerator();
vale.setXShiftMultiplier(i -> 0.5d);
vale.setHeightNoiseMultiplier(i -> 2);
vale.setXShiftOffset(i -> 40d);
this.addMixIn(vale);
this.addMixIn(unit -> {
if(unit.absoluteStart().chunkX() != 0) return;
for(int localX : ROW_OFFSETS_X) {
for(int localZ : ROW_OFFSETS_Z) {
final int absZ = unit.absoluteStart().blockZ() + localZ;
this.placeTube(unit, localX, absZ);
}
}
});
}
private void placeTube(GenerationUnit unit, int x, int z) {
for(int y = BOTTOM_Y; y < this.TOP_Y; y++) {
Block fill = FILL_BLOCKS[this.random.nextInt(FILL_BLOCKS.length)];
unit.modifier().fill(
new Pos(x, y, z),
new Pos(x, y, z).add(1),
fill
);
}
for(int dx = -1; dx <= 1; dx++) {
for(int dz = -1; dz <= 1; dz++) {
if(dx == 0 && dz == 0) continue; // Zentrum überspringen
unit.modifier().fill(
new Pos(x + dx, BOTTOM_Y, z + dz),
new Pos(x + dx, this.TOP_Y + 3, z + dz).add(1),
Block.BARRIER
);
}
}
}
}

View File

@@ -9,9 +9,7 @@ import eu.mhsl.minenet.minigames.util.GeneratorUtils;
import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec; import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.*;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.metadata.other.PrimedTntMeta; import net.minestom.server.entity.metadata.other.PrimedTntMeta;
import net.minestom.server.event.EventListener; import net.minestom.server.event.EventListener;
import net.minestom.server.event.entity.projectile.ProjectileCollideWithBlockEvent; import net.minestom.server.event.entity.projectile.ProjectileCollideWithBlockEvent;
@@ -31,7 +29,6 @@ public class BowSpleef extends StatelessGame {
private static final Tag<Boolean> ARROW_FIRST_HIT = Tag.Boolean("ARROW_ALREADY_LIT"); private static final Tag<Boolean> ARROW_FIRST_HIT = Tag.Boolean("ARROW_ALREADY_LIT");
private final int radius = 30; private final int radius = 30;
private final int totalElevation = 50; private final int totalElevation = 50;
public BowSpleef() { public BowSpleef() {
super(Dimension.OVERWORLD.key, "bowSpleef", new LastWinsScore()); super(Dimension.OVERWORLD.key, "bowSpleef", new LastWinsScore());
@@ -70,7 +67,7 @@ public class BowSpleef extends StatelessGame {
// .build() // .build()
// ); // );
this.eventNode().addListener( eventNode().addListener(
EventListener EventListener
.builder(ProjectileCollideWithBlockEvent.class) .builder(ProjectileCollideWithBlockEvent.class)
.handler(projectileBlockHitEvent -> { .handler(projectileBlockHitEvent -> {
@@ -83,9 +80,9 @@ public class BowSpleef extends StatelessGame {
float radius = 0.5F; float radius = 0.5F;
Point arrowPos = projectile.getPosition(); Point arrowPos = projectile.getPosition();
GeneratorUtils.foreachXZ(arrowPos.add(radius), arrowPos.sub(radius), point -> { GeneratorUtils.foreachXZ(arrowPos.add(radius), arrowPos.sub(radius), point -> {
Point location = point.add(projectile.getVelocity().mul(0.04)).withY(this.totalElevation); Point location = point.add(projectile.getVelocity().mul(0.04)).withY(totalElevation);
if(!this.getBlock(location).isAir()) { if(!getBlock(location).isAir()) {
this.setBlock(location, Block.AIR); setBlock(location, Block.AIR);
Entity fallingTnt = new Entity(EntityType.TNT); Entity fallingTnt = new Entity(EntityType.TNT);
PrimedTntMeta fallingTntMeta = (PrimedTntMeta) fallingTnt.getEntityMeta(); PrimedTntMeta fallingTntMeta = (PrimedTntMeta) fallingTnt.getEntityMeta();
@@ -100,7 +97,7 @@ public class BowSpleef extends StatelessGame {
.build() .build()
); );
this.eventNode().addListener( eventNode().addListener(
EventListener EventListener
.builder(ProjectileCollideWithEntityEvent.class) .builder(ProjectileCollideWithEntityEvent.class)
.handler(projectileEntityHitEvent -> projectileEntityHitEvent.setCancelled(true)) .handler(projectileEntityHitEvent -> projectileEntityHitEvent.setCancelled(true))
@@ -112,11 +109,11 @@ public class BowSpleef extends StatelessGame {
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = -this.radius; x <= this.radius; x++) { for(int x = -radius; x <= radius; x++) {
for(int z = -this.radius; z <= this.radius; z++) { for(int z = -radius; z <= radius; z++) {
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > this.radius) continue; if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue;
batch.setBlock(x, this.totalElevation, z, Block.TNT); batch.setBlock(x, totalElevation, z, Block.TNT);
} }
} }
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null)); BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
@@ -124,7 +121,7 @@ public class BowSpleef extends StatelessGame {
@Override @Override
protected void onStart() { protected void onStart() {
this.getPlayers().forEach(player -> { getPlayers().forEach(player -> {
player.getInventory().setItemStack( player.getInventory().setItemStack(
0, 0,
ItemStack ItemStack
@@ -138,14 +135,14 @@ public class BowSpleef extends StatelessGame {
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(playerMoveEvent.getNewPosition().y() < this.totalElevation) { if(playerMoveEvent.getNewPosition().y() < totalElevation) {
this.getScore().insertResult(playerMoveEvent.getPlayer()); getScore().insertResult(playerMoveEvent.getPlayer());
playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR); playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
} }
} }
@Override @Override
public Pos getSpawn() { public Pos getSpawn() {
return new Pos(0, this.totalElevation + 1, 0); return new Pos(0, totalElevation + 1, 0);
} }
} }

View File

@@ -3,8 +3,6 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef;
import eu.mhsl.minenet.minigames.instance.game.Game; 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.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option; import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.RestrictionHandler;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MinimalPlayeramountGameRestriction;
import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent; import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import net.minestom.server.item.Material; import net.minestom.server.item.Material;
@@ -31,10 +29,4 @@ public class BowSpleefFactory implements GameFactory {
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception { public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new BowSpleef().setParent(parent); return new BowSpleef().setParent(parent);
} }
@Override
public RestrictionHandler globalRestrictions() {
return new RestrictionHandler()
.addRestriction(new MinimalPlayeramountGameRestriction(2));
}
} }

View File

@@ -0,0 +1,13 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.NoScore;
public class BuildBattle extends StatelessGame {
public BuildBattle() {
super(Dimension.OVERWORLD.key, "buildBattle", new NoScore());
}
}

View File

@@ -1,33 +1,21 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge; package eu.mhsl.minenet.minigames.instance.game.stateless.types.buildBattle;
import eu.mhsl.minenet.minigames.instance.game.Game; import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory; import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option; import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent; import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
import net.minestom.server.item.Material;
import java.util.Map; import java.util.Map;
public class FastbridgeFactory implements GameFactory { public class BuildBattleFactory implements GameFactory {
@Override @Override
public TranslatedComponent name() { public TranslatedComponent name() {
return TranslatedComponent.byId("game_Fastbridge#name"); return TranslatedComponent.byId("game_BuildBattle#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_Fastbridge#description");
}
@Override
public Material symbol() {
return Material.WHITE_WOOL;
} }
@Override @Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception { public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new Fastbridge().setParent(parent); return new BuildBattle();
} }
} }

View File

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

View File

@@ -1,14 +1,13 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube; package eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube;
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;
import eu.mhsl.minenet.minigames.util.BatchUtil; import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.world.BlockPallet; import eu.mhsl.minenet.minigames.world.BlockPallet;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import io.github.togar2.pvp.feature.CombatFeatures; import io.github.togar2.pvp.feature.CombatFeatures;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch; import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -26,27 +25,28 @@ class Deathcube extends StatelessGame {
this.radius = radius; this.radius = radius;
this.height = height + 49; this.height = height + 49;
this.percentage = percentage; this.percentage = percentage;
this.setGenerator(new CircularPlateTerrainGenerator(radius + 10).setPlateHeight(50)); this.setGenerator(new CircularPlateTerrainGenerator(radius+10).setPlateHeight(50));
if(pvpEnabled == 1) this.eventNode().addChild( if(pvpEnabled == 1) eventNode().addChild(
CombatFeatures.empty() CombatFeatures.empty()
.add(CombatFeatures.VANILLA_ATTACK) .add(CombatFeatures.VANILLA_ATTACK)
.add(CombatFeatures.VANILLA_DAMAGE) .add(CombatFeatures.VANILLA_DAMAGE)
.add(CombatFeatures.VANILLA_KNOCKBACK) .add(CombatFeatures.VANILLA_KNOCKBACK)
.build().createNode() .build().createNode()
); );
System.out.println(radius);
} }
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = -this.radius; x <= this.radius; x++) { for(int x = -radius; x <= radius; x++) {
for(int z = -this.radius; z <= this.radius; z++) { for (int z = -radius; z <= radius; z++) {
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > this.radius) continue; if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue;
for(int y = 49; y < this.height; y++) { for (int y = 49; y < height; y++) {
if(super.rnd.nextInt(1, 100) <= this.percentage) { if(super.rnd.nextInt(1, 100) <= percentage) {
batch.setBlock(x, y, z, BlockPallet.WOOD.rnd()); batch.setBlock(x, y, z, BlockPallet.WOOD.rnd());
} }
} }
@@ -61,20 +61,18 @@ class Deathcube extends StatelessGame {
super.onPlayerMove(playerMoveEvent); super.onPlayerMove(playerMoveEvent);
if(playerMoveEvent.getNewPosition().y() < 48) { if(playerMoveEvent.getNewPosition().y() < 48) {
playerMoveEvent.setCancelled(true); playerMoveEvent.setCancelled(true);
playerMoveEvent.getPlayer().teleport(this.getSpawn()); playerMoveEvent.getPlayer().teleport(getSpawn());
return; return;
} }
if(this.isBeforeBeginning && playerMoveEvent.getNewPosition().y() > 51.5) { if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() > 51.5) {
playerMoveEvent.setCancelled(true); playerMoveEvent.setCancelled(true);
return; return;
} }
if(playerMoveEvent.getNewPosition().y() <= this.height) return; if(playerMoveEvent.getNewPosition().y() > height) getScore().insertResult(playerMoveEvent.getPlayer());
this.getScore().insertResult(playerMoveEvent.getPlayer());
playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
} }
@Override @Override
public Pos getSpawn() { public Pos getSpawn() {
return new Pos(0, 50, -(this.radius + 5)); return new Pos(0, 50, -(radius+5));
} }
} }

View File

@@ -1,9 +1,9 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube; package eu.mhsl.minenet.minigames.instance.game.stateless.types.deathcube;
import eu.mhsl.minenet.minigames.instance.game.Game; 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.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option; import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption; import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent; import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;

View File

@@ -20,10 +20,7 @@ import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.EquipmentSlot; import net.minestom.server.entity.EquipmentSlot;
import net.minestom.server.entity.GameMode; import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.event.player.*;
import net.minestom.server.event.player.PlayerStartFlyingWithElytraEvent;
import net.minestom.server.event.player.PlayerStopFlyingWithElytraEvent;
import net.minestom.server.event.player.PlayerUseItemEvent;
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;
@@ -36,7 +33,6 @@ import org.jetbrains.annotations.NotNull;
import java.time.Duration; import java.time.Duration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Random;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -52,74 +48,80 @@ public class ElytraRace extends StatelessGame {
private final Material resetMaterial = Material.RED_DYE; private final Material resetMaterial = Material.RED_DYE;
private final int boostMultiplier = 50; private final int boostMultiplier = 50;
private final Material ringMaterial = Material.GOLD_BLOCK; private final Material ringMaterial = Material.GOLD_BLOCK;
private final Map<Player, CheckPointData> playerCheckpoints = new HashMap<>();
private int generatedUntil = 0; private int generatedUntil = 0;
private record CheckPointData(int currentCheckpoint, int nextCheckpoint) {
public CheckPointData next(int spacing) {
return new CheckPointData(nextCheckpoint, nextCheckpoint + spacing);
}
}
private final Map<Player, CheckPointData> playerCheckpoints = new HashMap<>();
public ElytraRace(int ringCount) { public ElytraRace(int ringCount) {
super(Dimension.OVERWORLD.key, "ElytraRace", new FirstWinsScore()); super(Dimension.OVERWORLD.key, "ElytraRace", new FirstWinsScore());
this.ringCount = ringCount; this.ringCount = ringCount;
this.setGenerator(this.vale); setGenerator(vale);
this.vale.setCalculateSeaLevel(point -> this.seaLevel); vale.setCalculateSeaLevel(point -> seaLevel);
this.vale.setXShiftMultiplier(integer -> NumberUtil.map(integer, 50, 500, 0, 1)); vale.setXShiftMultiplier(integer -> NumberUtil.map(integer, 50, 500, 0, 1));
this.vale.addMixIn(new PlaneTerrainGenerator(this.gameHeight, Block.BARRIER)); vale.addMixIn(new PlaneTerrainGenerator(gameHeight, Block.BARRIER));
this.eventNode().addListener(PlayerUseItemEvent.class, playerUseItemEvent -> { eventNode().addListener(PlayerUseItemEvent.class, playerUseItemEvent -> {
Player player = playerUseItemEvent.getPlayer(); Player player = playerUseItemEvent.getPlayer();
Material usedMaterial = playerUseItemEvent.getItemStack().material(); Material usedMaterial = playerUseItemEvent.getItemStack().material();
if(usedMaterial.equals(this.boostMaterial)) { if(usedMaterial.equals(boostMaterial)) {
if(!player.isFlyingWithElytra()) return; if(!player.isFlyingWithElytra()) return;
this.boost(player); boost(player);
InventoryUtil.removeItemFromPlayer(player, this.boostMaterial, 1); InventoryUtil.removeItemFromPlayer(player, boostMaterial, 1);
} else if(usedMaterial.equals(this.resetMaterial)) { } else if(usedMaterial.equals(resetMaterial)) {
this.toCheckpoint(player); toCheckpoint(player);
InventoryUtil.removeItemFromPlayer(player, this.resetMaterial, 1); InventoryUtil.removeItemFromPlayer(player, resetMaterial, 1);
} }
}); });
this.eventNode().addListener(PlayerStopFlyingWithElytraEvent.class, playerStopFlyingWithElytraEvent -> { eventNode().addListener(PlayerStopFlyingWithElytraEvent.class, playerStopFlyingWithElytraEvent -> {
Player player = playerStopFlyingWithElytraEvent.getPlayer(); Player player = playerStopFlyingWithElytraEvent.getPlayer();
if(Position.blocksBelowPlayer(this, player).contains(this.ringMaterial.block())) { if(Position.blocksBelowPlayer(this, player).contains(ringMaterial.block())) {
player.setFlyingWithElytra(true); player.setFlyingWithElytra(true);
this.boost(player); boost(player);
} else { } else {
this.toCheckpoint(player); toCheckpoint(player);
// getScore().insertResult(playerStopFlyingWithElytraEvent.getPlayer()); // getScore().insertResult(playerStopFlyingWithElytraEvent.getPlayer());
// playerStopFlyingWithElytraEvent.getPlayer().setGameMode(GameMode.SPECTATOR); // playerStopFlyingWithElytraEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
} }
}); });
this.eventNode().addListener(PlayerStartFlyingWithElytraEvent.class, playerStartFlyingWithElytraEvent -> { eventNode().addListener(PlayerStartFlyingWithElytraEvent.class, playerStartFlyingWithElytraEvent -> {
if(!this.isRunning) { if(!isRunning) {
playerStartFlyingWithElytraEvent.getPlayer().setFlyingWithElytra(false); playerStartFlyingWithElytraEvent.getPlayer().setFlyingWithElytra(false);
return; return;
} }
this.boost(playerStartFlyingWithElytraEvent.getPlayer()); boost(playerStartFlyingWithElytraEvent.getPlayer());
}); });
} }
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
Point spawnpoint = new Pos(this.vale.getXShiftAtZ(0), -46, 0); Point spawnpoint = new Pos(vale.getXShiftAtZ(0), -46, 0);
GeneratorUtils.iterateArea(spawnpoint.sub(5, 0, 5), spawnpoint.add(5, 0, 5), point -> this.setBlock(point, BlockPallet.STREET.rnd())); GeneratorUtils.iterateArea(spawnpoint.sub(5, 0, 5), spawnpoint.add(5, 0, 5), point -> setBlock(point, BlockPallet.STREET.rnd()));
this.generateRing(this.ringSpacing); generateRing(ringSpacing);
this.generateRing(this.ringSpacing * 2); generateRing(ringSpacing * 2);
callback.complete(null); callback.complete(null);
} }
@Override @Override
protected void onStart() { protected void onStart() {
this.getPlayers().forEach(player -> { getPlayers().forEach(player -> {
player.getInventory().setEquipment(EquipmentSlot.CHESTPLATE, (byte) 0, ItemStack.of(Material.ELYTRA)); player.getInventory().setEquipment(EquipmentSlot.CHESTPLATE, (byte) 0, ItemStack.of(Material.ELYTRA));
for(int i = 0; i < 3; i++) { for(int i = 0; i < 3; i++) {
player.getInventory().setItemStack(i, ItemStack.builder(this.boostMaterial).customName(TranslatedComponent.byId("boost").getAssembled(player)).build()); player.getInventory().setItemStack(i, ItemStack.builder(boostMaterial).customName(TranslatedComponent.byId("boost").getAssembled(player)).build());
} }
this.addResetItemToPlayer(player); addResetItemToPlayer(player);
}); });
} }
@@ -128,44 +130,44 @@ public class ElytraRace extends StatelessGame {
Player player = playerMoveEvent.getPlayer(); Player player = playerMoveEvent.getPlayer();
Point newPos = playerMoveEvent.getNewPosition(); Point newPos = playerMoveEvent.getNewPosition();
if(this.isBeforeBeginning && playerMoveEvent.getNewPosition().y() < this.getSpawn().y()) { if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() < getSpawn().y()) {
player.teleport(this.getSpawn()); player.teleport(getSpawn());
return; return;
} }
this.playerCheckpoints.putIfAbsent(player, new CheckPointData(this.ringSpacing, this.ringSpacing * 2)); playerCheckpoints.putIfAbsent(player, new CheckPointData(ringSpacing, ringSpacing * 2));
if(newPos.z() > this.generatedUntil - this.ringSpacing) { if(newPos.z() > generatedUntil - ringSpacing) {
this.generateRing(this.generatedUntil + this.ringSpacing); generateRing(generatedUntil + ringSpacing);
} }
if(newPos.z() > this.playerCheckpoints.get(player).nextCheckpoint) { if(newPos.z() > playerCheckpoints.get(player).nextCheckpoint) {
this.playerCheckpoints.put(player, this.playerCheckpoints.get(player).next(this.ringSpacing)); playerCheckpoints.put(player, playerCheckpoints.get(player).next(ringSpacing));
this.boost(player); boost(player);
} }
if(newPos.y() > this.gameHeight - 5) { if(newPos.y() > gameHeight - 5) {
Point particlePoint = newPos.withY(this.gameHeight); Point particlePoint = newPos.withY(gameHeight);
ParticlePacket particle = new ParticlePacket( ParticlePacket particle = new ParticlePacket(
Particle.WAX_ON, Particle.WAX_ON,
particlePoint.blockX(), particlePoint.blockX(),
particlePoint.blockY(), particlePoint.blockY(),
particlePoint.withZ(z -> z + 10).blockZ(), particlePoint.withZ(z -> z+10).blockZ(),
20, 20,
0, 0,
30, 30,
1f, 1f,
Math.toIntExact((long) NumberUtil.map(newPos.y(), this.gameHeight - 5, this.gameHeight, 50, 500)) Math.toIntExact((long) NumberUtil.map(newPos.y(), gameHeight - 5, gameHeight, 50, 500))
); );
player.sendPacket(particle); player.sendPacket(particle);
} }
if(this.getBlock(player.getPosition()).equals(Block.WATER)) { if(getBlock(player.getPosition()).equals(Block.WATER)) {
this.toCheckpoint(player); toCheckpoint(player);
} }
if(newPos.z() > this.ringCount * this.ringSpacing) { if(newPos.z() > ringCount * ringSpacing) {
this.getScore().insertResult(player); getScore().insertResult(player);
player.setGameMode(GameMode.SPECTATOR); player.setGameMode(GameMode.SPECTATOR);
player.setFlyingWithElytra(false); player.setFlyingWithElytra(false);
} }
@@ -173,35 +175,34 @@ public class ElytraRace extends StatelessGame {
@Override @Override
public Pos getSpawn() { public Pos getSpawn() {
return new Pos(this.vale.getXShiftAtZ(0), -45, 0); return new Pos(vale.getXShiftAtZ(0), -45, 0);
} }
private void addResetItemToPlayer(Player p) { private void addResetItemToPlayer(Player p) {
p.getInventory().setItemStack(8, ItemStack.builder(this.resetMaterial).customName(TranslatedComponent.byId("reset").getAssembled(p)).build()); p.getInventory().setItemStack(8, ItemStack.builder(resetMaterial).customName(TranslatedComponent.byId("reset").getAssembled(p)).build());
} }
private Point getRingPositionAtZ(int z) { private Point getRingPositionAtZ(int z) {
Random random = new Random(this.hashCode() + z); return new Pos(vale.getXShiftAtZ(z), -45, z);
return new Pos(this.vale.getXShiftAtZ(z), -45 + random.nextInt(-5, 15), z);
} }
private void generateRing(int zPos) { private CompletableFuture<Void> generateRing(int zPos) {
if(zPos > this.ringCount * this.ringSpacing) return; if(zPos > ringCount * ringSpacing) return null;
boolean isLast = (zPos == this.ringCount * this.ringSpacing); boolean isLast = (zPos == ringCount * ringSpacing);
this.generatedUntil = zPos; generatedUntil = zPos;
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
Point ringPos = this.getRingPositionAtZ(zPos); Point ringPos = getRingPositionAtZ(zPos);
GeneratorUtils.iterateArea( GeneratorUtils.iterateArea(
ringPos.sub(100, 0, 0).withY(0), ringPos.sub(100, 0, 0).withY(0),
ringPos.add(100, 0, 0).withY(this.seaLevel), ringPos.add(100, 0, 0).withY(seaLevel),
point -> batch.setBlock(point, Block.BARRIER) point -> batch.setBlock(point, Block.BARRIER)
); );
GeneratorUtils.iterateArea( GeneratorUtils.iterateArea(
ringPos.sub(3, 3, 0), ringPos.sub(3, 3, 0),
ringPos.add(3, 3, 0), ringPos.add(3, 3, 0),
point -> batch.setBlock(point, isLast ? Block.DIAMOND_BLOCK : this.ringMaterial.block()) point -> batch.setBlock(point, isLast ? Block.DIAMOND_BLOCK : ringMaterial.block())
); );
GeneratorUtils.iterateArea( GeneratorUtils.iterateArea(
ringPos.sub(2, 2, 0), ringPos.sub(2, 2, 0),
@@ -209,8 +210,8 @@ public class ElytraRace extends StatelessGame {
point -> batch.setBlock(point, Block.AIR) point -> batch.setBlock(point, Block.AIR)
); );
BatchUtil.loadAndApplyBatch(batch, this, () -> { BatchUtil.loadAndApplyBatch(batch, this, () -> {});
}); return null;
} }
private void boost(Player player) { private void boost(Player player) {
@@ -218,13 +219,13 @@ public class ElytraRace extends StatelessGame {
Vec playerVelocity = player.getPosition().direction(); Vec playerVelocity = player.getPosition().direction();
player.setVelocity( player.setVelocity(
player.getVelocity().add(playerVelocity.mul(this.boostMultiplier)) player.getVelocity().add(playerVelocity.mul(boostMultiplier))
.withY(playerVelocity.withY(v -> v * this.boostMultiplier).y()) .withY(playerVelocity.withY(v -> v * boostMultiplier).y())
); );
} }
private void toCheckpoint(Player p) { private void toCheckpoint(Player p) {
Point checkpointPos = this.getRingPositionAtZ(this.playerCheckpoints.get(p).currentCheckpoint); Point checkpointPos = getRingPositionAtZ(playerCheckpoints.get(p).currentCheckpoint);
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(Pos.fromPoint(checkpointPos).add(0.5, 0, 0.5));
@@ -232,7 +233,7 @@ public class ElytraRace extends StatelessGame {
p.setFlying(true); p.setFlying(true);
p.setFlyingSpeed(0); p.setFlyingSpeed(0);
new Countdown() new Countdown(TitleMessage.class)
.countdown( .countdown(
Audience.audience(p), Audience.audience(p),
3, 3,
@@ -244,24 +245,16 @@ public class ElytraRace extends StatelessGame {
.subtitle( .subtitle(
subtitleMessage -> subtitleMessage ->
subtitleMessage subtitleMessage
.appendTranslated("game_ElytraRace#launchIn") .appendStatic(Component.text("Launch in ", NamedTextColor.DARK_GREEN))
.appendSpace()
.appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN)) .appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN))
.appendSpace() .appendStatic(Component.text(" seconds", NamedTextColor.DARK_GREEN))
.appendTranslated(countdownModifier.timeLeft == 1 ? "common#second" : "common#seconds")
) )
).thenRun(() -> { ).thenRun(() -> {
p.setFlying(false); p.setFlying(false);
p.setFlyingSpeed(1); p.setFlyingSpeed(1);
p.setFlyingWithElytra(true); p.setFlyingWithElytra(true);
this.boost(p); boost(p);
this.addResetItemToPlayer(p); addResetItemToPlayer(p);
}); });
} }
private record CheckPointData(int currentCheckpoint, int nextCheckpoint) {
public CheckPointData next(int spacing) {
return new CheckPointData(this.nextCheckpoint, this.nextCheckpoint + spacing);
}
}
} }

View File

@@ -1,64 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class Fastbridge extends StatelessGame {
private int currentSpawn = 0;
public Fastbridge() {
super(Dimension.OVERWORLD.key, "Fastbridge", new FirstWinsScore());
this.setGenerator(new FastbridgeChunkgenerator());
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player player = playerMoveEvent.getPlayer();
Pos newPos = playerMoveEvent.getNewPosition();
if(this.getScore().hasResult(player)) return;
if(newPos.y() < 0) {
player.teleport(this.getSpawn());
if(!this.isBeforeBeginning) this.resetPlayer(player);
}
if(newPos.x() > 53) {
this.getScore().insertResult(player);
player.setGameMode(GameMode.SPECTATOR);
}
}
@Override
protected void onStart() {
this.getPlayers().forEach(player -> {
player.setGameMode(GameMode.SURVIVAL);
this.resetPlayer(player);
});
}
@Override
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {
if(this.isBeforeBeginning) playerBlockPlaceEvent.setCancelled(true);
}
private void resetPlayer(Player player) {
if(this.isBeforeBeginning) return;
PlayerInventory inventory = player.getInventory();
inventory.clear();
inventory.addItemStack(ItemStack.of(Material.WHITE_WOOL, 64));
}
@Override
public synchronized Pos getSpawn() {
return new Pos(24, 1, this.currentSpawn++ * Chunk.CHUNK_SIZE_Z * 2 - 8, -90, 0);
}
}

View File

@@ -1,29 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge;
import eu.mhsl.minenet.minigames.world.generator.featureEnriched.ValeGenerator;
import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator;
import net.minestom.server.instance.block.Block;
public class FastbridgeChunkgenerator extends BaseGenerator {
public FastbridgeChunkgenerator() {
this.addMixIn(unit -> {
if(unit.absoluteStart().chunkZ() % 2 == 0) {
unit.modifier().fill(Block.BARRIER);
return;
}
if(unit.absoluteStart().chunkX() != 1 && unit.absoluteStart().chunkX() != 3) return;
for(int x = 5; x <= 10; x++) {
for(int z = 5; z <= 10; z++) {
unit.modifier().setRelative(x, 64, z, unit.absoluteStart().chunkX() == 3 ? Block.GOLD_BLOCK : Block.GRASS_BLOCK);
}
}
});
ValeGenerator vale = new ValeGenerator();
vale.setXShiftMultiplier(integer -> 0.5d);
vale.setHeightNoiseMultiplier(integer -> 2);
vale.setXShiftOffset(integer -> 40d);
this.addMixIn(vale);
}
}

View File

@@ -1,127 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.highGround;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.PointsWinScore;
import eu.mhsl.minenet.minigames.world.BlockPallet;
import io.github.togar2.pvp.events.EntityKnockbackEvent;
import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.events.PrepareAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures;
import io.github.togar2.pvp.feature.knockback.KnockbackSettings;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.event.instance.InstanceTickEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
class HighGround extends StatelessGame {
private final int radius;
private final int seconds;
private final WeakHashMap<Player, Integer> scoreMap = new WeakHashMap<>();
HighGround(int radius, int seconds) {
super(Dimension.THE_END.key, "highground", new PointsWinScore());
this.radius = radius;
this.seconds = seconds;
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 -> finalAttackEvent.setBaseDamage(0)
);
this.eventNode().addListener(PrepareAttackEvent.class, prepareAttackEvent -> {
if(this.isBeforeBeginning) {
prepareAttackEvent.setCancelled(true);
}
});
this.eventNode().addListener(
EntityKnockbackEvent.class,
entityKnockbackEvent -> entityKnockbackEvent.setSettings(new KnockbackSettings(1.1, 1.1, 2, 0, 0))
);
this.eventNode().addListener(InstanceTickEvent.class, instanceTickEvent -> {
if(this.isBeforeBeginning || !this.isRunning) return;
this.getPlayers().forEach(player -> {
if((player.isOnGround() && player.getPosition().y() >= 1) || (!player.isOnGround() && player.getPosition().y() >= 1.5)) {
this.scoreMap.put(player, this.scoreMap.get(player) + 1);
player.setLevel(this.scoreMap.get(player) / 20);
player.setExp((this.scoreMap.get(player) % 20) / 20.0f);
}
});
});
}
@Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
for(int y = 0; y >= -3; y--) {
int radius = (Math.abs(y) * 5) + this.radius;
for(int x = -radius; x <= radius; x++) {
for(int z = -radius; z <= radius; z++) {
double distance = new Pos(x, 0, z).distance(0, 0, 0);
if(distance <= radius) {
this.setBlock(x, y, z, y == 0 ? Block.DIAMOND_BLOCK : Block.GRASS_BLOCK);
Pos featurePosition = new Pos(x, y + 1, z);
if(y >= 0 || this.getBlock(featurePosition).isSolid()) continue;
if(this.rnd.nextDouble() < 0.1) {
this.setBlock(featurePosition, Block.SHORT_GRASS);
}
if(this.rnd.nextDouble() < 0.01) {
this.setBlock(featurePosition, BlockPallet.FLOWER.rnd());
}
}
}
}
}
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player player = playerMoveEvent.getPlayer();
if(playerMoveEvent.getNewPosition().y() < -10) {
player.teleport(this.getSpawn());
}
}
@Override
protected void start() {
this.getPlayers().forEach(player -> this.scoreMap.put(player, 0));
super.start();
}
@Override
protected void onStart() {
this.setTimeLimit(this.seconds);
}
@Override
protected void onStop() {
this.getPlayers().forEach(player -> this.getScore().insertResult(player, this.scoreMap.get(player)));
}
@Override
public Pos getSpawn() {
double theta = this.rnd.nextDouble() * 2 * Math.PI;
double spawnRadius = this.radius + 5;
double x = spawnRadius * Math.cos(theta);
double z = spawnRadius * Math.sin(theta);
return new Pos(x, 0, z).withLookAt(new Pos(0, 0, 0));
}
}

View File

@@ -1,49 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.highGround;
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.game.stateless.config.restriction.RestrictionHandler;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MinimalPlayeramountGameRestriction;
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 HighGroundFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_Highground#name");
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_Highground#description");
}
@Override
public Material symbol() {
return Material.GOLDEN_HELMET;
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 3, 5, 7, 10))
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 30, 60, 90, 120));
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new HighGround(configuration.get("radius").getAsInt(), configuration.get("seconds").getAsInt()).setParent(parent);
}
@Override
public RestrictionHandler globalRestrictions() {
return new RestrictionHandler()
.addRestriction(new MinimalPlayeramountGameRestriction(2));
}
}

View File

@@ -35,10 +35,10 @@ public class JumpDive extends StatelessGame {
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = -this.radius * 2; x <= this.radius * 2; x++) { for(int x = -radius*2; x <= radius*2; x++) {
for(int z = -this.radius * 2; z <= this.radius * 2; z++) { for(int z = -radius*2; z <= radius*2; z++) {
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > this.radius) { if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) {
batch.setBlock(x, this.height, z, BlockPallet.STONE.rnd()); batch.setBlock(x, height, z, BlockPallet.STONE.rnd());
} else { } else {
batch.setBlock(x, 0, z, BlockPallet.GROUND.rnd()); batch.setBlock(x, 0, z, BlockPallet.GROUND.rnd());
batch.setBlock(x, 1, z, Block.WATER); batch.setBlock(x, 1, z, Block.WATER);
@@ -51,7 +51,7 @@ public class JumpDive extends StatelessGame {
@Override @Override
protected void onStart() { protected void onStart() {
this.setTimeLimit(this.timeLimit); setTimeLimit(timeLimit);
} }
@Override @Override
@@ -59,22 +59,22 @@ public class JumpDive extends StatelessGame {
Player p = playerMoveEvent.getPlayer(); Player p = playerMoveEvent.getPlayer();
if( if(
p.isOnGround() && playerMoveEvent.getNewPosition().y() < this.height p.isOnGround() && playerMoveEvent.getNewPosition().y() < height
|| playerMoveEvent.getNewPosition().y() < 0 || playerMoveEvent.getNewPosition().y() < 0
|| this.isBeforeBeginning && playerMoveEvent.getNewPosition().y() < this.height || isBeforeBeginning && playerMoveEvent.getNewPosition().y() < height
) { ) {
p.teleport(this.getSpawn()); p.teleport(getSpawn());
playerMoveEvent.setCancelled(true); playerMoveEvent.setCancelled(true);
} }
if( if(
playerMoveEvent.getNewPosition().y() <= 1 playerMoveEvent.getNewPosition().y() <= 1
&& playerMoveEvent.getNewPosition().distance(0, 1, 0) < this.radius + 0.5 && playerMoveEvent.getNewPosition().distance(0, 1, 0) < radius + 0.5
&& !(!this.isBeforeBeginning && !this.isRunning) && !(!isBeforeBeginning && !isRunning)
) { ) {
this.setBlock(playerMoveEvent.getNewPosition().withY(1), Block.REDSTONE_BLOCK); setBlock(playerMoveEvent.getNewPosition().withY(1), Block.REDSTONE_BLOCK);
this.scores.merge(p, 1, Integer::sum); scores.merge(p, 1, Integer::sum);
p.teleport(this.getSpawn()); p.teleport(getSpawn());
playerMoveEvent.setCancelled(true); playerMoveEvent.setCancelled(true);
p.playSound(Sound.sound(SoundEvent.ENTITY_EXPERIENCE_ORB_PICKUP, Sound.Source.PLAYER, 2f, 2f)); p.playSound(Sound.sound(SoundEvent.ENTITY_EXPERIENCE_ORB_PICKUP, Sound.Source.PLAYER, 2f, 2f));
} }
@@ -82,18 +82,18 @@ public class JumpDive extends StatelessGame {
@Override @Override
protected void onStop() { protected void onStop() {
this.getPlayers().forEach(player -> this.getScore().insertResult(player, this.scores.getOrDefault(player, 0))); getPlayers().forEach(player -> getScore().insertResult(player, scores.getOrDefault(player, 0)));
} }
@Override @Override
public Pos getSpawn() { public Pos getSpawn() {
double theta = this.rnd.nextDouble() * 2 * Math.PI; double theta = rnd.nextDouble() * 2 * Math.PI;
double spawnRadius = this.radius + 2; double spawnRadius = radius + 2;
double x = spawnRadius * Math.cos(theta); double x = spawnRadius * Math.cos(theta);
double z = spawnRadius * Math.sin(theta); double z = spawnRadius * Math.sin(theta);
return new Pos(x, this.height + 2, z).withLookAt(new Pos(0, this.height, 0)); return new Pos(x, height + 2, z).withLookAt(new Pos(0, height, 0));
} }
} }

View File

@@ -1,11 +1,11 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun; package eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun;
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;
import eu.mhsl.minenet.minigames.util.BatchUtil; import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.util.CommonProperties; import eu.mhsl.minenet.minigames.util.CommonProperties;
import eu.mhsl.minenet.minigames.util.Intersect; import eu.mhsl.minenet.minigames.util.Intersect;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.world.BlockPallet; import eu.mhsl.minenet.minigames.world.BlockPallet;
import eu.mhsl.minenet.minigames.world.generator.terrain.SquarePlateTerrainGenerator; import eu.mhsl.minenet.minigames.world.generator.terrain.SquarePlateTerrainGenerator;
import net.kyori.adventure.sound.Sound; import net.kyori.adventure.sound.Sound;
@@ -18,7 +18,7 @@ import net.minestom.server.instance.block.Block;
import net.minestom.server.sound.SoundEvent; import net.minestom.server.sound.SoundEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Random; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
class Minerun extends StatelessGame { class Minerun extends StatelessGame {
@@ -33,7 +33,7 @@ class Minerun extends StatelessGame {
public Minerun(int width, int length, int minePercentage) { public Minerun(int width, int length, int minePercentage) {
super(Dimension.THE_END.key, "Minerun", new FirstWinsScore()); super(Dimension.THE_END.key, "Minerun", new FirstWinsScore());
this.setGenerator(new SquarePlateTerrainGenerator(width, length + this.preRun + this.afterFinishLine).setPlateHeight(50).setGenerateBorders(true)); setGenerator(new SquarePlateTerrainGenerator(width, length + preRun + afterFinishLine).setPlateHeight(50).setGenerateBorders(true));
this.width = width; this.width = width;
this.length = length; this.length = length;
@@ -42,24 +42,24 @@ class Minerun extends StatelessGame {
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
int spawnToFinishLine = this.preRun + this.length + this.afterMines; int spawnToFinishLine = preRun + length + afterMines;
Random random = new Random(); Random random = new Random();
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = 0; x <= this.width; x++) { for(int x = 0; x <= width; x++) {
for(int z = this.preRun; z <= this.length + this.preRun; z++) { for(int z = preRun; z <= length + preRun; z++) {
if(random.nextInt(0, 100) < this.minePercentage) { if (random.nextInt(0, 100) < minePercentage) {
batch.setBlock(x, 50, z, BlockPallet.PRESSURE_PLATES.rnd()); batch.setBlock(x, 50, z, BlockPallet.PRESSURE_PLATES.rnd());
} }
} }
} }
for(int x = 0; x <= this.width; x++) { for(int x = 0; x <= width; x++) {
batch.setBlock(x, 49, spawnToFinishLine, Block.GOLD_BLOCK); batch.setBlock(x, 49, spawnToFinishLine, Block.GOLD_BLOCK);
batch.setBlock(x, 49, this.preRun, Block.GOLD_BLOCK); batch.setBlock(x, 49, preRun, Block.GOLD_BLOCK);
batch.setBlock(x, 50, this.preRun, Block.OAK_FENCE.withProperties(CommonProperties.fenceEastWest)); batch.setBlock(x, 50, preRun, Block.OAK_FENCE.withProperties(CommonProperties.fenceEastWest));
} }
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null)); BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
} }
@@ -67,11 +67,11 @@ class Minerun extends StatelessGame {
@Override @Override
protected void onStart() { protected void onStart() {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = 0; x <= this.width; x++) { for(int x = 0; x <= width; x++) {
batch.setBlock(x, 50, this.preRun, Block.AIR); batch.setBlock(x, 50, preRun, Block.AIR);
} }
BatchUtil.loadAndApplyBatch(batch, this, () -> this.playSound(Sound.sound(SoundEvent.BLOCK_WOOD_BREAK, Sound.Source.BLOCK, 1f, 1f))); BatchUtil.loadAndApplyBatch(batch, this, () -> playSound(Sound.sound(SoundEvent.BLOCK_WOOD_BREAK, Sound.Source.BLOCK, 1f, 1f)));
} }
@Override @Override
@@ -80,23 +80,23 @@ class Minerun extends StatelessGame {
Player p = playerMoveEvent.getPlayer(); Player p = playerMoveEvent.getPlayer();
Pos middle = playerMoveEvent.getNewPosition(); Pos middle = playerMoveEvent.getNewPosition();
if(this.isBeforeBeginning && middle.z() > this.preRun + 0.5) { //player cannot go forward before the game start if(isBeforeBeginning && middle.z() > preRun+0.5) { //player cannot go forward before the game start
playerMoveEvent.setCancelled(true); playerMoveEvent.setCancelled(true);
} }
if(Intersect.withPressurePlate(this, BlockPallet.PRESSURE_PLATES, middle)) { //Player died if(Intersect.withPressurePlate(this, BlockPallet.PRESSURE_PLATES, middle)) { //Player died
p.playSound(Sound.sound(SoundEvent.ENTITY_GENERIC_EXPLODE, Sound.Source.PLAYER, 1f, 1f)); p.playSound(Sound.sound(SoundEvent.ENTITY_GENERIC_EXPLODE, Sound.Source.PLAYER, 1f, 1f));
p.teleport(new Pos(p.getPosition().x(), this.getSpawn().y(), this.getSpawn().z())); p.teleport(new Pos(p.getPosition().x(), getSpawn().y(), getSpawn().z()));
} }
if(middle.z() > this.preRun + this.length + this.afterMines) { // Player finished if(middle.z() > preRun + length + afterMines) { // Player finished
this.getScore().insertResult(p); getScore().insertResult(p);
p.setGameMode(GameMode.SPECTATOR); p.setGameMode(GameMode.SPECTATOR);
} }
} }
@Override @Override
public Pos getSpawn() { public Pos getSpawn() {
return new Pos((double) this.width / 2, 50, 3); return new Pos((double) width /2, 50, 3);
} }
} }

View File

@@ -1,185 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.spaceSnake;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.PointsWinScore;
import eu.mhsl.minenet.minigames.util.MaterialUtil;
import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.events.PrepareAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures;
import net.kyori.adventure.sound.Sound;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
import net.minestom.server.event.entity.EntityTickEvent;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.WorldBorder;
import net.minestom.server.instance.block.Block;
import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.sound.SoundEvent;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class SpaceSnake extends StatelessGame {
private final Map<Player, PlayState> playerStates = new WeakHashMap<>();
private final Supplier<Integer> posInBoundsH = () -> this.rnd.nextInt(-60, 300);
private int mapSize;
private final Supplier<Integer> posInBoundsW = () -> this.rnd.nextInt(-this.mapSize / 2, this.mapSize / 2);
public SpaceSnake(int mapSize, int powerUpCount) {
super(Dimension.THE_END.key, "spaceSnake", new PointsWinScore());
this.mapSize = mapSize;
this.setWorldBorder(new WorldBorder(this.mapSize, 0, 0, 0, 0));
for(int i = 0; i < powerUpCount; i++) {
this.spawnPowerUp();
}
this.eventNode().addChild(
CombatFeatures.empty()
.add(CombatFeatures.VANILLA_ATTACK)
.add(CombatFeatures.VANILLA_DAMAGE)
.add(CombatFeatures.VANILLA_KNOCKBACK)
.build()
.createNode()
);
this.eventNode().addListener(PrepareAttackEvent.class, prepareAttackEvent -> {
if(this.isBeforeBeginning) prepareAttackEvent.setCancelled(true);
});
this.eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
finalAttackEvent.setBaseDamage(0);
((Player) finalAttackEvent.getTarget()).setHealth(20);
});
}
@Override
protected void onStart() {
this.getPlayers().forEach(player -> {
player.setGameMode(GameMode.SURVIVAL);
this.updateInv(player);
player.setHeldItemSlot((byte) 1);
});
}
@Override
protected void onStop() {
this.getPlayers().forEach(player -> this.getScore().insertResult(player, this.playerStates.get(player).length.get()));
}
@Override
protected boolean onPlayerJoin(Player p) {
Pos spawn = new Pos(this.posInBoundsW.get(), -60, this.posInBoundsW.get());
PlayState state = new PlayState(
new AtomicInteger(3),
new ArrayDeque<>(List.of(spawn)),
MaterialUtil.getRandomFullBlock(material -> !material.equals(Material.DIAMOND_BLOCK)),
spawn
);
this.playerStates.put(p, state);
this.setBlock(spawn, state.blockType.block());
MinecraftServer.getSchedulerManager().scheduleNextTick(
() -> p.teleport(this.getSaveSpawn(spawn))
);
return super.onPlayerJoin(p);
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
PlayState state = this.playerStates.get(playerMoveEvent.getPlayer());
if(this.isBeforeBeginning) {
boolean falling = state.blocks.stream().anyMatch(pos -> pos.y() > playerMoveEvent.getNewPosition().y());
if(falling) playerMoveEvent.getPlayer().teleport(this.getSaveSpawn(state.spawn));
return;
}
if(playerMoveEvent.getNewPosition().y() < -64) {
this.getScore().insertResult(playerMoveEvent.getPlayer(), state.length.get());
playerMoveEvent.getPlayer().teleport(this.getSpawn());
playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
long livingPlayers = this.getPlayers().stream()
.filter(p -> this.getScore().hasResult(p))
.count();
if(livingPlayers == 1) this.setTimeLimit(10);
if(livingPlayers == 0) this.stop();
}
}
@Override
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {
if(this.isBeforeBeginning) {
playerBlockPlaceEvent.setCancelled(true);
return;
}
PlayState state = this.playerStates.get(playerBlockPlaceEvent.getPlayer());
state.blocks.add(playerBlockPlaceEvent.getBlockPosition().asVec().asPosition());
state.cutToLength(pos -> this.setBlock(pos, Block.AIR));
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> this.updateInv(playerBlockPlaceEvent.getPlayer()));
playerBlockPlaceEvent.getPlayer().setLevel(state.length.get());
}
private Pos getSaveSpawn(Pos blockPos) {
return blockPos.add(0.5).withY((y) -> y + 2);
}
private void updateInv(Player player) {
PlayerInventory inventory = player.getInventory();
inventory.clear();
inventory.addItemStack(ItemStack.of(Material.STICK, 1).with(builder -> builder.glowing(true)));
inventory.addItemStack(ItemStack.of(this.playerStates.get(player).blockType, 64));
}
private void spawnPowerUp() {
Pos spawnPos = new Pos(this.posInBoundsW.get(), this.posInBoundsH.get(), this.posInBoundsW.get());
Entity display = new Entity(EntityType.FALLING_BLOCK);
((FallingBlockMeta) display.getEntityMeta()).setBlock(Block.DIAMOND_BLOCK);
display.setGlowing(true);
display.setNoGravity(true);
display.setInstance(this, spawnPos);
display.eventNode().addListener(EntityTickEvent.class, onTick -> {
Player player = this.getPlayers().stream()
.filter(p -> !this.getScore().hasResult(p))
.filter(p -> p.getBoundingBox()
.grow(1, 1, 1)
.intersectBox(display.getPosition().sub(p.getPosition()), display.getBoundingBox())
)
.findAny()
.orElse(null);
if(player == null) return;
this.spawnPowerUp();
display.remove();
this.onPowerup(player);
});
}
private void onPowerup(Player player) {
PlayState state = this.playerStates.get(player);
state.length.incrementAndGet();
player.setLevel(player.getLevel() + 1);
player.playSound(Sound.sound(SoundEvent.ENTITY_EXPERIENCE_ORB_PICKUP, Sound.Source.PLAYER, 1f, 1f));
}
record PlayState(AtomicInteger length, Queue<Pos> blocks, Material blockType, Pos spawn) {
public void cutToLength(Consumer<Pos> removed) {
while(this.blocks.size() > this.length.get()) {
removed.accept(this.blocks.poll());
}
}
}
}

View File

@@ -1,41 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.spaceSnake;
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 SpaceSnakeFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_SpaceSnake#name");
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("width", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#width"), 20, 30, 40, 50, 60, 70, 80))
.addOption(new NumericOption("powerUpCount", Material.DIAMOND, TranslatedComponent.byId("game_SpaceSnake#powerUpCount"), 50, 100, 200, 300));
}
@Override
public Material symbol() {
return Material.GREEN_CONCRETE_POWDER;
}
@Override
public TranslatedComponent description() {
return TranslatedComponent.byId("game_SpaceSnake#description");
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new SpaceSnake(configuration.get("width").getAsInt(), configuration.get("powerUpCount").getAsInt()).setParent(parent);
}
}

View File

@@ -9,45 +9,44 @@ import eu.mhsl.minenet.minigames.world.BlockPallet;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode; import net.minestom.server.entity.GameMode;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.event.player.PlayerStartDiggingEvent; import net.minestom.server.event.player.PlayerStartDiggingEvent;
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.*;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class Spleef extends StatelessGame { public class Spleef extends StatelessGame {
final int heightPerLevel = 20;
final int totalElevation = 50;
int radius; int radius;
int stackCount; int stackCount;
final int heightPerLevel = 20;
final int totalElevation = 50;
public Spleef(int radius, int stackCount) { public Spleef(int radius, int stackCount) {
super(Dimension.OVERWORLD.key, "Spleef", new LastWinsScore()); super(Dimension.OVERWORLD.key, "Spleef", new LastWinsScore());
this.getScore().setIgnoreLastPlayers(1); getScore().setIgnoreLastPlayers(1);
this.radius = radius; this.radius = radius;
this.stackCount = stackCount; this.stackCount = stackCount;
this.setGenerator(new CircularPlateTerrainGenerator(50)); setGenerator(new CircularPlateTerrainGenerator(50));
this.eventNode().addListener(PlayerStartDiggingEvent.class, this::destroyBlock); eventNode().addListener(PlayerStartDiggingEvent.class, this::destroyBlock);
} }
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
AbsoluteBlockBatch circle = new AbsoluteBlockBatch(); AbsoluteBlockBatch circle = new AbsoluteBlockBatch();
for(int level = 0; level < this.stackCount; level++) { for (int level = 0; level < stackCount; level++) {
for(int x = -this.radius; x <= this.radius; x++) { for(int x = -radius; x <= radius; x++) {
for(int z = -this.radius; z <= this.radius; z++) { for(int z = -radius; z <= radius; z++) {
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > this.radius) continue; if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue;
circle.setBlock(x, this.totalElevation + (level * this.heightPerLevel), z, BlockPallet.WINTER.rnd()); circle.setBlock(x, totalElevation + (level * heightPerLevel), z, BlockPallet.WINTER.rnd());
} }
} }
} }
@@ -57,7 +56,7 @@ public class Spleef extends StatelessGame {
@Override @Override
protected void onStart() { protected void onStart() {
this.getPlayers().forEach(player -> { getPlayers().forEach(player -> {
player.setGameMode(GameMode.SURVIVAL); player.setGameMode(GameMode.SURVIVAL);
player.getInventory().addItemStack( player.getInventory().addItemStack(
ItemStack ItemStack
@@ -71,29 +70,20 @@ public class Spleef extends StatelessGame {
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(playerMoveEvent.getNewPosition().y() < this.totalElevation) { if(playerMoveEvent.getNewPosition().y() < totalElevation) {
playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR); playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
playerMoveEvent.getPlayer().getInventory().clear(); playerMoveEvent.getPlayer().getInventory().clear();
this.getScore().insertResult(playerMoveEvent.getPlayer()); getScore().insertResult(playerMoveEvent.getPlayer());
} }
} }
@Override
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent event) {
if(!this.isRunning) {
event.setCancelled(true);
return;
}
this.setBlock(event.getBlockPosition(), Block.AIR);
}
private void destroyBlock(PlayerStartDiggingEvent event) { private void destroyBlock(PlayerStartDiggingEvent event) {
if(!this.isRunning) return; if(!isRunning) return;
this.setBlock(event.getBlockPosition(), Block.AIR); setBlock(event.getBlockPosition(), Block.AIR);
} }
@Override @Override
public Pos getSpawn() { public Pos getSpawn() {
return new Pos(0, this.totalElevation + this.heightPerLevel * (this.stackCount - 1) + 1, 0); return new Pos(0, totalElevation + heightPerLevel * (stackCount-1) + 1, 0);
} }
} }

View File

@@ -28,7 +28,7 @@ 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"), 5, 7, 9, 11));
} }
@Override @Override
@@ -40,7 +40,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().setParent(parent);
} }
@Override @Override

View File

@@ -2,7 +2,7 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight;
import eu.mhsl.minenet.minigames.instance.Dimension; import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.LowestPointsWinScore; import eu.mhsl.minenet.minigames.score.LastWinsScore;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator; import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import io.github.togar2.pvp.events.FinalAttackEvent; import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.feature.CombatFeatures; import io.github.togar2.pvp.feature.CombatFeatures;
@@ -13,21 +13,17 @@ import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class Stickfight extends StatelessGame { public class Stickfight extends StatelessGame {
private final double radius; private final double radius = 20;
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 boolean countdownStarted = false;
public Stickfight(int length) { public Stickfight() {
super(Dimension.OVERWORLD.key, "Stickfight", new LowestPointsWinScore()); super(Dimension.OVERWORLD.key, "Stickfight", new LastWinsScore());
this.radius = length;
this.eventNode().addChild( eventNode().addChild(
CombatFeatures.empty() CombatFeatures.empty()
.add(CombatFeatures.VANILLA_ATTACK) .add(CombatFeatures.VANILLA_ATTACK)
.add(CombatFeatures.VANILLA_DAMAGE) .add(CombatFeatures.VANILLA_DAMAGE)
@@ -35,88 +31,66 @@ public class Stickfight extends StatelessGame {
.build().createNode() .build().createNode()
); );
this.eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> { eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
if(this.isBeforeBeginning) finalAttackEvent.setCancelled(true);
finalAttackEvent.setBaseDamage(0); finalAttackEvent.setBaseDamage(0);
((Player) finalAttackEvent.getTarget()).setHealth(20); ((Player) finalAttackEvent.getTarget()).setHealth(20);
}); });
this.setGenerator(new CircularPlateTerrainGenerator(20)); setGenerator(new CircularPlateTerrainGenerator(20));
} }
@Override @Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) { protected void onLoad(@NotNull CompletableFuture<Void> callback) {
this.replaceCircle(Block.SANDSTONE); setBlock(0, 50, 0, Block.DIAMOND_BLOCK);
}
private void replaceCircle(Block block) {
int radius = 8;
for(int x = -radius; x <= radius; x++) {
for(int z = -radius; z <= radius; z++) {
Pos blockPosition = this.getSpawn().add(x, -1, z);
if(blockPosition.distance(this.getSpawn().sub(0, 1, 0)) <= radius) this.setBlock(blockPosition, block);
}
}
} }
@Override @Override
protected void start() { protected void start() {
List<Player> players = this.getPlayers().stream().toList(); List<Player> players = getPlayers().stream().toList();
int numPlayers = players.size(); int numPlayers = players.size();
this.countdownStarted = true;
this.replaceCircle(Block.AIR); for (int i = 0; i < numPlayers; i++) {
for(int i = 0; i < numPlayers; i++) {
double angle = (2 * Math.PI / numPlayers) * i; double angle = (2 * Math.PI / numPlayers) * i;
int spawnX = (int) (this.radius * Math.cos(angle)); int spawnX = (int) (radius * Math.cos(angle));
int spawnZ = (int) (this.radius * Math.sin(angle)); int spawnZ = (int) (radius * Math.sin(angle));
int spawnY = 50; int spawnY = 50;
Pos spawnpoint = new Pos(spawnX, spawnY + 1, spawnZ).add(0.5); Pos spawnpoint = new Pos(spawnX, spawnY + 1, spawnZ).add(0.5);
this.spawnPoints.put(players.get(i), spawnpoint.withLookAt(this.getSpawn())); spawnPoints.put(players.get(i), spawnpoint.withLookAt(getSpawn()));
players.get(i).teleport(spawnpoint); players.get(i).teleport(spawnpoint);
this.generateBridge(spawnX, spawnY, spawnZ); generateBridge(spawnX, spawnY, spawnZ);
} }
this.setBlock(0, 50, 0, Block.GOLD_BLOCK); setBlock(0, 50, 0, Block.GOLD_BLOCK);
super.start(); super.start();
} }
@Override
protected void onStop() {
this.scoreMap.forEach((player, score) -> this.getScore().insertResult(player, score));
}
private void generateBridge(int startX, int startY, int startZ) { private void generateBridge(int startX, int startY, int startZ) {
int steps = (int) (this.radius * 1.5); int steps = (int) (radius * 1.5);
for(int i = 0; i < steps; i++) { for (int i = 0; i < steps; i++) {
double t = (double) i / steps; double t = (double) i / steps;
int x = (int) (startX * (1 - t)); int x = (int) (startX * (1 - t));
int z = (int) (startZ * (1 - t)); int z = (int) (startZ * (1 - t));
this.setBlock(x, startY, z, Block.SANDSTONE); setBlock(x, startY, z, Block.SANDSTONE);
} }
} }
@Override @Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) { protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player player = playerMoveEvent.getPlayer(); if(!spawnPoints.containsKey(playerMoveEvent.getPlayer())) {
if(!this.spawnPoints.containsKey(player)) { playerMoveEvent.setCancelled(true);
if(playerMoveEvent.getNewPosition().y() < 45) player.teleport(this.getSpawn());
if(this.countdownStarted) playerMoveEvent.setCancelled(true);
return; return;
} }
if(this.isBeforeBeginning) { if(isBeforeBeginning) {
if(this.spawnPoints.get(player).distance(playerMoveEvent.getNewPosition()) < 1) return; if(spawnPoints.get(playerMoveEvent.getPlayer()).distance(playerMoveEvent.getNewPosition()) < 1) return;
playerMoveEvent.setCancelled(true); playerMoveEvent.setCancelled(true);
player.teleport(this.spawnPoints.get(player)); playerMoveEvent.getPlayer().teleport(spawnPoints.get(playerMoveEvent.getPlayer()));
} }
if(playerMoveEvent.getNewPosition().y() < 40) { if(playerMoveEvent.getNewPosition().y() < 40) {
player.teleport(this.spawnPoints.get(player)); playerMoveEvent.getPlayer().teleport(spawnPoints.get(playerMoveEvent.getPlayer()));
this.scoreMap.putIfAbsent(player, 0);
this.scoreMap.put(player, this.scoreMap.get(player) + 1);
} }
} }

View File

@@ -1,129 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.sumo;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.LastWinsScore;
import io.github.togar2.pvp.events.FinalAttackEvent;
import io.github.togar2.pvp.events.PrepareAttackEvent;
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.player.PlayerMoveEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.timer.TaskSchedule;
import org.jetbrains.annotations.NotNull;
import java.util.WeakHashMap;
import java.util.concurrent.CompletableFuture;
public class Sumo extends StatelessGame {
int radius;
int health;
int seconds;
int originalRadius;
int timer;
WeakHashMap<Player, Integer> healthMap = new WeakHashMap<>();
public Sumo(int radius, int health, int seconds) {
super(Dimension.OVERWORLD.key, "Sumo", new LastWinsScore());
this.getScore().setIgnoreLastPlayers(1);
this.setTime(6000);
this.setTimeRate(0);
this.radius = radius;
this.health = health;
this.seconds = seconds;
this.originalRadius = radius;
this.timer = seconds;
this.eventNode().addChild(
CombatFeatures.empty()
.add(CombatFeatures.VANILLA_ATTACK)
.add(CombatFeatures.VANILLA_DAMAGE)
.add(CombatFeatures.VANILLA_KNOCKBACK)
.build()
.createNode()
);
this.eventNode().addListener(PrepareAttackEvent.class, prepareAttackEvent -> {
if(this.isBeforeBeginning)
prepareAttackEvent.setCancelled(true);
});
this.eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
finalAttackEvent.setBaseDamage(0);
((Player) finalAttackEvent.getTarget()).setHealth(20);
});
}
@Override
protected void start() {
this.getPlayers().forEach(player -> {
this.healthMap.put(player, this.health);
player.setLevel(this.healthMap.get(player));
});
MinecraftServer.getSchedulerManager().scheduleTask(
() -> {
if(this.isBeforeBeginning) return TaskSchedule.seconds(1);
this.timer--;
double percent = (double) this.timer / this.seconds;
int radius = (int) (this.originalRadius * percent);
if(this.radius >= 5) {
this.radius = radius;
this.generatePlatform();
return TaskSchedule.seconds(1);
}
return TaskSchedule.stop();
},
TaskSchedule.seconds(1)
);
super.start();
}
@Override
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
this.generatePlatform();
}
private void generatePlatform() {
int buffer = 5;
for(int x = -this.radius - buffer; x <= this.radius + buffer; x++) {
for(int z = -this.radius - buffer; z <= this.radius + buffer; z++) {
double distance = new Pos(x, 0, z).distance(new Pos(0, 0, 0));
if(distance <= this.radius) {
boolean isEdge = this.radius - 1 < distance;
this.setBlock(x, 0, z, isEdge ? Block.RED_CONCRETE : Block.WHITE_CONCRETE);
} else {
this.setBlock(x, 0, z, Block.AIR);
}
}
}
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player player = playerMoveEvent.getPlayer();
if(playerMoveEvent.getNewPosition().y() < -10) {
player.teleport(this.getSpawn());
this.healthMap.put(player, this.healthMap.get(player) - 1);
player.setLevel(this.healthMap.get(player));
if(this.healthMap.get(player) == 0) {
this.getScore().insertResult(player);
player.setGameMode(GameMode.SPECTATOR);
}
}
}
@Override
public Pos getSpawn() {
return new Pos(0, 2, 0);
}
}

View File

@@ -1,49 +0,0 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.sumo;
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.game.stateless.config.restriction.RestrictionHandler;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.restriction.common.MinimalPlayeramountGameRestriction;
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 SumoFactory implements GameFactory {
@Override
public TranslatedComponent name() {
return TranslatedComponent.byId("game_Sumo#name");
}
public TranslatedComponent description() {
return TranslatedComponent.byId("game_Sumo#description");
}
@Override
public Material symbol() {
return Material.SLIME_BALL;
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 10, 20, 30))
.addOption(new NumericOption("health", Material.GOLDEN_APPLE, TranslatedComponent.byId("game_Sumo#lives"), 1, 2, 3, 4, 5))
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 30, 60, 90, 120));
}
@Override
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
return new Sumo(configuration.get("radius").getAsInt(), configuration.get("health").getAsInt(), configuration.get("seconds").getAsInt()).setParent(parent);
}
@Override
public RestrictionHandler globalRestrictions() {
return new RestrictionHandler()
.addRestriction(new MinimalPlayeramountGameRestriction(2));
}
}

View File

@@ -1,8 +1,8 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris; package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame; import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.TetrisGame; import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.TetrisGame;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.Tetromino; import eu.mhsl.minenet.minigames.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;
@@ -10,30 +10,25 @@ import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.GameMode; import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerHandAnimationEvent; import net.minestom.server.event.player.*;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.event.player.PlayerTickEvent;
import net.minestom.server.event.player.PlayerUseItemEvent;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.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.*;
import java.util.Random;
import java.util.WeakHashMap;
class Tetris extends StatelessGame { class Tetris extends StatelessGame {
private final Map<Player, TetrisGame> tetrisGames = new WeakHashMap<>(); private final Map<Player, TetrisGame> tetrisGames = new WeakHashMap<>();
private final int nextTetrominoesCount; private final int nextTetrominoesCount;
private final boolean isFast; private final boolean isFast;
private final boolean hasCombat; private final boolean hasCombat;
private final long randomSeed;
private boolean setTimeLimit = false; private boolean setTimeLimit = false;
private final long randomSeed;
public Tetris(int nextTetrominoesCount, boolean isFast, boolean hasCombat) { public Tetris(int nextTetrominoesCount, boolean isFast, boolean hasCombat) {
super(Dimension.THE_END.key, "Tetris", new PointsWinScore()); super(Dimension.THE_END.key, "Tetris", new PointsWinScore());
this.eventNode() eventNode()
.addListener(PlayerUseItemEvent.class, this::onPlayerInteract) .addListener(PlayerUseItemEvent.class, this::onPlayerInteract)
.addListener(PlayerHandAnimationEvent.class, this::onPlayerAttack) .addListener(PlayerHandAnimationEvent.class, this::onPlayerAttack)
.addListener(PlayerTickEvent.class, this::onPlayerTick); .addListener(PlayerTickEvent.class, this::onPlayerTick);
@@ -63,7 +58,7 @@ class Tetris extends StatelessGame {
protected void onStop() { protected void onStop() {
this.tetrisGames.forEach((player, tetrisGame) -> { this.tetrisGames.forEach((player, tetrisGame) -> {
tetrisGame.loose(); tetrisGame.loose();
this.getScore().insertResult(player, tetrisGame.getScore()); getScore().insertResult(player, tetrisGame.getScore());
tetrisGame.sidebar.removeViewer(player); tetrisGame.sidebar.removeViewer(player);
}); });
} }
@@ -111,25 +106,23 @@ class Tetris extends StatelessGame {
TetrisGame tetrisGame = this.tetrisGames.get(player); TetrisGame tetrisGame = this.tetrisGames.get(player);
if(tetrisGame == null) return; if(tetrisGame == null) return;
if(tetrisGame.lost && player.getGameMode() != GameMode.SPECTATOR) { if(tetrisGame.lost && player.getGameMode() != GameMode.SPECTATOR) {
this.letPlayerLoose(player); letPlayerLoose(player);
} }
} }
private void letPlayerLoose(Player player) { private void letPlayerLoose(Player player) {
TetrisGame tetrisGame = this.tetrisGames.get(player); TetrisGame tetrisGame = this.tetrisGames.get(player);
if(!this.getScore().hasResult(player)) {
player.setGameMode(GameMode.SPECTATOR); player.setGameMode(GameMode.SPECTATOR);
player.setInvisible(true); player.setInvisible(true);
this.getScore().insertResult(player, tetrisGame.getScore()); getScore().insertResult(player, tetrisGame.getScore());
}
boolean allGamesLost = this.tetrisGames.values().stream() boolean allGamesLost = this.tetrisGames.values().stream()
.filter(game -> !game.lost) .filter(game -> !game.lost)
.toList() .toList()
.isEmpty(); .isEmpty();
if(!this.setTimeLimit && !allGamesLost) { if(!setTimeLimit && !allGamesLost) {
this.setTimeLimit(90); this.setTimeLimit(90);
this.setTimeLimit = true; setTimeLimit = true;
} }
} }
@@ -141,7 +134,7 @@ class Tetris extends StatelessGame {
if(this.tetrisGames.get(p) == null) { if(this.tetrisGames.get(p) == null) {
this.tetrisGames.put(p, new TetrisGame( this.tetrisGames.put(p, new TetrisGame(
this, this,
this.getSpawn().sub(6, 8, 15).add(this.tetrisGames.size() * 30, 0, 0), getSpawn().sub(6, 8, 15).add(this.tetrisGames.size()*30, 0, 0),
Tetromino.Shape.J, Tetromino.Shape.J,
this.nextTetrominoesCount, this.nextTetrominoesCount,
this.isFast, this.isFast,

View File

@@ -1,9 +1,9 @@
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris; package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris;
import eu.mhsl.minenet.minigames.instance.game.Game; import eu.mhsl.minenet.minigames.instance.game.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.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option; import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.BoolOption; import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.BoolOption;
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption; import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
import eu.mhsl.minenet.minigames.instance.room.Room; import eu.mhsl.minenet.minigames.instance.room.Room;

View File

@@ -10,10 +10,10 @@ import org.apache.commons.lang3.ArrayUtils;
import java.util.Random; import java.util.Random;
public class Playfield { public class Playfield {
private final static int height = 22;
private final static Block scoreBlock = Block.STONE;
private final Pos lowerLeftCorner; private final Pos lowerLeftCorner;
private final StatelessGame instance; private final StatelessGame instance;
private final static int height = 22;
private final static Block scoreBlock = Block.STONE;
private final int nextTetrominoesCount; private final int nextTetrominoesCount;
private final Random random; private final Random random;
@@ -41,19 +41,19 @@ public class Playfield {
} }
public Pos getScorePosition() { public Pos getScorePosition() {
return this.lowerLeftCorner.add(-5, height + 3, 0); return this.lowerLeftCorner.add(-5, height+3, 0);
} }
public void generate() { public void generate() {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch(); AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
// actual playfield: // actual playfield:
for(int x = 0; x < 12; x++) { for(int x=0; x<12; x++) {
for(int y = 0; y < height; y++) { for(int y = 0; y< height; y++) {
batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.GLASS); batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.GLASS);
batch.setBlock(this.lowerLeftCorner.add(x, y, -1), Block.BLACK_CONCRETE); batch.setBlock(this.lowerLeftCorner.add(x, y, -1), Block.BLACK_CONCRETE);
if(x == 0 || x == 11 || y == 0) { if(x==0 || x==11 || y==0) {
batch.setBlock(this.lowerLeftCorner.add(x, y, 1), Block.GRAY_CONCRETE); batch.setBlock(this.lowerLeftCorner.add(x, y, 1), Block.GRAY_CONCRETE);
batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.GRAY_CONCRETE); batch.setBlock(this.lowerLeftCorner.add(x, y, 0), Block.GRAY_CONCRETE);
} }
@@ -63,35 +63,34 @@ public class Playfield {
// hold position: // hold position:
for(int x = 0; x < 4; x++) { for(int x = 0; x < 4; x++) {
for(int y = 0; y < 4; y++) { for(int y = 0; y < 4; y++) {
batch.setBlock(this.getHoldPosition().add(x - 1, y - 1, -1), Block.QUARTZ_BLOCK); batch.setBlock(this.getHoldPosition().add(x-1, y-1, -1), Block.QUARTZ_BLOCK);
} }
} }
// next positions: // next positions:
for(int x = 0; x < 4; x++) { for(int x = 0; x < 4; x++) {
for(int y = -4 * this.nextTetrominoesCount + 4; y < 4; y++) { for(int y = -4*this.nextTetrominoesCount+4; y < 4; y++) {
batch.setBlock(this.getNextPosition().add(x - 1, y - 1, -1), Block.QUARTZ_BLOCK); batch.setBlock(this.getNextPosition().add(x-1, y-1, -1), Block.QUARTZ_BLOCK);
} }
} }
batch.setBlock(this.getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE); batch.setBlock(getPlayerSpawnPosition().sub(0, 1, 0), Block.STONE);
batch.setBlock(this.getPlayerSpawnPosition().sub(1, 1, 0), Block.STONE); batch.setBlock(getPlayerSpawnPosition().sub(1, 1, 0), Block.STONE);
batch.setBlock(this.getPlayerSpawnPosition().sub(1, 1, 1), Block.STONE); batch.setBlock(getPlayerSpawnPosition().sub(1, 1, 1), Block.STONE);
batch.setBlock(this.getPlayerSpawnPosition().sub(0, 1, 1), Block.STONE); batch.setBlock(getPlayerSpawnPosition().sub(0, 1, 1), Block.STONE);
BatchUtil.loadAndApplyBatch(batch, this.instance, () -> { BatchUtil.loadAndApplyBatch(batch, this.instance, () -> {});
});
} }
public int removeFullLines() { public int removeFullLines() {
int removedLinesCounter = 0; int removedLinesCounter = 0;
for(int y = 1; y < height; y++) { for(int y = 1; y< height; y++) {
boolean isFullLine = true; boolean isFullLine = true;
for(int x = 1; x < 11; x++) { for(int x=1; x<11; x++) {
if(this.instance.getBlock(this.lowerLeftCorner.add(x, y, 1)) == Block.AIR) isFullLine = false; if(this.instance.getBlock(this.lowerLeftCorner.add(x, y, 1)) == Block.AIR) isFullLine = false;
} }
if(isFullLine) { if(isFullLine) {
this.removeFullLine(y); removeFullLine(y);
removedLinesCounter += 1; removedLinesCounter += 1;
y -= 1; y -= 1;
} }
@@ -100,11 +99,11 @@ public class Playfield {
} }
public void addLines(int lines) { public void addLines(int lines) {
int xPosMissing = this.random.nextInt(1, 10); int xPosMissing = random.nextInt(1, 10);
for(int i = 0; i < lines; i++) { for (int i = 0; i < lines; i++) {
this.moveAllLinesUp(); moveAllLinesUp();
for(int x = 1; x < 11; x++) { for (int x = 1; x < 11; x++) {
if(x != xPosMissing) { if(x != xPosMissing) {
this.instance.setBlock(this.lowerLeftCorner.add(x, 1, 1), Block.LIGHT_GRAY_CONCRETE); this.instance.setBlock(this.lowerLeftCorner.add(x, 1, 1), Block.LIGHT_GRAY_CONCRETE);
} else { } else {
@@ -115,7 +114,7 @@ public class Playfield {
} }
public void updateAttackingLines(int attackingLines) { public void updateAttackingLines(int attackingLines) {
for(int y = 0; y < height + 5; y++) { for (int y = 0; y < height + 5; y++) {
if(attackingLines > 0) { if(attackingLines > 0) {
this.instance.setBlock(this.lowerLeftCorner.add(12, y, 1), Block.REDSTONE_BLOCK); this.instance.setBlock(this.lowerLeftCorner.add(12, y, 1), Block.REDSTONE_BLOCK);
attackingLines -= 1; attackingLines -= 1;
@@ -133,49 +132,48 @@ public class Playfield {
for(int i = 6; i > 0; i--) { for(int i = 6; i > 0; i--) {
char digit; char digit;
if(i <= characters.length) { if(i <= characters.length) {
digit = characters[i - 1]; digit = characters[i-1];
} else { } else {
digit = '0'; digit = '0';
} }
this.displayDigit(digit, 6 - i); this.displayDigit(digit, 6-i);
} }
} }
private void displayDigit(char digit, int positionFromLeft) { private void displayDigit(char digit, int positionFromLeft) {
int[][] digitArray; int[][] digitArray;
switch(digit) { switch (digit) {
case '1' -> digitArray = new int[][]{{0, 0, 1}, {0, 1, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}}; case '1' -> digitArray = new int[][]{{0,0,1},{0,1,1},{0,0,1},{0,0,1},{0,0,1}};
case '2' -> digitArray = new int[][]{{1, 1, 1}, {0, 0, 1}, {1, 1, 1}, {1, 0, 0}, {1, 1, 1}}; case '2' -> digitArray = new int[][]{{1,1,1},{0,0,1},{1,1,1},{1,0,0},{1,1,1}};
case '3' -> digitArray = new int[][]{{1, 1, 1}, {0, 0, 1}, {0, 1, 1}, {0, 0, 1}, {1, 1, 1}}; case '3' -> digitArray = new int[][]{{1,1,1},{0,0,1},{0,1,1},{0,0,1},{1,1,1}};
case '4' -> digitArray = new int[][]{{1, 0, 1}, {1, 0, 1}, {1, 1, 1}, {0, 0, 1}, {0, 0, 1}}; case '4' -> digitArray = new int[][]{{1,0,1},{1,0,1},{1,1,1},{0,0,1},{0,0,1}};
case '5' -> digitArray = new int[][]{{1, 1, 1}, {1, 0, 0}, {1, 1, 1}, {0, 0, 1}, {1, 1, 1}}; case '5' -> digitArray = new int[][]{{1,1,1},{1,0,0},{1,1,1},{0,0,1},{1,1,1}};
case '6' -> digitArray = new int[][]{{1, 1, 1}, {1, 0, 0}, {1, 1, 1}, {1, 0, 1}, {1, 1, 1}}; case '6' -> digitArray = new int[][]{{1,1,1},{1,0,0},{1,1,1},{1,0,1},{1,1,1}};
case '7' -> digitArray = new int[][]{{1, 1, 1}, {0, 0, 1}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0}}; case '7' -> digitArray = new int[][]{{1,1,1},{0,0,1},{0,1,0},{0,1,0},{0,1,0}};
case '8' -> digitArray = new int[][]{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}, {1, 0, 1}, {1, 1, 1}}; case '8' -> digitArray = new int[][]{{1,1,1},{1,0,1},{1,1,1},{1,0,1},{1,1,1}};
case '9' -> digitArray = new int[][]{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}, {0, 0, 1}, {1, 1, 1}}; case '9' -> digitArray = new int[][]{{1,1,1},{1,0,1},{1,1,1},{0,0,1},{1,1,1}};
default -> digitArray = new int[][]{{1, 1, 1}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}, {1, 1, 1}}; default -> digitArray = new int[][]{{1,1,1},{1,0,1},{1,0,1},{1,0,1},{1,1,1}};
} }
for(int x = 0; x < 3; x++) { for (int x = 0; x < 3; x++) {
for(int y = 0; y < 5; y++) { for (int y = 0; y < 5; y++) {
if(digitArray[4 - y][x] == 1) if(digitArray[4-y][x] == 1) this.instance.setBlock(this.getScorePosition().add(positionFromLeft*4+x, y, 0), scoreBlock);
this.instance.setBlock(this.getScorePosition().add(positionFromLeft * 4 + x, y, 0), scoreBlock);
} }
} }
} }
private void removeDigits() { private void removeDigits() {
for(int x = 0; x < 4 * 6; x++) { for (int x = 0; x < 4 * 6; x++) {
for(int y = 0; y < 5; y++) { for (int y = 0; y < 5; y++) {
this.instance.setBlock(this.getScorePosition().add(x, y, 0), Block.AIR); this.instance.setBlock(this.getScorePosition().add(x, y, 0), Block.AIR);
} }
} }
} }
private void moveAllLinesUp() { private void moveAllLinesUp() {
for(int y = height + 3; y > 1; y--) { for (int y = height + 3; y > 1; y--) {
for(int x = 1; x < 11; x++) { for (int x = 1; x < 11; x++) {
Block blockBeneath = this.instance.getBlock(this.lowerLeftCorner.add(x, y - 1, 1)); Block blockBeneath = this.instance.getBlock(this.lowerLeftCorner.add(x, y - 1, 1));
this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockBeneath); this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockBeneath);
} }
@@ -183,9 +181,9 @@ public class Playfield {
} }
private void removeFullLine(int positionY) { private void removeFullLine(int positionY) {
for(int y = positionY; y < height; y++) { for(int y = positionY; y< height; y++) {
for(int x = 1; x < 11; x++) { for(int x=1; x<11; x++) {
Block blockAbove = this.instance.getBlock(this.lowerLeftCorner.add(x, y + 1, 1)); Block blockAbove = this.instance.getBlock(this.lowerLeftCorner.add(x, y+1, 1));
this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockAbove); this.instance.setBlock(this.lowerLeftCorner.add(x, y, 1), blockAbove);
} }
} }

View File

@@ -14,26 +14,36 @@ public class TetrisGame {
private final StatelessGame instance; private final StatelessGame instance;
private final Playfield playfield; private final Playfield playfield;
private final boolean isFast; private final boolean isFast;
private final boolean hasCombat;
private final List<Tetromino> nextTetrominoes = new ArrayList<>();
private final List<Tetromino> tetrominoBag = new ArrayList<>();
private final Pos nextPosition;
private final Pos holdPosition;
private final Pos tetrominoSpawnPosition;
private final Map<Button, Long> lastPresses = new HashMap<>();
private final List<TetrisGame> otherTetrisGames = new ArrayList<>();
private final Random random;
public boolean lost = false;
public boolean paused = true;
public Tetromino currentTetromino;
public Sidebar sidebar = new Sidebar(Component.text("Info:"));
private int level = 1; private int level = 1;
private int lines = 0; private int lines = 0;
private int score = 0; private int score = 0;
private int combo = 0; private int combo = 0;
private int attackingLines = 0; private int attackingLines = 0;
public boolean lost = false;
public boolean paused = true;
private final boolean hasCombat;
public Tetromino currentTetromino;
private final List<Tetromino> nextTetrominoes = new ArrayList<>();
private Tetromino holdTetromino; private Tetromino holdTetromino;
private final List<Tetromino> tetrominoBag = new ArrayList<>();
private boolean holdPossible = true; private boolean holdPossible = true;
private final Pos nextPosition;
private final Pos holdPosition;
private final Pos tetrominoSpawnPosition;
public Sidebar sidebar = new Sidebar(Component.text("Info:"));
private final Map<Button, Long> lastPresses = new HashMap<>();
private final List<TetrisGame> otherTetrisGames = new ArrayList<>();
private final Random random;
public enum Button {
W,
A,
S,
D,
mouseLeft,
mouseRight,
space
}
public TetrisGame(StatelessGame instance, Pos lowerLeftCorner, Tetromino.Shape startTetrominoShape, int nextTetrominoesCount, boolean isfast, boolean hasCombat, long randomSeed) { public TetrisGame(StatelessGame instance, Pos lowerLeftCorner, Tetromino.Shape startTetrominoShape, int nextTetrominoesCount, boolean isfast, boolean hasCombat, long randomSeed) {
this.isFast = isfast; this.isFast = isfast;
@@ -48,7 +58,7 @@ public class TetrisGame {
this.buildSidebar(); this.buildSidebar();
this.currentTetromino = new Tetromino(this.instance, startTetrominoShape); this.currentTetromino = new Tetromino(this.instance, startTetrominoShape);
for(int i = 0; i < nextTetrominoesCount; i++) { for (int i = 0; i < nextTetrominoesCount; i++) {
this.updateNextTetrominoes(); this.updateNextTetrominoes();
} }
} }
@@ -57,15 +67,15 @@ public class TetrisGame {
final int standardButtonDelay = 100; final int standardButtonDelay = 100;
final int buttonDebounce = 70; final int buttonDebounce = 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()); this.lastPresses.put(button, System.currentTimeMillis());
if(button == Button.W) this.lastPresses.put(button, System.currentTimeMillis() + buttonDebounce); if(button == Button.W) this.lastPresses.put(button, System.currentTimeMillis()+buttonDebounce);
if(button == Button.S) this.lastPresses.put(button, System.currentTimeMillis() - buttonDebounce); if(button == Button.S) this.lastPresses.put(button, System.currentTimeMillis()-buttonDebounce);
if(this.lost || this.paused) return; if(this.lost || this.paused) return;
switch(button) { switch (button) {
case A -> this.currentTetromino.moveLeft(); case A -> this.currentTetromino.moveLeft();
case S -> this.moveDown(); case S -> this.moveDown();
case D -> this.currentTetromino.moveRight(); case D -> this.currentTetromino.moveRight();
@@ -88,7 +98,7 @@ public class TetrisGame {
int standardTickDelay = 40; int standardTickDelay = 40;
if(this.isFast) standardTickDelay = 20; if(this.isFast) standardTickDelay = 20;
TaskSchedule nextTick = TaskSchedule.tick(Math.round((float) standardTickDelay / this.level)); TaskSchedule nextTick = TaskSchedule.tick(Math.round((float) standardTickDelay /this.level));
if(this.paused) return nextTick; if(this.paused) return nextTick;
this.tick(); this.tick();
return nextTick; return nextTick;
@@ -97,7 +107,7 @@ public class TetrisGame {
this.updateInfo(); this.updateInfo();
this.nextTetrominoes.forEach(tetromino -> { this.nextTetrominoes.forEach(tetromino -> {
double xChange = -tetromino.getXChange(); double xChange = -tetromino.getXChange();
tetromino.setPosition(this.nextPosition.sub(xChange, 4 * this.nextTetrominoes.indexOf(tetromino), 0)); tetromino.setPosition(this.nextPosition.sub(xChange, 4*this.nextTetrominoes.indexOf(tetromino), 0));
tetromino.drawAsEntities(); tetromino.drawAsEntities();
}); });
} }
@@ -111,8 +121,8 @@ 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(!currentTetromino.moveDown()) {
this.setActiveTetrominoDown(); setActiveTetrominoDown();
} }
} }
@@ -139,6 +149,7 @@ public class TetrisGame {
this.lost = true; this.lost = true;
} }
private boolean moveDown() { private boolean moveDown() {
if(!this.currentTetromino.moveDown()) { if(!this.currentTetromino.moveDown()) {
this.setActiveTetrominoDown(); this.setActiveTetrominoDown();
@@ -165,7 +176,7 @@ public class TetrisGame {
} }
private boolean switchHold() { private boolean switchHold() {
if(!this.holdPossible) return false; if(!holdPossible) return false;
Tetromino newCurrentTetromino; Tetromino newCurrentTetromino;
if(this.holdTetromino == null) { if(this.holdTetromino == null) {
@@ -183,7 +194,7 @@ public class TetrisGame {
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()) loose();
double xChange = this.holdTetromino.getXChange(); double xChange = this.holdTetromino.getXChange();
this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0)); this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0));
@@ -192,6 +203,7 @@ public class TetrisGame {
return true; return true;
} }
private void updateNextTetrominoes() { private void updateNextTetrominoes() {
if(this.tetrominoBag.isEmpty()) { if(this.tetrominoBag.isEmpty()) {
for(Tetromino.Shape shape : Tetromino.Shape.values()) { for(Tetromino.Shape shape : Tetromino.Shape.values()) {
@@ -205,7 +217,7 @@ public class TetrisGame {
this.nextTetrominoes.add(newTetromino); this.nextTetrominoes.add(newTetromino);
this.nextTetrominoes.forEach(tetromino -> { this.nextTetrominoes.forEach(tetromino -> {
double xChange = -tetromino.getXChange(); double xChange = -tetromino.getXChange();
tetromino.setPosition(this.nextPosition.sub(xChange, 4 * this.nextTetrominoes.indexOf(tetromino), 0)); tetromino.setPosition(this.nextPosition.sub(xChange, 4*this.nextTetrominoes.indexOf(tetromino), 0));
tetromino.drawAsEntities(); tetromino.drawAsEntities();
}); });
} }
@@ -244,7 +256,7 @@ public class TetrisGame {
int removedLines = this.playfield.removeFullLines(); int removedLines = this.playfield.removeFullLines();
int combatLines = 0; int combatLines = 0;
this.combo += 1; this.combo += 1;
switch(removedLines) { switch (removedLines) {
case 0 -> this.combo = 0; case 0 -> this.combo = 0;
case 1 -> { case 1 -> {
this.lines += 1; this.lines += 1;
@@ -269,7 +281,7 @@ public class TetrisGame {
this.score += 50 * this.combo * this.level; this.score += 50 * this.combo * this.level;
if(this.combo >= 2) { if(this.combo >= 2) {
combatLines += (int) Math.floor((double) this.combo / 2); combatLines += (int) Math.floor((double) this.combo /2);
} }
if(this.hasCombat && this.attackingLines > 0) { if(this.hasCombat && this.attackingLines > 0) {
@@ -300,17 +312,7 @@ public class TetrisGame {
this.currentTetromino.setPosition(this.tetrominoSpawnPosition); this.currentTetromino.setPosition(this.tetrominoSpawnPosition);
this.currentTetromino.draw(); this.currentTetromino.draw();
if(!this.currentTetromino.moveDown()) { if(!this.currentTetromino.moveDown()) {
this.loose(); loose();
} }
} }
public enum Button {
W,
A,
S,
D,
mouseLeft,
mouseRight,
space
}
} }

View File

@@ -14,27 +14,37 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
public class Tetromino { public class Tetromino {
private final static EntityType ghostEntityType = EntityType.FALLING_BLOCK;
private final static Tag<String> uuidTag = Tag.String("uuid");
private final Shape shape; private final Shape shape;
private final StatelessGame instance; private final StatelessGame instance;
private final UUID uuid;
private Pos position; private Pos position;
private int[][] shapeArray; private int[][] shapeArray;
private final static EntityType ghostEntityType = EntityType.FALLING_BLOCK;
private final UUID uuid;
private final static Tag<String> uuidTag = Tag.String("uuid");
public enum Shape {
I,
J,
L,
O,
S,
T,
Z
}
public Tetromino(StatelessGame instance, Shape shape) { public Tetromino(StatelessGame instance, Shape shape) {
this.instance = instance; this.instance = instance;
this.shape = shape; this.shape = shape;
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 -> shapeArray = new int[][]{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}};
case J -> this.shapeArray = new int[][]{{1, 0, 0}, {1, 1, 1}, {0, 0, 0}}; case J -> 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 -> shapeArray = new int[][]{{0,0,1}, {1,1,1}, {0,0,0}};
case O -> this.shapeArray = new int[][]{{1, 1}, {1, 1}}; case O -> shapeArray = new int[][]{{1,1}, {1,1}};
case S -> this.shapeArray = new int[][]{{0, 1, 1}, {1, 1, 0}, {0, 0, 0}}; case S -> 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 -> 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 -> shapeArray = new int[][]{{1,1,0}, {0,1,1}, {0,0,0}};
} }
} }
@@ -48,22 +58,22 @@ public class Tetromino {
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); return checkCollisionAndMove(this.position, newShapeArray);
} }
public boolean moveDown() { public boolean moveDown() {
Pos newPosition = this.position.sub(0, 1, 0); Pos newPosition = this.position.sub(0, 1, 0);
return this.checkCollisionAndMove(newPosition, this.shapeArray); return checkCollisionAndMove(newPosition, this.shapeArray);
} }
public boolean moveLeft() { public boolean moveLeft() {
Pos newPosition = this.position.sub(1, 0, 0); Pos newPosition = this.position.sub(1, 0, 0);
return this.checkCollisionAndMove(newPosition, this.shapeArray); return checkCollisionAndMove(newPosition, this.shapeArray);
} }
public boolean moveRight() { public boolean moveRight() {
Pos newPosition = this.position.add(1, 0, 0); Pos newPosition = this.position.add(1, 0, 0);
return this.checkCollisionAndMove(newPosition, this.shapeArray); return checkCollisionAndMove(newPosition, this.shapeArray);
} }
public void draw() { public void draw() {
@@ -73,11 +83,11 @@ 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 (!checkCollision(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);
this.getBlockPositions().forEach(pos -> { getBlockPositions().forEach(pos -> {
Entity ghostBlock = new Entity(ghostEntityType); Entity ghostBlock = new Entity(ghostEntityType);
((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getGhostBlock()); ((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getGhostBlock());
ghostBlock.setNoGravity(true); ghostBlock.setNoGravity(true);
@@ -87,11 +97,11 @@ public class Tetromino {
}); });
} }
this.getBlockPositions().forEach(pos -> this.instance.setBlock(pos, this.getColoredBlock())); getBlockPositions().forEach(pos -> this.instance.setBlock(pos, this.getColoredBlock()));
} }
public void drawAsEntities() { public void drawAsEntities() {
this.getBlockPositions().forEach(pos -> { getBlockPositions().forEach(pos -> {
Entity ghostBlock = new Entity(ghostEntityType); Entity ghostBlock = new Entity(ghostEntityType);
((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getColoredBlock()); ((FallingBlockMeta) ghostBlock.getEntityMeta()).setBlock(this.getColoredBlock());
ghostBlock.setNoGravity(true); ghostBlock.setNoGravity(true);
@@ -107,7 +117,7 @@ public class Tetromino {
public Block getColoredBlock() { public Block getColoredBlock() {
Block returnBlock; Block returnBlock;
switch(this.shape) { switch (this.shape) {
case I -> returnBlock = Block.LIGHT_BLUE_CONCRETE; case I -> returnBlock = Block.LIGHT_BLUE_CONCRETE;
case J -> returnBlock = Block.BLUE_CONCRETE; case J -> returnBlock = Block.BLUE_CONCRETE;
case L -> returnBlock = Block.ORANGE_CONCRETE; case L -> returnBlock = Block.ORANGE_CONCRETE;
@@ -131,7 +141,7 @@ public class Tetromino {
} }
public double getXChange() { public double getXChange() {
switch(this.shape) { switch (this.shape) {
case O, I -> { case O, I -> {
return 0; return 0;
} }
@@ -141,13 +151,14 @@ public class Tetromino {
} }
} }
public Shape getShape() { public Shape getShape() {
return this.shape; return this.shape;
} }
private Block getGhostBlock() { private Block getGhostBlock() {
Block returnBlock; Block returnBlock;
switch(this.shape) { switch (this.shape) {
case I -> returnBlock = Block.LIGHT_BLUE_STAINED_GLASS; case I -> returnBlock = Block.LIGHT_BLUE_STAINED_GLASS;
case J -> returnBlock = Block.BLUE_STAINED_GLASS; case J -> returnBlock = Block.BLUE_STAINED_GLASS;
case L -> returnBlock = Block.ORANGE_STAINED_GLASS; case L -> returnBlock = Block.ORANGE_STAINED_GLASS;
@@ -168,10 +179,10 @@ public class Tetromino {
int[][] startArray = Arrays.stream(this.shapeArray).map(int[]::clone).toArray(int[][]::new); int[][] startArray = Arrays.stream(this.shapeArray).map(int[]::clone).toArray(int[][]::new);
int[][] returnArray = new int[arrayLength][arrayLength]; int[][] returnArray = new int[arrayLength][arrayLength];
for(int k = 0; k < iterations; k++) { for(int k=0; k<iterations; k++) {
for(int i = 0; i < arrayLength; i++) { for(int i=0; i<arrayLength; i++) {
for(int j = 0; j < arrayLength; j++) { for(int j=0; j<arrayLength; j++) {
returnArray[i][arrayLength - 1 - j] = startArray[j][i]; returnArray[i][arrayLength-1-j] = startArray[j][i];
} }
} }
startArray = Arrays.stream(returnArray).map(int[]::clone).toArray(int[][]::new); startArray = Arrays.stream(returnArray).map(int[]::clone).toArray(int[][]::new);
@@ -195,13 +206,13 @@ public class Tetromino {
int arrayLength = shapeArray.length; int arrayLength = shapeArray.length;
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) { switch (this.shape) {
case I -> returnList.add(position.add(x - 1, y - 2, 0)); case I -> returnList.add(position.add(x-1, y-2, 0));
case O -> returnList.add(position.add(x, y, 0)); case O -> returnList.add(position.add(x, y, 0));
default -> returnList.add(position.add(x - 1, y - 1, 0)); default -> returnList.add(position.add(x-1, y-1, 0));
} }
} }
} }
@@ -211,10 +222,10 @@ public class Tetromino {
} }
private boolean checkCollision(Pos newPosition, int[][] newShapeArray) { private boolean checkCollision(Pos newPosition, int[][] newShapeArray) {
List<Pos> newBlockPositions = this.getBlockPositions(newPosition, newShapeArray); List<Pos> newBlockPositions = getBlockPositions(newPosition, newShapeArray);
for(Pos pos : newBlockPositions) { for(Pos pos : newBlockPositions) {
if(this.isPartOfTetromino(pos)) continue; if(isPartOfTetromino(pos)) continue;
if(this.instance.getBlock(pos) == this.getGhostBlock()) continue; if(this.instance.getBlock(pos) == this.getGhostBlock()) continue;
if(this.instance.getBlock(pos) != Block.AIR) return true; if(this.instance.getBlock(pos) != Block.AIR) return true;
} }
@@ -223,7 +234,7 @@ public class Tetromino {
} }
private boolean checkCollisionAndMove(Pos newPosition, int[][] newShapeArray) { private boolean checkCollisionAndMove(Pos newPosition, int[][] newShapeArray) {
if(!this.checkCollision(newPosition, newShapeArray)) { if(!checkCollision(newPosition, newShapeArray)) {
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);
@@ -232,14 +243,4 @@ public class Tetromino {
} }
return false; return false;
} }
public enum Shape {
I,
J,
L,
O,
S,
T,
Z
}
} }

Some files were not shown because too many files have changed in this diff Show More