Compare commits
38 Commits
develop-up
...
develop-te
| Author | SHA1 | Date | |
|---|---|---|---|
| 56f56d48b6 | |||
| 991e51bc10 | |||
| ffba86ac41 | |||
| f95c670514 | |||
| 0b3c757ce0 | |||
| 76df6643db | |||
| 7186b4dbea | |||
| 24d79d7a11 | |||
| 70fd5bafdb | |||
| 11ddd01470 | |||
| 7d5fb025bd | |||
| 05240660f2 | |||
| d0031b4ea5 | |||
| 360266339d | |||
| 325fba2a53 | |||
| e760cdb2c6 | |||
| c111c027ff | |||
| 73ab137ae4 | |||
| 9a9e646288 | |||
| 728dc92fc8 | |||
| 2f8ff36e5e | |||
| 5cb71c5c32 | |||
| 5ab42fde4b | |||
| d5c2f06409 | |||
| 1ff8cca7e9 | |||
| 47c40c4941 | |||
| d4a7fcada7 | |||
| a0124f1bcb | |||
| c79fbf3136 | |||
| 660eb645e4 | |||
| 3c50aca1e8 | |||
| 865cdfa605 | |||
| fe88e3f921 | |||
| 5e94479949 | |||
| b15c9c97b0 | |||
| 334e130cf6 | |||
| 31385fbd7f | |||
| b1b1e24104 |
2
.idea/codeStyles/codeStyleConfig.xml
generated
2
.idea/codeStyles/codeStyleConfig.xml
generated
@@ -1,5 +1,5 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
<state>
|
<state>
|
||||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Minigames" />
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
</state>
|
</state>
|
||||||
</component>
|
</component>
|
||||||
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="25" />
|
<bytecodeTargetLevel target="21" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" default="true" project-jdk-name="openjdk-25" project-jdk-type="JavaSDK" />
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
|
||||||
</project>
|
</project>
|
||||||
1
.idea/modules.xml
generated
1
.idea/modules.xml
generated
@@ -4,6 +4,7 @@
|
|||||||
<modules>
|
<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.main.iml" filepath="$PROJECT_DIR$/.idea/modules/Minigames.main.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Minigames.test.iml" filepath="$PROJECT_DIR$/.idea/modules/Minigames.test.iml" />
|
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Minigames.test.iml" filepath="$PROJECT_DIR$/.idea/modules/Minigames.test.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/modules/eu.mhsl.minenet.Minigames.main.iml" filepath="$PROJECT_DIR$/.idea/modules/eu.mhsl.minenet.Minigames.main.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
4
.idea/modules/Minigames.main.iml
generated
4
.idea/modules/Minigames.main.iml
generated
@@ -10,4 +10,8 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
</facet>
|
</facet>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
</module>
|
</module>
|
||||||
14
build.gradle
14
build.gradle
@@ -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,7 +44,7 @@ dependencies {
|
|||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
|
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
|
||||||
|
|
||||||
//https://jitpack.io/#Minestom/Minestom
|
//https://jitpack.io/#Minestom/Minestom
|
||||||
implementation 'net.minestom:minestom: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'
|
||||||
@@ -57,12 +57,12 @@ 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")
|
||||||
implementation("team.unnamed:hephaestus-reader-blockbench:0.2.1-SNAPSHOT")
|
// implementation("team.unnamed:hephaestus-reader-blockbench:0.2.1-SNAPSHOT")
|
||||||
implementation("team.unnamed:hephaestus-runtime-minestom:0.2.1-SNAPSHOT")
|
// implementation("team.unnamed:hephaestus-runtime-minestom:0.2.1-SNAPSHOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -26,7 +25,7 @@ public class Main {
|
|||||||
public static ConfigurationNode globalConfig;
|
public static ConfigurationNode globalConfig;
|
||||||
|
|
||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
static void main() throws ConfigurateException {
|
public static void main(String[] args) throws ConfigurateException {
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
Resource.values(); // This initializes and preloads the enum and extracts the resources
|
Resource.values(); // This initializes and preloads the enum and extracts the resources
|
||||||
Languages.getInstance(); //Preload languages into the jvm
|
Languages.getInstance(); //Preload languages into the jvm
|
||||||
@@ -41,35 +40,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();
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class PublishRewardCommand extends PrivilegedCommand {
|
|||||||
|
|
||||||
String rewardRequestJson = new Gson().toJson(room.getTournament().getRewards());
|
String rewardRequestJson = new Gson().toJson(room.getTournament().getRewards());
|
||||||
HttpRequest giveRewardsRequest = HttpRequest.newBuilder()
|
HttpRequest giveRewardsRequest = HttpRequest.newBuilder()
|
||||||
.uri(new URI("http://10.20.7.1:8080/api/event/reward"))
|
.uri(new URI("http://10.20.9.3:8080/api/event/reward"))
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(rewardRequestJson))
|
.POST(HttpRequest.BodyPublishers.ofString(rewardRequestJson))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class SetMemorialCommand extends PrivilegedCommand {
|
|||||||
ArgumentString loreArgument = ArgumentType.String("lore");
|
ArgumentString loreArgument = ArgumentType.String("lore");
|
||||||
|
|
||||||
materialArgument.setSuggestionCallback(
|
materialArgument.setSuggestionCallback(
|
||||||
(_, _, suggestion) -> Material
|
(sender, context, suggestion) -> 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())))
|
||||||
@@ -35,7 +35,7 @@ public class SetMemorialCommand extends PrivilegedCommand {
|
|||||||
.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)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class SetRewardCommand extends PrivilegedCommand {
|
|||||||
ArgumentStringArray amountsArgument = ArgumentType.StringArray("amount");
|
ArgumentStringArray amountsArgument = ArgumentType.StringArray("amount");
|
||||||
|
|
||||||
materialArgument.setSuggestionCallback(
|
materialArgument.setSuggestionCallback(
|
||||||
(_, _, suggestion) -> Material
|
(sender, context, suggestion) -> 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())))
|
||||||
@@ -37,7 +37,7 @@ public class SetRewardCommand extends PrivilegedCommand {
|
|||||||
.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())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public class SetRoomOwnerCommand extends PrivilegedCommand {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.addSyntax((sender, context) -> {
|
this.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));
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package eu.mhsl.minenet.minigames.handler.global;
|
|||||||
|
|
||||||
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.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.minestom.server.event.EventListener;
|
import net.minestom.server.event.EventListener;
|
||||||
import net.minestom.server.event.player.PlayerChatEvent;
|
import net.minestom.server.event.player.PlayerChatEvent;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -14,7 +16,14 @@ public class ChatFormatHandler implements EventListener<PlayerChatEvent> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull Result run(@NotNull PlayerChatEvent event) {
|
public @NotNull Result run(@NotNull PlayerChatEvent event) {
|
||||||
event.setFormattedMessage(new ChatMessage(Icon.CHAT).appendStatic(event.getRawMessage()).build(event.getPlayer()));
|
NamedTextColor color = event.getPlayer().getPermissionLevel() > 0 ? NamedTextColor.AQUA : NamedTextColor.GRAY;
|
||||||
|
event.setFormattedMessage(
|
||||||
|
new ChatMessage(Icon.CHAT)
|
||||||
|
.appendStatic(Component.text(event.getPlayer().getUsername(), color))
|
||||||
|
.appendStatic(Component.text(" > ", NamedTextColor.DARK_GRAY))
|
||||||
|
.appendStatic(event.getRawMessage())
|
||||||
|
.build(event.getPlayer())
|
||||||
|
);
|
||||||
return Result.SUCCESS;
|
return Result.SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +1,49 @@
|
|||||||
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(Key namespaceID, DimensionType dimType) {
|
Dimension(NamespaceID 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, this.DIMENSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,15 +7,14 @@ 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.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);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -34,7 +34,7 @@ public abstract class Game extends MineNetInstance implements Spawnable {
|
|||||||
protected boolean isRunning = false;
|
protected boolean isRunning = false;
|
||||||
protected boolean isBeforeBeginning = true;
|
protected boolean isBeforeBeginning = true;
|
||||||
|
|
||||||
public Game(RegistryKey<@NotNull DimensionType> dimensionType) {
|
public Game(DynamicRegistry.Key<DimensionType> dimensionType) {
|
||||||
super(dimensionType);
|
super(dimensionType);
|
||||||
|
|
||||||
MinecraftServer.getInstanceManager().registerInstance(this);
|
MinecraftServer.getInstanceManager().registerInstance(this);
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.acidRain.AcidRain
|
|||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.anvilRun.AnvilRunFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.backrooms.BackroomsFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bedwars.BedwarsFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle.BlockBattleFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace.BlockBreakRaceFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBreakRace.BlockBreakRaceFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace.BoatRaceFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.bowSpleef.BowSpleefFactory;
|
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.elytraRace.ElytraRaceFactory;
|
||||||
@@ -13,6 +15,7 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.fastbridge.Fastbr
|
|||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.highGround.HighGroundFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.highGround.HighGroundFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive.JumpDiveFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.jumpDive.JumpDiveFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun.MinerunFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.minerun.MinerunFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.pillars.PillarsFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.spaceSnake.SpaceSnakeFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.spaceSnake.SpaceSnakeFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef.SpleefFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.spleef.SpleefFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight.StickFightFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.stickfight.StickFightFactory;
|
||||||
@@ -44,7 +47,10 @@ public enum GameList {
|
|||||||
HIGHGROUND(new HighGroundFactory(), GameType.PVP),
|
HIGHGROUND(new HighGroundFactory(), GameType.PVP),
|
||||||
FASTBRIDGE(new FastbridgeFactory(), GameType.OTHER),
|
FASTBRIDGE(new FastbridgeFactory(), GameType.OTHER),
|
||||||
BLOCKBREAKRACE(new BlockBreakRaceFactory(), GameType.OTHER),
|
BLOCKBREAKRACE(new BlockBreakRaceFactory(), GameType.OTHER),
|
||||||
SPACESNAKE(new SpaceSnakeFactory(), GameType.PVP);
|
SPACESNAKE(new SpaceSnakeFactory(), GameType.PVP),
|
||||||
|
BOATRACE(new BoatRaceFactory(), GameType.OTHER),
|
||||||
|
PILLARS(new PillarsFactory(), GameType.PROTOTYPE),
|
||||||
|
BLOCKBATTLE(new BlockBattleFactory(), GameType.PROTOTYPE);
|
||||||
|
|
||||||
private final GameFactory factory;
|
private final GameFactory factory;
|
||||||
private final GameType type;
|
private final GameType type;
|
||||||
|
|||||||
@@ -9,12 +9,11 @@ import eu.mhsl.minenet.minigames.score.Score;
|
|||||||
import net.kyori.adventure.audience.Audience;
|
import net.kyori.adventure.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;
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import net.minestom.server.entity.Player;
|
|||||||
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
|
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
|
||||||
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
|
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
|
||||||
import net.minestom.server.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,8 +39,8 @@ 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();
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ public class GameConfigurationInventory extends InteractableInventory {
|
|||||||
)
|
)
|
||||||
.build(),
|
.build(),
|
||||||
0,
|
0,
|
||||||
itemClick -> itemClick.player().closeInventory(),
|
itemClick -> itemClick.getPlayer().closeInventory(),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -105,7 +106,8 @@ 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(!this.map.containsKey(slot)) return;
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ public class GameConfigurationInventory extends InteractableInventory {
|
|||||||
.lore(restrictionHandler.getWarnings(restrictionData).stream().map(translatedComponent -> translatedComponent.getAssembled(this.p)).collect(Collectors.toList()))
|
.lore(restrictionHandler.getWarnings(restrictionData).stream().map(translatedComponent -> translatedComponent.getAssembled(this.p)).collect(Collectors.toList()))
|
||||||
.build(),
|
.build(),
|
||||||
8,
|
8,
|
||||||
itemClick -> Game.initialize(this.factory, this.map.values().stream().toList(), itemClick.player()),
|
itemClick -> Game.initialize(this.factory, this.map.values().stream().toList(), itemClick.getPlayer()),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -153,7 +155,7 @@ public class GameConfigurationInventory extends InteractableInventory {
|
|||||||
this.updatePlayButton();
|
this.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
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,207 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
|
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
|
||||||
|
import eu.mhsl.minenet.minigames.util.BatchUtil;
|
||||||
|
import io.github.togar2.pvp.events.FinalAttackEvent;
|
||||||
|
import io.github.togar2.pvp.feature.CombatFeatures;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.event.player.PlayerBlockBreakEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
|
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class BlockBattle extends StatelessGame {
|
||||||
|
private final Team teamBlue = new Team(new Pos(0,101,20).add(0.5).withView(180, 0), Team.Color.BLUE);
|
||||||
|
private final Team teamRed = new Team(new Pos(0, 101, -20).add(0.5), Team.Color.RED);
|
||||||
|
private final int itemCount;
|
||||||
|
|
||||||
|
private final Map<Player, Team> teams = new WeakHashMap<>();
|
||||||
|
|
||||||
|
public BlockBattle(int itemCount) {
|
||||||
|
super(Dimension.THE_END.key, "Block Battle", new FirstWinsScore());
|
||||||
|
|
||||||
|
this.itemCount = itemCount;
|
||||||
|
|
||||||
|
this.eventNode().addChild(
|
||||||
|
CombatFeatures.empty()
|
||||||
|
.add(CombatFeatures.VANILLA_ATTACK)
|
||||||
|
.add(CombatFeatures.VANILLA_DAMAGE)
|
||||||
|
.add(CombatFeatures.VANILLA_KNOCKBACK)
|
||||||
|
.build().createNode()
|
||||||
|
);
|
||||||
|
|
||||||
|
this.eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
|
||||||
|
if(this.isBeforeBeginning) finalAttackEvent.setCancelled(true);
|
||||||
|
finalAttackEvent.setBaseDamage(0);
|
||||||
|
((Player) finalAttackEvent.getTarget()).setHealth(20);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||||
|
this.generatePlatform(new Pos(0, 100, 0), Block.GOLD_BLOCK, Block.YELLOW_CONCRETE_POWDER);
|
||||||
|
this.generatePlatform(new Pos(0, 101, 0), Block.AIR, Block.SANDSTONE_SLAB);
|
||||||
|
this.generatePlatform(new Pos(0, 100, 20), Block.BLUE_CONCRETE, Block.BLUE_CONCRETE_POWDER);
|
||||||
|
this.generatePlatform(new Pos(0, 100, -20), Block.RED_CONCRETE, Block.RED_CONCRETE_POWDER);
|
||||||
|
this.generatePlatform(new Pos(-5, 101, -14), Block.RED_STAINED_GLASS, Block.AIR);
|
||||||
|
this.generatePlatform(new Pos(5, 101, 14), Block.BLUE_STAINED_GLASS, Block.AIR);
|
||||||
|
|
||||||
|
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
|
||||||
|
|
||||||
|
Pos[] positionsRedGlass = {
|
||||||
|
new Pos(2, 102, -9),
|
||||||
|
new Pos(-1, 103, -9),
|
||||||
|
new Pos(-2, 104, -6),
|
||||||
|
new Pos(-5, 103, -7),
|
||||||
|
new Pos(-7, 102, -10),
|
||||||
|
new Pos(3, 102, -12),
|
||||||
|
new Pos(5, 101, -15)
|
||||||
|
};
|
||||||
|
|
||||||
|
Pos[] positionsBlueGlass = {
|
||||||
|
new Pos(-5, 101, 15),
|
||||||
|
new Pos(-3, 102, 12),
|
||||||
|
new Pos(-2, 102, 9),
|
||||||
|
new Pos(1, 103, 9),
|
||||||
|
new Pos(2, 104, 6),
|
||||||
|
new Pos(5, 103, 7),
|
||||||
|
new Pos(7, 102, 10)
|
||||||
|
};
|
||||||
|
|
||||||
|
for(Pos pos : positionsRedGlass)
|
||||||
|
batch.setBlock(pos, Block.RED_STAINED_GLASS);
|
||||||
|
|
||||||
|
for(Pos pos : positionsBlueGlass)
|
||||||
|
batch.setBlock(pos, Block.BLUE_STAINED_GLASS);
|
||||||
|
|
||||||
|
BatchUtil.loadAndApplyBatch(batch, this, () -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {
|
||||||
|
Pos posGoldBlock = new Pos(playerBlockPlaceEvent.getBlockPosition()).sub(0, 1, 0);
|
||||||
|
Block goldBlock = playerBlockPlaceEvent.getInstance().getBlock(posGoldBlock);
|
||||||
|
|
||||||
|
playerBlockPlaceEvent.setCancelled(goldBlock != Block.GOLD_BLOCK);
|
||||||
|
|
||||||
|
playerBlockPlaceEvent.getInstance().scheduler().scheduleNextTick(() -> {
|
||||||
|
Pos middle = new Pos(0, 101, 0);
|
||||||
|
boolean validBlue = true;
|
||||||
|
boolean validRed = true;
|
||||||
|
|
||||||
|
for(int x = middle.blockX()-1; x < middle.blockX()+2; x++) {
|
||||||
|
for(int z = middle.blockZ()-1; z < middle.blockZ()+2; z++) {
|
||||||
|
if(playerBlockPlaceEvent.getInstance().getBlock(x, 101, z) != Block.BLUE_WOOL) {
|
||||||
|
validBlue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!validBlue)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = middle.blockX()-1; x < middle.blockX()+2; x++) {
|
||||||
|
for(int z = middle.blockZ()-1; z < middle.blockZ()+2; z++) {
|
||||||
|
if(playerBlockPlaceEvent.getInstance().getBlock(x, 101, z) != Block.RED_WOOL) {
|
||||||
|
validRed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!validRed)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!validBlue && !validRed) return;
|
||||||
|
var winningTeam = validBlue ? Team.Color.BLUE : Team.Color.RED;
|
||||||
|
var winningPlayers = this.teams.entrySet().stream()
|
||||||
|
.filter(entry -> entry.getValue().color().equals(winningTeam))
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
this.getScore().insertMultiple(winningPlayers);
|
||||||
|
super.stop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent playerBlockBreakEvent) {
|
||||||
|
boolean isAllowed = Arrays.stream(Team.Color.values())
|
||||||
|
.map(Team.Color::getMaterial)
|
||||||
|
.map(Material::block)
|
||||||
|
.toList()
|
||||||
|
.contains(playerBlockBreakEvent.getBlock());
|
||||||
|
if(!isAllowed) playerBlockBreakEvent.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
|
||||||
|
if(playerMoveEvent.getNewPosition().y() < 95) {
|
||||||
|
var player = playerMoveEvent.getPlayer();
|
||||||
|
|
||||||
|
player.teleport(
|
||||||
|
this.isBeforeBeginning
|
||||||
|
? this.getSpawn()
|
||||||
|
: this.teams.get(player).spawnPosition()
|
||||||
|
);
|
||||||
|
|
||||||
|
this.giveItems(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
this.setTeams();
|
||||||
|
this.getPlayers().forEach(player -> player.teleport(this.teams.get(player).spawnPosition()).thenRun(() -> {
|
||||||
|
this.giveItems(player);
|
||||||
|
player.setGameMode(GameMode.SURVIVAL);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generatePlatform(Pos center, Block inner, Block outer) {
|
||||||
|
for(int x = center.blockX()-2; x < center.blockX()+3; x++) {
|
||||||
|
for(int z = center.blockZ()-2; z < center.blockZ()+3; z++) {
|
||||||
|
this.setBlock(x, center.blockY(), z, outer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int x = center.blockX()-1; x < center.blockX()+2; x++) {
|
||||||
|
for(int z = center.blockZ()-1; z < center.blockZ()+2; z++) {
|
||||||
|
this.setBlock(x, center.blockY(), z, inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTeams() {
|
||||||
|
List<Player> players = new ArrayList<>(this.getPlayers());
|
||||||
|
Collections.shuffle(players);
|
||||||
|
int halfPlayers = players.size()/2;
|
||||||
|
players.subList(0, halfPlayers).forEach(player -> this.teams.put(player, this.teamBlue));
|
||||||
|
players.subList(halfPlayers, players.size()).forEach(player -> this.teams.put(player, this.teamRed));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pos getSpawn() {
|
||||||
|
return new Pos(0, 101, 0).add(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void giveItems(Player player) {
|
||||||
|
player.getInventory().clear();
|
||||||
|
ItemStack item = ItemStack.of(
|
||||||
|
this.teams.get(player).color().getMaterial(),
|
||||||
|
this.itemCount
|
||||||
|
);
|
||||||
|
player.getInventory().addItemStack(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.Game;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.room.Room;
|
||||||
|
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class BlockBattleFactory implements GameFactory {
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent name() {
|
||||||
|
return TranslatedComponent.byId("game_BlockBattle#name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent description() {
|
||||||
|
return TranslatedComponent.byId("game_BlockBattle#description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigManager configuration() {
|
||||||
|
return new ConfigManager()
|
||||||
|
.addOption(new NumericOption("itemCount", Material.WHITE_WOOL, TranslatedComponent.byId("game_BlockBattle#itemCount"), 1, 2, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material symbol() {
|
||||||
|
return Material.GREEN_CONCRETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
|
return new BlockBattle(configuration.get("itemCount").getAsInt()).setParent(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.blockBattle;
|
||||||
|
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
|
public record Team(Pos spawnPosition, Color color) {
|
||||||
|
public enum Color {
|
||||||
|
RED(Material.RED_WOOL),
|
||||||
|
BLUE(Material.BLUE_WOOL);
|
||||||
|
|
||||||
|
private final Material block;
|
||||||
|
|
||||||
|
Color(Material block) {
|
||||||
|
this.block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material getMaterial() {
|
||||||
|
return this.block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.Resource;
|
||||||
|
import eu.mhsl.minenet.minigames.handler.global.PlayerLoginHandler;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
|
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
|
||||||
|
import eu.mhsl.minenet.minigames.util.CommonProperties;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.Entity;
|
||||||
|
import net.minestom.server.entity.EntityType;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
|
import net.minestom.server.instance.anvil.AnvilLoader;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
|
||||||
|
public class BoatRace extends StatelessGame {
|
||||||
|
public BoatRace() {
|
||||||
|
super(Dimension.OVERWORLD.key, "boatRace", new FirstWinsScore());
|
||||||
|
this.setChunkLoader(new AnvilLoader(Resource.GAME_MAP.getPath().resolve("boatRace/woodlandMansion")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onPlayerJoin(Player p) {
|
||||||
|
Entity boat = new Entity(EntityType.OAK_BOAT);
|
||||||
|
boat.setInstance(this, this.getSpawn());
|
||||||
|
boat.setSynchronizationTicks(100000);
|
||||||
|
PlayerLoginHandler.globalTeam.addMember(boat.getUuid().toString());
|
||||||
|
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> boat.addPassenger(p));
|
||||||
|
return super.onPlayerJoin(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLoad(@NotNull CompletableFuture<Void> callback) {
|
||||||
|
for(int z = 9; z <= 32; z++) {
|
||||||
|
this.setBlock(31, 235, z, Block.CHERRY_FENCE.withProperties(CommonProperties.fenceNorthSouth));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
for(int z = 9; z <= 32; z++) {
|
||||||
|
this.setBlock(31, 235, z, Block.AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPlayerMove(@NotNull PlayerMoveEvent event) {
|
||||||
|
if (this.isBeforeBeginning) return;
|
||||||
|
|
||||||
|
if(event.getNewPosition().z() > 469) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
this.getScore().insertResult(player);
|
||||||
|
|
||||||
|
Entity vehicle = player.getVehicle();
|
||||||
|
if(vehicle != null) {
|
||||||
|
vehicle.removePassenger(player);
|
||||||
|
player.teleport(player.getPosition().withY(y -> y + 3));
|
||||||
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
|
vehicle.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pos getSpawn() {
|
||||||
|
return new Pos(20, 236, 20, -90, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.boatRace;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.Game;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.room.Room;
|
||||||
|
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class BoatRaceFactory implements GameFactory {
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent name() {
|
||||||
|
return TranslatedComponent.byId("game_BoatRace#name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material symbol() {
|
||||||
|
return Material.OAK_BOAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
|
return new BoatRace().setParent(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@ class Deathcube extends StatelessGame {
|
|||||||
.add(CombatFeatures.VANILLA_KNOCKBACK)
|
.add(CombatFeatures.VANILLA_KNOCKBACK)
|
||||||
.build().createNode()
|
.build().createNode()
|
||||||
);
|
);
|
||||||
|
System.out.println(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public class ElytraRace extends StatelessGame {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.playerCheckpoints.putIfAbsent(player, new CheckPointData(this.ringSpacing, this.ringSpacing * 2));
|
this.playerCheckpoints.putIfAbsent(player, new CheckPointData(0, this.ringSpacing));
|
||||||
|
|
||||||
if(newPos.z() > this.generatedUntil - this.ringSpacing) {
|
if(newPos.z() > this.generatedUntil - this.ringSpacing) {
|
||||||
this.generateRing(this.generatedUntil + this.ringSpacing);
|
this.generateRing(this.generatedUntil + this.ringSpacing);
|
||||||
@@ -224,7 +224,9 @@ public class ElytraRace extends StatelessGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void toCheckpoint(Player p) {
|
private void toCheckpoint(Player p) {
|
||||||
|
CheckPointData data = this.playerCheckpoints.get(p);
|
||||||
Point checkpointPos = this.getRingPositionAtZ(this.playerCheckpoints.get(p).currentCheckpoint);
|
Point checkpointPos = this.getRingPositionAtZ(this.playerCheckpoints.get(p).currentCheckpoint);
|
||||||
|
if(data.currentCheckpoint == 0) checkpointPos = this.getSpawn().add(0, 3, 0);
|
||||||
p.setVelocity(Vec.ZERO);
|
p.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));
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import io.github.togar2.pvp.events.EntityKnockbackEvent;
|
|||||||
import io.github.togar2.pvp.events.FinalAttackEvent;
|
import io.github.togar2.pvp.events.FinalAttackEvent;
|
||||||
import io.github.togar2.pvp.events.PrepareAttackEvent;
|
import io.github.togar2.pvp.events.PrepareAttackEvent;
|
||||||
import io.github.togar2.pvp.feature.CombatFeatures;
|
import io.github.togar2.pvp.feature.CombatFeatures;
|
||||||
import io.github.togar2.pvp.feature.knockback.KnockbackSettings;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.event.instance.InstanceTickEvent;
|
import net.minestom.server.event.instance.InstanceTickEvent;
|
||||||
@@ -51,7 +50,7 @@ class HighGround extends StatelessGame {
|
|||||||
|
|
||||||
this.eventNode().addListener(
|
this.eventNode().addListener(
|
||||||
EntityKnockbackEvent.class,
|
EntityKnockbackEvent.class,
|
||||||
entityKnockbackEvent -> entityKnockbackEvent.setSettings(new KnockbackSettings(1.1, 1.1, 2, 0, 0))
|
entityKnockbackEvent -> entityKnockbackEvent.setStrength(1.1f)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.eventNode().addListener(InstanceTickEvent.class, instanceTickEvent -> {
|
this.eventNode().addListener(InstanceTickEvent.class, instanceTickEvent -> {
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.pillars;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.Dimension;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
|
import eu.mhsl.minenet.minigames.score.LastWinsScore;
|
||||||
|
import eu.mhsl.minenet.minigames.util.Position;
|
||||||
|
import io.github.togar2.pvp.feature.CombatFeatures;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.event.item.ItemDropEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerBlockBreakEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
class Pillars extends StatelessGame {
|
||||||
|
private int spawnPosx = 0;
|
||||||
|
private int spawnPosz = 0;
|
||||||
|
private final int pillarSpacing = 10;
|
||||||
|
private final int pillarRowCount = 5;
|
||||||
|
|
||||||
|
public Pillars() {
|
||||||
|
super(Dimension.THE_END.key, "Pillars", new LastWinsScore());
|
||||||
|
this.getScore().setIgnoreLastPlayers(1);
|
||||||
|
|
||||||
|
this.eventNode().addChild(
|
||||||
|
CombatFeatures.empty()
|
||||||
|
.add(CombatFeatures.VANILLA_ATTACK)
|
||||||
|
.add(CombatFeatures.VANILLA_DAMAGE)
|
||||||
|
.add(CombatFeatures.VANILLA_KNOCKBACK)
|
||||||
|
.build().createNode()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onPlayerJoin(Player p) {
|
||||||
|
Pos pos = new Pos(this.spawnPosx * this.pillarSpacing, 100, this.spawnPosz * this.pillarSpacing);
|
||||||
|
this.setBlock(pos.sub(0, 1, 0), Block.BEDROCK);
|
||||||
|
|
||||||
|
if(this.spawnPosx >= this.pillarRowCount) {
|
||||||
|
this.spawnPosx = 0;
|
||||||
|
this.spawnPosz++;
|
||||||
|
}
|
||||||
|
this.spawnPosx++;
|
||||||
|
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> p.teleport(pos.add(0.5, 0, 0.5)));
|
||||||
|
|
||||||
|
return super.onPlayerJoin(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent playerBlockBreakEvent) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onItemDrop(@NotNull ItemDropEvent itemDropEvent) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pos getSpawn() {
|
||||||
|
return new Pos(0, 105, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
|
||||||
|
var player = playerMoveEvent.getPlayer();
|
||||||
|
|
||||||
|
if(this.isBeforeBeginning && Position.hasPositionChanged(player.getPosition(), playerMoveEvent.getNewPosition()))
|
||||||
|
playerMoveEvent.setCancelled(true);
|
||||||
|
|
||||||
|
if(playerMoveEvent.getNewPosition().y() < 80) {
|
||||||
|
this.getScore().insertResult(player);
|
||||||
|
player.teleport(this.getSpawn());
|
||||||
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
this.getPlayers().forEach(player -> player.setGameMode(GameMode.SURVIVAL));
|
||||||
|
|
||||||
|
MinecraftServer.getSchedulerManager().submitTask(() -> {
|
||||||
|
List<Material> materials = Material.values().stream()
|
||||||
|
.filter(material -> !material.equals(Material.AIR))
|
||||||
|
.toList();
|
||||||
|
this.getPlayers().forEach(player -> {
|
||||||
|
ItemStack item = ItemStack.of(materials.get(ThreadLocalRandom.current().nextInt(Material.values().toArray().length)));
|
||||||
|
player.getInventory().addItemStack(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
return TaskSchedule.seconds(5);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.pillars;
|
||||||
|
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.Game;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
||||||
|
import eu.mhsl.minenet.minigames.instance.room.Room;
|
||||||
|
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PillarsFactory implements GameFactory {
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent name() {
|
||||||
|
return TranslatedComponent.byId("game_Pillars#name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TranslatedComponent description() {
|
||||||
|
return TranslatedComponent.byId("game_Pillars#description");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material symbol() {
|
||||||
|
return Material.BEDROCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
|
return new Pillars().setParent(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -110,7 +110,7 @@ public class SpaceSnake extends StatelessGame {
|
|||||||
playerMoveEvent.getPlayer().teleport(this.getSpawn());
|
playerMoveEvent.getPlayer().teleport(this.getSpawn());
|
||||||
playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
|
playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
|
||||||
long livingPlayers = this.getPlayers().stream()
|
long livingPlayers = this.getPlayers().stream()
|
||||||
.filter(p -> this.getScore().hasResult(p))
|
.filter(p -> !this.getScore().hasResult(p))
|
||||||
.count();
|
.count();
|
||||||
if(livingPlayers == 1) this.setTimeLimit(10);
|
if(livingPlayers == 1) this.setTimeLimit(10);
|
||||||
if(livingPlayers == 0) this.stop();
|
if(livingPlayers == 0) this.stop();
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ public class StickFightFactory implements GameFactory {
|
|||||||
@Override
|
@Override
|
||||||
public ConfigManager configuration() {
|
public ConfigManager configuration() {
|
||||||
return new ConfigManager()
|
return new ConfigManager()
|
||||||
.addOption(new NumericOption("length", Material.SANDSTONE, TranslatedComponent.byId("optionCommon#length"), 7, 10, 13, 16, 19));
|
.addOption(new NumericOption("length", Material.SANDSTONE, TranslatedComponent.byId("optionCommon#length"), 7, 10, 13, 16, 19))
|
||||||
|
.addOption(new NumericOption("seconds", Material.CLOCK, TranslatedComponent.byId("optionCommon#seconds"), 30, 60, 90, 120));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -40,7 +41,7 @@ public class StickFightFactory implements GameFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) {
|
||||||
return new Stickfight(configuration.get("length").getAsInt()).setParent(parent);
|
return new Stickfight(configuration.get("length").getAsInt(), configuration.get("seconds").getAsInt()).setParent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import net.minestom.server.coordinate.Pos;
|
|||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -22,10 +24,12 @@ public class Stickfight extends StatelessGame {
|
|||||||
private final WeakHashMap<Player, Pos> spawnPoints = new WeakHashMap<>();
|
private final WeakHashMap<Player, Pos> spawnPoints = new WeakHashMap<>();
|
||||||
private final Map<Player, Integer> scoreMap = new WeakHashMap<>();
|
private final Map<Player, Integer> scoreMap = new WeakHashMap<>();
|
||||||
private boolean countdownStarted = false;
|
private boolean countdownStarted = false;
|
||||||
|
private final int seconds;
|
||||||
|
|
||||||
public Stickfight(int length) {
|
public Stickfight(int length, int seconds) {
|
||||||
super(Dimension.OVERWORLD.key, "Stickfight", new LowestPointsWinScore());
|
super(Dimension.OVERWORLD.key, "Stickfight", new LowestPointsWinScore());
|
||||||
this.radius = length;
|
this.radius = length;
|
||||||
|
this.seconds = seconds;
|
||||||
|
|
||||||
this.eventNode().addChild(
|
this.eventNode().addChild(
|
||||||
CombatFeatures.empty()
|
CombatFeatures.empty()
|
||||||
@@ -79,10 +83,18 @@ public class Stickfight extends StatelessGame {
|
|||||||
this.generateBridge(spawnX, spawnY, spawnZ);
|
this.generateBridge(spawnX, spawnY, spawnZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemStack item = ItemStack.of(Material.STICK).withGlowing(true);
|
||||||
|
players.forEach(player -> player.getInventory().addItemStack(item));
|
||||||
|
|
||||||
this.setBlock(0, 50, 0, Block.GOLD_BLOCK);
|
this.setBlock(0, 50, 0, Block.GOLD_BLOCK);
|
||||||
super.start();
|
super.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
this.setTimeLimit(this.seconds);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
this.scoreMap.forEach((player, score) -> this.getScore().insertResult(player, score));
|
this.scoreMap.forEach((player, score) -> this.getScore().insertResult(player, score));
|
||||||
@@ -117,6 +129,7 @@ public class Stickfight extends StatelessGame {
|
|||||||
player.teleport(this.spawnPoints.get(player));
|
player.teleport(this.spawnPoints.get(player));
|
||||||
this.scoreMap.putIfAbsent(player, 0);
|
this.scoreMap.putIfAbsent(player, 0);
|
||||||
this.scoreMap.put(player, this.scoreMap.get(player) + 1);
|
this.scoreMap.put(player, this.scoreMap.get(player) + 1);
|
||||||
|
player.setLevel(this.scoreMap.get(player));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,16 +6,20 @@ import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.Tetri
|
|||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.Tetromino;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game.Tetromino;
|
||||||
import eu.mhsl.minenet.minigames.score.PointsWinScore;
|
import eu.mhsl.minenet.minigames.score.PointsWinScore;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.entity.Entity;
|
import net.minestom.server.entity.Entity;
|
||||||
|
import net.minestom.server.entity.EntityType;
|
||||||
import net.minestom.server.entity.GameMode;
|
import net.minestom.server.entity.GameMode;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.entity.metadata.display.BlockDisplayMeta;
|
||||||
import net.minestom.server.event.player.PlayerHandAnimationEvent;
|
import net.minestom.server.event.player.PlayerHandAnimationEvent;
|
||||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
|
||||||
import net.minestom.server.event.player.PlayerTickEvent;
|
import net.minestom.server.event.player.PlayerTickEvent;
|
||||||
import net.minestom.server.event.player.PlayerUseItemEvent;
|
import net.minestom.server.event.player.PlayerUseItemEvent;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -71,48 +75,36 @@ class Tetris extends StatelessGame {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPlayerLeave(Player p) {
|
protected void onPlayerLeave(Player p) {
|
||||||
this.tetrisGames.get(p).sidebar.removeViewer(p);
|
this.tetrisGames.get(p).sidebar.removeViewer(p);
|
||||||
|
p.clearEffects();
|
||||||
this.letPlayerLoose(p);
|
this.letPlayerLoose(p);
|
||||||
|
p.setGameMode(GameMode.SURVIVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void onPlayerInteract(@NotNull PlayerUseItemEvent event) {
|
||||||
protected void onPlayerMove(@NotNull PlayerMoveEvent event) {
|
event.setItemUseTime(0);
|
||||||
Player player = event.getPlayer();
|
this.tetrisGames.get(event.getPlayer()).pressedButtonRaw(TetrisGame.Button.mouseRight);
|
||||||
Pos currentPosition = event.getNewPosition();
|
|
||||||
|
|
||||||
TetrisGame tetrisGame = this.tetrisGames.get(player);
|
|
||||||
|
|
||||||
if(tetrisGame == null) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(tetrisGame.lost) return;
|
|
||||||
if(player.getGameMode() == GameMode.SPECTATOR) return;
|
|
||||||
|
|
||||||
if(player.inputs().forward()) tetrisGame.pressedButton(TetrisGame.Button.W);
|
|
||||||
if(player.inputs().backward()) tetrisGame.pressedButton(TetrisGame.Button.S);
|
|
||||||
if(player.inputs().right()) tetrisGame.pressedButton(TetrisGame.Button.D);
|
|
||||||
if(player.inputs().left()) tetrisGame.pressedButton(TetrisGame.Button.A);
|
|
||||||
if(player.inputs().jump()) tetrisGame.pressedButton(TetrisGame.Button.space);
|
|
||||||
|
|
||||||
event.setNewPosition(tetrisGame.getPlayerSpawnPosition().withView(currentPosition));
|
|
||||||
player.setSprinting(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onPlayerInteract(@NotNull PlayerUseItemEvent event) {
|
private void onPlayerAttack(@NotNull PlayerHandAnimationEvent event) {
|
||||||
this.tetrisGames.get(event.getPlayer()).pressedButton(TetrisGame.Button.mouseRight);
|
this.tetrisGames.get(event.getPlayer()).pressedButtonRaw(TetrisGame.Button.mouseLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onPlayerAttack(@NotNull PlayerHandAnimationEvent event) {
|
private void onPlayerTick(PlayerTickEvent event) {
|
||||||
this.tetrisGames.get(event.getPlayer()).pressedButton(TetrisGame.Button.mouseLeft);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onPlayerTick(PlayerTickEvent event) {
|
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
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) {
|
||||||
this.letPlayerLoose(player);
|
this.letPlayerLoose(player);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(player.getGameMode() == GameMode.SPECTATOR) return;
|
||||||
|
|
||||||
|
if(player.inputs().forward()) tetrisGame.pressedButtonRaw(TetrisGame.Button.W);
|
||||||
|
if(player.inputs().backward()) tetrisGame.pressedButtonRaw(TetrisGame.Button.S);
|
||||||
|
if(player.inputs().right()) tetrisGame.pressedButtonRaw(TetrisGame.Button.D);
|
||||||
|
if(player.inputs().left()) tetrisGame.pressedButtonRaw(TetrisGame.Button.A);
|
||||||
|
if(player.inputs().jump()) tetrisGame.pressedButtonRaw(TetrisGame.Button.space);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void letPlayerLoose(Player player) {
|
private void letPlayerLoose(Player player) {
|
||||||
@@ -120,6 +112,7 @@ class Tetris extends StatelessGame {
|
|||||||
if(!this.getScore().hasResult(player)) {
|
if(!this.getScore().hasResult(player)) {
|
||||||
player.setGameMode(GameMode.SPECTATOR);
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
player.setInvisible(true);
|
player.setInvisible(true);
|
||||||
|
if(player.getVehicle() != null) player.getVehicle().removePassenger(player);
|
||||||
this.getScore().insertResult(player, tetrisGame.getScore());
|
this.getScore().insertResult(player, tetrisGame.getScore());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +150,16 @@ class Tetris extends StatelessGame {
|
|||||||
p.teleport(tetrisGame.getPlayerSpawnPosition());
|
p.teleport(tetrisGame.getPlayerSpawnPosition());
|
||||||
tetrisGame.sidebar.addViewer(p);
|
tetrisGame.sidebar.addViewer(p);
|
||||||
|
|
||||||
|
MinecraftServer.getSchedulerManager().scheduleTask(() -> {
|
||||||
|
Entity ghostBlock = new Entity(EntityType.BLOCK_DISPLAY);
|
||||||
|
((BlockDisplayMeta) ghostBlock.getEntityMeta()).setBlockState(Block.AIR);
|
||||||
|
ghostBlock.setNoGravity(true);
|
||||||
|
ghostBlock.setInstance(this, tetrisGame.getPlayerSpawnPosition());
|
||||||
|
ghostBlock.addPassenger(p);
|
||||||
|
return TaskSchedule.stop();
|
||||||
|
}, TaskSchedule.nextTick());
|
||||||
|
|
||||||
|
|
||||||
return super.onPlayerJoin(p);
|
return super.onPlayerJoin(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
|
||||||
|
|
||||||
|
public enum Orientation {
|
||||||
|
NONE,
|
||||||
|
RIGHT,
|
||||||
|
LEFT,
|
||||||
|
UPSIDE_DOWN;
|
||||||
|
|
||||||
|
public Orientation rotated(boolean clockwise) {
|
||||||
|
switch(this) {
|
||||||
|
case NONE -> {
|
||||||
|
return clockwise ? Orientation.RIGHT : Orientation.LEFT;
|
||||||
|
}
|
||||||
|
case RIGHT -> {
|
||||||
|
return clockwise ? Orientation.UPSIDE_DOWN : Orientation.NONE;
|
||||||
|
}
|
||||||
|
case UPSIDE_DOWN -> {
|
||||||
|
return clockwise ? Orientation.LEFT : Orientation.RIGHT;
|
||||||
|
}
|
||||||
|
case LEFT -> {
|
||||||
|
return clockwise ? Orientation.NONE : Orientation.UPSIDE_DOWN;
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
return Orientation.NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public final class RotationChecker {private static final Map<Orientation, int[][]> STANDARD_WALL_KICKS = Map.of(
|
||||||
|
Orientation.NONE, new int[][] {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}},
|
||||||
|
Orientation.RIGHT, new int[][] {{0,0}, {1,0}, {1,-1}, {0,2}, {1,2}},
|
||||||
|
Orientation.UPSIDE_DOWN, new int[][] {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}},
|
||||||
|
Orientation.LEFT, new int[][] {{0,0}, {-1,0}, {-1,-1}, {0,2}, {-1,2}}
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Map<Orientation, int[][]> I_WALL_KICKS = Map.of(
|
||||||
|
Orientation.NONE, new int[][] {{0,0}, {-1,0}, {2,0}, {-1,0}, {2,0}},
|
||||||
|
Orientation.RIGHT, new int[][] {{-1,0}, {0,0}, {0,0}, {0,1}, {0,-2}},
|
||||||
|
Orientation.UPSIDE_DOWN, new int[][] {{-1,1}, {1,1}, {-2,1}, {1,0}, {-2,0}},
|
||||||
|
Orientation.LEFT, new int[][] {{0,1}, {0,1}, {0,1}, {0,-1}, {0,2}}
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final Map<Orientation, int[][]> O_WALL_KICKS = Map.of(
|
||||||
|
Orientation.NONE, new int[][] {{0,0}},
|
||||||
|
Orientation.RIGHT, new int[][] {{0,-1}},
|
||||||
|
Orientation.UPSIDE_DOWN, new int[][] {{-1,-1}},
|
||||||
|
Orientation.LEFT, new int[][] {{-1,0}}
|
||||||
|
);
|
||||||
|
|
||||||
|
public static int[][] getKicksArray(Orientation from, Orientation to, Tetromino.Shape shape) {
|
||||||
|
int[][] firstOffsets = getOffsetData(from, shape);
|
||||||
|
int[][] secondOffsets = getOffsetData(to, shape);
|
||||||
|
int[][] result = new int[firstOffsets.length][2];
|
||||||
|
|
||||||
|
for(int i = 0; i < firstOffsets.length; i++) {
|
||||||
|
result[i] = subtractInt(firstOffsets[i], secondOffsets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[] subtractInt(int[] first, int[] second) {
|
||||||
|
return IntStream.range(0, first.length)
|
||||||
|
.map(i -> first[i] - second[i])
|
||||||
|
.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[][] getOffsetData(Orientation orientation, Tetromino.Shape shape) {
|
||||||
|
return switch(shape) {
|
||||||
|
case J, L, S, T, Z -> STANDARD_WALL_KICKS.get(orientation);
|
||||||
|
case I -> I_WALL_KICKS.get(orientation);
|
||||||
|
case O -> O_WALL_KICKS.get(orientation);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,10 +2,9 @@ package eu.mhsl.minenet.minigames.instance.game.stateless.types.tetris.game;
|
|||||||
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.scoreboard.Sidebar;
|
import net.minestom.server.scoreboard.Sidebar;
|
||||||
import net.minestom.server.timer.Scheduler;
|
import net.minestom.server.timer.Task;
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -23,6 +22,8 @@ public class TetrisGame {
|
|||||||
private final Map<Button, Long> lastPresses = new HashMap<>();
|
private final Map<Button, Long> lastPresses = new HashMap<>();
|
||||||
private final List<TetrisGame> otherTetrisGames = new ArrayList<>();
|
private final List<TetrisGame> otherTetrisGames = new ArrayList<>();
|
||||||
private final Random random;
|
private final Random random;
|
||||||
|
private Task tetrominoLockTask;
|
||||||
|
private Task hardTetrominoLockTask;
|
||||||
public boolean lost = false;
|
public boolean lost = false;
|
||||||
public boolean paused = true;
|
public boolean paused = true;
|
||||||
public Tetromino currentTetromino;
|
public Tetromino currentTetromino;
|
||||||
@@ -53,25 +54,28 @@ public class TetrisGame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pressedButton(Button button) {
|
public void pressedButtonRaw(Button button) {
|
||||||
final int standardButtonDelay = 100;
|
final int standardButtonDelay = 95;
|
||||||
final int buttonDebounce = 70;
|
final int wsButtonDebounce = 70;
|
||||||
|
|
||||||
if(this.lastPresses.getOrDefault(button, 0L) >= System.currentTimeMillis() - standardButtonDelay) return;
|
if(this.lastPresses.getOrDefault(button, 0L) >= System.currentTimeMillis() - standardButtonDelay) return;
|
||||||
|
|
||||||
this.lastPresses.put(button, System.currentTimeMillis());
|
switch(button) {
|
||||||
if(button == Button.W) this.lastPresses.put(button, System.currentTimeMillis() + buttonDebounce);
|
case W -> this.lastPresses.put(button, System.currentTimeMillis() + wsButtonDebounce);
|
||||||
if(button == Button.S) this.lastPresses.put(button, System.currentTimeMillis() - buttonDebounce);
|
case S -> this.lastPresses.put(button, System.currentTimeMillis() - wsButtonDebounce);
|
||||||
|
case mouseLeft, mouseRight -> this.lastPresses.put(button, 0L);
|
||||||
|
default -> this.lastPresses.put(button, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
if(this.lost || this.paused) return;
|
if(this.lost || this.paused) return;
|
||||||
|
|
||||||
switch(button) {
|
switch(button) {
|
||||||
case A -> this.currentTetromino.moveLeft();
|
case A -> this.moveLeft();
|
||||||
case S -> this.moveDown();
|
case S -> this.moveDown();
|
||||||
case D -> this.currentTetromino.moveRight();
|
case D -> this.moveRight();
|
||||||
case W -> this.hardDrop();
|
case W -> this.hardDrop();
|
||||||
case mouseLeft -> this.currentTetromino.rotate(false);
|
case mouseLeft -> this.rotate(false);
|
||||||
case mouseRight -> this.currentTetromino.rotate(true);
|
case mouseRight -> this.rotate(true);
|
||||||
case space -> this.switchHold();
|
case space -> this.switchHold();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,8 +86,7 @@ public class TetrisGame {
|
|||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
this.paused = false;
|
this.paused = false;
|
||||||
Scheduler scheduler = MinecraftServer.getSchedulerManager();
|
this.instance.scheduler().submitTask(() -> {
|
||||||
scheduler.submitTask(() -> {
|
|
||||||
if(this.lost) return TaskSchedule.stop();
|
if(this.lost) return TaskSchedule.stop();
|
||||||
int standardTickDelay = 40;
|
int standardTickDelay = 40;
|
||||||
if(this.isFast) standardTickDelay = 20;
|
if(this.isFast) standardTickDelay = 20;
|
||||||
@@ -111,8 +114,9 @@ public class TetrisGame {
|
|||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if(this.lost || this.paused) return;
|
if(this.lost || this.paused) return;
|
||||||
|
if(!this.currentTetromino.isGrounded()) this.stopTetrominoLockTask(true);
|
||||||
if(!this.currentTetromino.moveDown()) {
|
if(!this.currentTetromino.moveDown()) {
|
||||||
this.setActiveTetrominoDown();
|
this.scheduleTetrominoLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,33 +143,42 @@ public class TetrisGame {
|
|||||||
this.lost = true;
|
this.lost = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean moveDown() {
|
private void moveDown() {
|
||||||
if(!this.currentTetromino.moveDown()) {
|
if(!this.currentTetromino.moveDown()) {
|
||||||
this.setActiveTetrominoDown();
|
this.scheduleTetrominoLock();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
this.score += 1;
|
this.score += 1;
|
||||||
this.updateInfo();
|
this.updateInfo();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hardDrop() {
|
private void moveLeft() {
|
||||||
|
if(this.currentTetromino.moveLeft()) this.stopTetrominoLockTask(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveRight() {
|
||||||
|
if(this.currentTetromino.moveRight()) this.stopTetrominoLockTask(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rotate(boolean clockwise) {
|
||||||
|
if(this.currentTetromino.rotate(clockwise)) this.stopTetrominoLockTask(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hardDrop() {
|
||||||
if(!this.currentTetromino.moveDown()) {
|
if(!this.currentTetromino.moveDown()) {
|
||||||
this.setActiveTetrominoDown();
|
this.lockActiveTetromino();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
this.score += 2;
|
do {
|
||||||
this.updateInfo();
|
|
||||||
while(this.currentTetromino.moveDown()) {
|
|
||||||
this.score += 2;
|
this.score += 2;
|
||||||
this.updateInfo();
|
} while(this.currentTetromino.moveDown());
|
||||||
}
|
this.updateInfo();
|
||||||
this.setActiveTetrominoDown();
|
this.lockActiveTetromino();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean switchHold() {
|
private void switchHold() {
|
||||||
if(!this.holdPossible) return false;
|
if(!this.holdPossible) return;
|
||||||
|
this.stopTetrominoLockTask(true);
|
||||||
|
|
||||||
Tetromino newCurrentTetromino;
|
Tetromino newCurrentTetromino;
|
||||||
if(this.holdTetromino == null) {
|
if(this.holdTetromino == null) {
|
||||||
@@ -189,7 +202,6 @@ public class TetrisGame {
|
|||||||
this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0));
|
this.holdTetromino.setPosition(this.holdPosition.add(xChange, 0, 0));
|
||||||
this.holdTetromino.drawAsEntities();
|
this.holdTetromino.drawAsEntities();
|
||||||
this.holdPossible = false;
|
this.holdPossible = false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateNextTetrominoes() {
|
private void updateNextTetrominoes() {
|
||||||
@@ -235,7 +247,40 @@ public class TetrisGame {
|
|||||||
this.sidebar.updateLineScore("2", this.level);
|
this.sidebar.updateLineScore("2", this.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setActiveTetrominoDown() {
|
private void scheduleTetrominoLock() {
|
||||||
|
if(this.tetrominoLockTask == null || !this.tetrominoLockTask.isAlive())
|
||||||
|
this.tetrominoLockTask = this.instance.scheduler().scheduleTask(() -> {
|
||||||
|
if(this.currentTetromino.isGrounded()) {
|
||||||
|
this.lockActiveTetromino();
|
||||||
|
} else {
|
||||||
|
this.stopTetrominoLockTask(true);
|
||||||
|
}
|
||||||
|
return TaskSchedule.stop();
|
||||||
|
}, TaskSchedule.millis(500));
|
||||||
|
if(this.hardTetrominoLockTask == null || !this.hardTetrominoLockTask.isAlive())
|
||||||
|
this.hardTetrominoLockTask = this.instance.scheduler().scheduleTask(() -> {
|
||||||
|
if(this.currentTetromino.isGrounded()) {
|
||||||
|
this.lockActiveTetromino();
|
||||||
|
} else {
|
||||||
|
this.stopTetrominoLockTask(true);
|
||||||
|
}
|
||||||
|
return TaskSchedule.stop();
|
||||||
|
}, TaskSchedule.millis(6000));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopTetrominoLockTask(boolean resetHard) {
|
||||||
|
if(this.tetrominoLockTask != null) {
|
||||||
|
this.tetrominoLockTask.cancel();
|
||||||
|
this.tetrominoLockTask = null;
|
||||||
|
}
|
||||||
|
if(resetHard && this.hardTetrominoLockTask != null) {
|
||||||
|
this.hardTetrominoLockTask.cancel();
|
||||||
|
this.hardTetrominoLockTask = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lockActiveTetromino() {
|
||||||
|
this.stopTetrominoLockTask(true);
|
||||||
this.currentTetromino.removeOwnEntities();
|
this.currentTetromino.removeOwnEntities();
|
||||||
this.currentTetromino = this.nextTetrominoes.removeFirst();
|
this.currentTetromino = this.nextTetrominoes.removeFirst();
|
||||||
this.currentTetromino.remove();
|
this.currentTetromino.remove();
|
||||||
|
|||||||
@@ -8,14 +8,12 @@ import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
|||||||
import net.minestom.server.instance.block.Block;
|
import net.minestom.server.instance.block.Block;
|
||||||
import net.minestom.server.tag.Tag;
|
import net.minestom.server.tag.Tag;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class Tetromino {
|
public class Tetromino {
|
||||||
private final static EntityType ghostEntityType = EntityType.FALLING_BLOCK;
|
private final static EntityType ghostEntityType = EntityType.FALLING_BLOCK;
|
||||||
private final static Tag<String> uuidTag = Tag.String("uuid");
|
private final static Tag<String> uuidTag = Tag.String("uuid");
|
||||||
|
private Orientation orientation = Orientation.NONE;
|
||||||
private final Shape shape;
|
private final Shape shape;
|
||||||
private final StatelessGame instance;
|
private final StatelessGame instance;
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
@@ -28,10 +26,10 @@ public class Tetromino {
|
|||||||
this.uuid = UUID.randomUUID();
|
this.uuid = UUID.randomUUID();
|
||||||
|
|
||||||
switch(this.shape) {
|
switch(this.shape) {
|
||||||
case I -> this.shapeArray = new int[][]{{0, 0, 0, 0}, {1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}};
|
case I -> this.shapeArray = new int[][]{{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 1, 1, 1, 1}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}};
|
||||||
case J -> this.shapeArray = new int[][]{{1, 0, 0}, {1, 1, 1}, {0, 0, 0}};
|
case J -> this.shapeArray = new int[][]{{1, 0, 0}, {1, 1, 1}, {0, 0, 0}};
|
||||||
case L -> this.shapeArray = new int[][]{{0, 0, 1}, {1, 1, 1}, {0, 0, 0}};
|
case L -> this.shapeArray = new int[][]{{0, 0, 1}, {1, 1, 1}, {0, 0, 0}};
|
||||||
case O -> this.shapeArray = new int[][]{{1, 1}, {1, 1}};
|
case O -> this.shapeArray = new int[][]{{0, 1, 1}, {0, 1, 1}, {0, 0, 0}};
|
||||||
case S -> this.shapeArray = new int[][]{{0, 1, 1}, {1, 1, 0}, {0, 0, 0}};
|
case S -> this.shapeArray = new int[][]{{0, 1, 1}, {1, 1, 0}, {0, 0, 0}};
|
||||||
case T -> this.shapeArray = new int[][]{{0, 1, 0}, {1, 1, 1}, {0, 0, 0}};
|
case T -> this.shapeArray = new int[][]{{0, 1, 0}, {1, 1, 1}, {0, 0, 0}};
|
||||||
case Z -> this.shapeArray = new int[][]{{1, 1, 0}, {0, 1, 1}, {0, 0, 0}};
|
case Z -> this.shapeArray = new int[][]{{1, 1, 0}, {0, 1, 1}, {0, 0, 0}};
|
||||||
@@ -43,12 +41,23 @@ public class Tetromino {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setPosition(Pos newPosition) {
|
public void setPosition(Pos newPosition) {
|
||||||
this.position = newPosition;
|
this.position = new Pos(newPosition.x(), newPosition.y(), newPosition.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean rotate(boolean clockwise) {
|
public boolean rotate(boolean clockwise) {
|
||||||
int[][] newShapeArray = this.getTurnedShapeArray(clockwise);
|
int[][] newShapeArray = this.getTurnedShapeArray(clockwise);
|
||||||
return this.checkCollisionAndMove(this.position, newShapeArray);
|
Orientation newOrientation = this.orientation.rotated(clockwise);
|
||||||
|
|
||||||
|
int[][] kicksArray = RotationChecker.getKicksArray(this.orientation, newOrientation, this.shape);
|
||||||
|
for(int[] k : kicksArray) {
|
||||||
|
Pos candidate = new Pos(this.position.x() + k[0], this.position.y() + k[1], this.position.z());
|
||||||
|
if(this.checkCollisionAndMove(candidate, newShapeArray)) {
|
||||||
|
this.orientation = newOrientation;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean moveDown() {
|
public boolean moveDown() {
|
||||||
@@ -73,7 +82,7 @@ public class Tetromino {
|
|||||||
public void draw(boolean withGhost) {
|
public void draw(boolean withGhost) {
|
||||||
if(withGhost) {
|
if(withGhost) {
|
||||||
Pos ghostPos = this.position;
|
Pos ghostPos = this.position;
|
||||||
while(!this.checkCollision(ghostPos.sub(0, 1, 0), this.shapeArray)) {
|
while(!this.hasCollision(ghostPos.sub(0, 1, 0), this.shapeArray)) {
|
||||||
ghostPos = ghostPos.sub(0, 1, 0);
|
ghostPos = ghostPos.sub(0, 1, 0);
|
||||||
}
|
}
|
||||||
Pos positionChange = this.position.sub(ghostPos);
|
Pos positionChange = this.position.sub(ghostPos);
|
||||||
@@ -182,7 +191,7 @@ public class Tetromino {
|
|||||||
|
|
||||||
private boolean isPartOfTetromino(Pos position) {
|
private boolean isPartOfTetromino(Pos position) {
|
||||||
return this.getBlockPositions().stream()
|
return this.getBlockPositions().stream()
|
||||||
.anyMatch(pos -> pos.equals(position));
|
.anyMatch(pos -> pos.sameBlock(position));
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Pos> getBlockPositions() {
|
private List<Pos> getBlockPositions() {
|
||||||
@@ -198,10 +207,10 @@ public class Tetromino {
|
|||||||
for(int x = 0; x < arrayLength; x++) {
|
for(int x = 0; x < arrayLength; x++) {
|
||||||
for(int y = 0; y < arrayLength; y++) {
|
for(int y = 0; y < arrayLength; y++) {
|
||||||
if(shapeArray[arrayLength - 1 - y][x] == 1) {
|
if(shapeArray[arrayLength - 1 - y][x] == 1) {
|
||||||
switch(this.shape) {
|
if(Objects.requireNonNull(this.shape) == Shape.I) {
|
||||||
case I -> returnList.add(position.add(x - 1, y - 2, 0));
|
returnList.add(position.add(x - 2, y - 2, 0));
|
||||||
case O -> returnList.add(position.add(x, y, 0));
|
} else {
|
||||||
default -> returnList.add(position.add(x - 1, y - 1, 0));
|
returnList.add(position.add(x - 1, y - 1, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,7 +219,7 @@ public class Tetromino {
|
|||||||
return returnList;
|
return returnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkCollision(Pos newPosition, int[][] newShapeArray) {
|
private boolean hasCollision(Pos newPosition, int[][] newShapeArray) {
|
||||||
List<Pos> newBlockPositions = this.getBlockPositions(newPosition, newShapeArray);
|
List<Pos> newBlockPositions = this.getBlockPositions(newPosition, newShapeArray);
|
||||||
|
|
||||||
for(Pos pos : newBlockPositions) {
|
for(Pos pos : newBlockPositions) {
|
||||||
@@ -222,15 +231,17 @@ public class Tetromino {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isGrounded() {
|
||||||
|
return this.hasCollision(this.position.sub(0, 1, 0), this.shapeArray);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkCollisionAndMove(Pos newPosition, int[][] newShapeArray) {
|
private boolean checkCollisionAndMove(Pos newPosition, int[][] newShapeArray) {
|
||||||
if(!this.checkCollision(newPosition, newShapeArray)) {
|
if(this.hasCollision(newPosition, newShapeArray)) return false;
|
||||||
this.remove();
|
this.remove();
|
||||||
this.shapeArray = Arrays.stream(newShapeArray).map(int[]::clone).toArray(int[][]::new);
|
this.shapeArray = Arrays.stream(newShapeArray).map(int[]::clone).toArray(int[][]::new);
|
||||||
this.setPosition(newPosition);
|
this.setPosition(newPosition);
|
||||||
this.draw();
|
this.draw();
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Shape {
|
public enum Shape {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class HubInventory extends InteractableInventory {
|
|||||||
.lore(TranslatedComponent.assemble("hub#create_description", p))
|
.lore(TranslatedComponent.assemble("hub#create_description", p))
|
||||||
.build(),
|
.build(),
|
||||||
12,
|
12,
|
||||||
itemClick -> Room.createRoom(itemClick.player()),
|
itemClick -> Room.createRoom(itemClick.getPlayer()),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ public class HubInventory extends InteractableInventory {
|
|||||||
.lore(TranslatedComponent.assemble("hub#join_description", p))
|
.lore(TranslatedComponent.assemble("hub#join_description", p))
|
||||||
.build(),
|
.build(),
|
||||||
14,
|
14,
|
||||||
itemClick -> itemClick.player().openInventory(new JoinInventory(itemClick.player()))
|
itemClick -> itemClick.getPlayer().openInventory(new JoinInventory(itemClick.getPlayer()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import net.minestom.server.MinecraftServer;
|
|||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.event.player.PlayerPacketEvent;
|
import net.minestom.server.event.player.PlayerPacketEvent;
|
||||||
import net.minestom.server.inventory.InventoryType;
|
import net.minestom.server.inventory.InventoryType;
|
||||||
import net.minestom.server.inventory.click.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.network.packet.client.play.ClientNameItemPacket;
|
import net.minestom.server.network.packet.client.play.ClientNameItemPacket;
|
||||||
@@ -31,7 +32,7 @@ public class JoinInventory extends InteractableInventory {
|
|||||||
.customName(Component.text(this.prefix))
|
.customName(Component.text(this.prefix))
|
||||||
.build(),
|
.build(),
|
||||||
0,
|
0,
|
||||||
_ -> {
|
itemClick -> {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -44,8 +45,9 @@ public class JoinInventory extends InteractableInventory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onClick(Player player, int slot, Click clickType) {
|
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
|
||||||
if(slot != 2) return;
|
if(slot != 2) return;
|
||||||
|
inventoryConditionResult.setCancel(true);
|
||||||
player.closeInventory();
|
player.closeInventory();
|
||||||
|
|
||||||
this.typedText = this.formatInput(this.typedText);
|
this.typedText = this.formatInput(this.typedText);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class MinigameSelectInventory extends InteractableInventory {
|
|||||||
.lore(type.getDescription().addWrap().getWrappedAssembled(p))
|
.lore(type.getDescription().addWrap().getWrappedAssembled(p))
|
||||||
.build(),
|
.build(),
|
||||||
itemAlignment.next().get(),
|
itemAlignment.next().get(),
|
||||||
_ -> this.drawGames(type)
|
itemClick -> this.drawGames(type)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,8 +62,7 @@ public class MinigameSelectInventory extends InteractableInventory {
|
|||||||
.lore(gameFactory.description().addWrap().getWrappedAssembled(this.p))
|
.lore(gameFactory.description().addWrap().getWrappedAssembled(this.p))
|
||||||
.build(),
|
.build(),
|
||||||
offset + itemAlignment.next().get(),
|
offset + itemAlignment.next().get(),
|
||||||
itemClick -> itemClick.player().openInventory(new GameConfigurationInventory(this.room, itemClick.player(), gameFactory)),
|
itemClick -> itemClick.getPlayer().openInventory(new GameConfigurationInventory(this.room, itemClick.getPlayer(), gameFactory))
|
||||||
true
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ public abstract class Score {
|
|||||||
throw new NotImplementedException("This Score type is not able to process points");
|
throw new NotImplementedException("This Score type is not able to process points");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void insertMultiple(Set<Player> p) {
|
||||||
|
p.forEach(player -> this.insertResultProcessor(player, () -> {}));
|
||||||
|
this.insertResultImplementation(p);
|
||||||
|
}
|
||||||
|
|
||||||
public void insertResult(Player p) {
|
public void insertResult(Player p) {
|
||||||
this.insertResultProcessor(p, () -> this.insertResultImplementation(Set.of(p)));
|
this.insertResultProcessor(p, () -> this.insertResultImplementation(Set.of(p)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ public class Tournament {
|
|||||||
for(Player player : players) {
|
for(Player player : players) {
|
||||||
int points = (game.getScores().size() - count) + this.boost(count, game.getScores().size());
|
int points = (game.getScores().size() - count) + this.boost(count, game.getScores().size());
|
||||||
|
|
||||||
data.computeIfPresent(player, (_, existingPoints) -> existingPoints + points);
|
data.computeIfPresent(player, (existingPlayer, existingPoints) -> existingPoints + points);
|
||||||
data.computeIfAbsent(player, _ -> points);
|
data.computeIfAbsent(player, newPlayer -> points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -44,28 +44,28 @@ public class Tournament {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new Rewards(
|
return new Rewards(
|
||||||
this.memorialConfiguration.memorialMaterial().key().value(),
|
this.memorialConfiguration.memorialMaterial().namespace().value(),
|
||||||
this.memorialConfiguration.memorialTitle(),
|
this.memorialConfiguration.memorialTitle(),
|
||||||
this.memorialConfiguration.memorialLore(),
|
this.memorialConfiguration.memorialLore(),
|
||||||
this.getGameScores().keySet().stream().map(Player::getUuid).toList(),
|
this.getGameScores().keySet().stream().map(Player::getUuid).toList(),
|
||||||
this.rewardConfiguration.item().key().value(),
|
this.rewardConfiguration.item().namespace().value(),
|
||||||
itemCount
|
itemCount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Set<Player>> getPlaces() {
|
public List<Set<Player>> getPlaces() {
|
||||||
List<Set<Player>> players = new ArrayList<>(
|
Map<Integer, Set<Player>> players = this.getGameScores().entrySet().stream()
|
||||||
this.getGameScores().entrySet().stream()
|
.collect(
|
||||||
.collect(
|
Collectors.groupingBy(
|
||||||
Collectors.groupingBy(
|
Map.Entry::getValue,
|
||||||
Map.Entry::getValue,
|
Collectors.mapping(Map.Entry::getKey, Collectors.toSet())
|
||||||
Collectors.mapping(Map.Entry::getKey, Collectors.toSet())
|
)
|
||||||
)
|
);
|
||||||
).values()
|
|
||||||
);
|
|
||||||
|
|
||||||
Collections.reverse(players);
|
return players.entrySet().stream()
|
||||||
return players;
|
.sorted(Map.Entry.<Integer, Set<Player>>comparingByKey().reversed())
|
||||||
|
.map(Map.Entry::getValue)
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int boost(int selfPlace, int placeCount) {
|
private int boost(int selfPlace, int placeCount) {
|
||||||
|
|||||||
@@ -2,64 +2,38 @@ package eu.mhsl.minenet.minigames.shared.inventory;
|
|||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.event.inventory.InventoryPreClickEvent;
|
|
||||||
import net.minestom.server.inventory.Inventory;
|
import net.minestom.server.inventory.Inventory;
|
||||||
import net.minestom.server.inventory.InventoryType;
|
import net.minestom.server.inventory.InventoryType;
|
||||||
import net.minestom.server.inventory.click.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 org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class InteractableInventory extends Inventory {
|
public class InteractableInventory extends Inventory {
|
||||||
private final Map<Integer, ClickableItem> clickableItems = new HashMap<>();
|
|
||||||
|
|
||||||
public record ItemClick(Player player, InteractableInventory inventory, int clickedSlot, ItemStack item, Click clickType) { }
|
|
||||||
public record ClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback, boolean closeAfterClick) { }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines an Inventory with direct callbacks for ItemSlots
|
* Defines an Inventory with direct callbacks for ItemSlots
|
||||||
*/
|
*/
|
||||||
protected InteractableInventory(@NotNull InventoryType inventoryType, @NotNull Component title) {
|
protected InteractableInventory(@NotNull InventoryType inventoryType, @NotNull Component title) {
|
||||||
super(inventoryType, title);
|
super(inventoryType, title);
|
||||||
|
|
||||||
this.eventNode().addListener(
|
this.addInventoryCondition(this::onClick);
|
||||||
InventoryPreClickEvent.class,
|
|
||||||
inventoryPreClickEvent -> this.onClick(
|
|
||||||
inventoryPreClickEvent.getPlayer(),
|
|
||||||
inventoryPreClickEvent.getSlot(),
|
|
||||||
inventoryPreClickEvent.getClick()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.eventNode().addListener(InventoryPreClickEvent.class, inventoryPreClickEvent -> {
|
|
||||||
@Nullable ClickableItem selectedItem = this.clickableItems.values().stream()
|
|
||||||
.filter(clickableItem -> clickableItem.slot() == inventoryPreClickEvent.getSlot())
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
if(selectedItem == null) {
|
|
||||||
inventoryPreClickEvent.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(selectedItem.closeAfterClick()) inventoryPreClickEvent.getPlayer().closeInventory();
|
|
||||||
selectedItem.callback().accept(
|
|
||||||
new ItemClick(inventoryPreClickEvent.getPlayer(), this, inventoryPreClickEvent.getSlot(), selectedItem.item(), inventoryPreClickEvent.getClick())
|
|
||||||
);
|
|
||||||
inventoryPreClickEvent.setCancelled(true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Item with Callback
|
* Set Item with Callback
|
||||||
*/
|
*/
|
||||||
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback, boolean closeAfter) {
|
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback, boolean closeAfter) {
|
||||||
ClickableItem clickableItem = new ClickableItem(item, slot, callback, closeAfter);
|
this.setItemStack(slot, item);
|
||||||
this.setItemStack(clickableItem.slot(), clickableItem.item());
|
this.addInventoryCondition((player, clickedSlot, clickType, inventoryConditionResult) -> {
|
||||||
this.clickableItems.put(clickableItem.slot(), clickableItem);
|
if(clickedSlot == slot) {
|
||||||
|
if(closeAfter) player.closeInventory();
|
||||||
|
callback.accept(new ItemClick(player, this, clickedSlot, item, clickType));
|
||||||
|
}
|
||||||
|
inventoryConditionResult.setCancel(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback) {
|
protected void setClickableItem(ItemStack item, int slot, Consumer<ItemClick> callback) {
|
||||||
@@ -73,7 +47,7 @@ public class InteractableInventory extends Inventory {
|
|||||||
this.setClickableItem(
|
this.setClickableItem(
|
||||||
item,
|
item,
|
||||||
slot,
|
slot,
|
||||||
_ -> {
|
itemClick -> {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -88,7 +62,7 @@ public class InteractableInventory extends Inventory {
|
|||||||
/**
|
/**
|
||||||
* You may want to Override this method to get more generic click events
|
* You may want to Override this method to get more generic click events
|
||||||
*/
|
*/
|
||||||
protected void onClick(Player player, int slot, Click clickType) {
|
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package eu.mhsl.minenet.minigames.shared.inventory;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.inventory.Inventory;
|
||||||
|
import net.minestom.server.inventory.click.ClickType;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
|
||||||
|
public class ItemClick {
|
||||||
|
private final Player player;
|
||||||
|
private final InteractableInventory inventory;
|
||||||
|
private final int clickedSlot;
|
||||||
|
private final ItemStack item;
|
||||||
|
private final ClickType clickType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes a click on an Item from an IntractableInventory
|
||||||
|
*/
|
||||||
|
public ItemClick(Player player, InteractableInventory inventory, int clickedSlot, ItemStack item, ClickType clickType) {
|
||||||
|
this.player = player;
|
||||||
|
this.inventory = inventory;
|
||||||
|
this.clickedSlot = clickedSlot;
|
||||||
|
this.item = item;
|
||||||
|
this.clickType = clickType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return this.player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Inventory getInventory() {
|
||||||
|
return this.inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClickedSlot() {
|
||||||
|
return this.clickedSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getItem() {
|
||||||
|
return this.item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClickType getClickType() {
|
||||||
|
return this.clickType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package eu.mhsl.minenet.minigames.util;
|
package eu.mhsl.minenet.minigames.util;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import net.minestom.server.instance.InstanceContainer;
|
import net.minestom.server.instance.InstanceContainer;
|
||||||
import net.minestom.server.instance.batch.Batch;
|
import net.minestom.server.instance.batch.Batch;
|
||||||
import net.minestom.server.instance.batch.ChunkBatch;
|
import net.minestom.server.instance.batch.ChunkBatch;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class BatchUtil {
|
public class BatchUtil {
|
||||||
@@ -16,13 +16,10 @@ public class BatchUtil {
|
|||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<Long, ChunkBatch> chunkBatchesMap = (Map<Long, ChunkBatch>) field.get(batch);
|
Long2ObjectMap<ChunkBatch> chunkBatchesMap = (Long2ObjectMap<ChunkBatch>) field.get(batch);
|
||||||
|
|
||||||
long[] out = new long[chunkBatchesMap.size()];
|
return chunkBatchesMap.keySet().toLongArray();
|
||||||
int i = 0;
|
} catch(NoSuchFieldException | IllegalAccessException e) {
|
||||||
for (Long k : chunkBatchesMap.keySet()) out[i++] = k;
|
|
||||||
return out;
|
|
||||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,9 +36,15 @@ public class BatchUtil {
|
|||||||
long[] affectedChunks = BatchUtil.getAffectedChunks(batch);
|
long[] affectedChunks = BatchUtil.getAffectedChunks(batch);
|
||||||
CompletableFuture<Void> loadChunksTask = ChunkUtils.optionalLoadAll(instance, affectedChunks, null);
|
CompletableFuture<Void> loadChunksTask = ChunkUtils.optionalLoadAll(instance, affectedChunks, null);
|
||||||
|
|
||||||
Runnable completerTask = () -> future.complete(null);
|
Runnable completerTask = () -> {
|
||||||
|
System.out.println("COMPLETE");
|
||||||
|
future.complete(null);
|
||||||
|
};
|
||||||
|
|
||||||
loadChunksTask.thenRun(() -> batch.apply(instance, completerTask));
|
loadChunksTask.thenRun(() -> {
|
||||||
|
System.out.println("BEGIN");
|
||||||
|
batch.apply(instance, completerTask);
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
future.get();
|
future.get();
|
||||||
|
|||||||
@@ -10,4 +10,11 @@ public class CommonProperties {
|
|||||||
this.put("east", "true");
|
this.put("east", "true");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static Map<String, String> fenceNorthSouth = new HashMap<>() {
|
||||||
|
{
|
||||||
|
this.put("north", "true");
|
||||||
|
this.put("south", "true");
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,15 @@ public class Position {
|
|||||||
public static List<Block> blocksBelowPlayer(Instance instance, Player p) {
|
public static List<Block> blocksBelowPlayer(Instance instance, Player p) {
|
||||||
Point playerPos = p.getPosition();
|
Point playerPos = p.getPosition();
|
||||||
List<Block> blocks = new ArrayList<>();
|
List<Block> blocks = new ArrayList<>();
|
||||||
GeneratorUtils.foreachXZ(playerPos.sub(0.5, 1, 0.5), playerPos.add(0.5, -1, 0.5), point -> {
|
GeneratorUtils.foreachXZ(
|
||||||
blocks.add(instance.getBlock(point));
|
playerPos.sub(0.5, 1, 0.5),
|
||||||
});
|
playerPos.add(0.5, -1, 0.5),
|
||||||
|
point -> blocks.add(instance.getBlock(point))
|
||||||
|
);
|
||||||
return blocks.stream().distinct().toList();
|
return blocks.stream().distinct().toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasPositionChanged(Pos oldPos, Pos newPos) {
|
||||||
|
return !oldPos.withView(0, 0).equals(newPos.withView(0, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public class WeatherUtils {
|
|||||||
MinecraftServer.getSchedulerManager().submitTask(() -> {
|
MinecraftServer.getSchedulerManager().submitTask(() -> {
|
||||||
this.intensity += 0.1f;
|
this.intensity += 0.1f;
|
||||||
players.forEach(p -> p.sendPacket(new ChangeGameStatePacket(ChangeGameStatePacket.Reason.RAIN_LEVEL_CHANGE, this.intensity)));
|
players.forEach(p -> p.sendPacket(new ChangeGameStatePacket(ChangeGameStatePacket.Reason.RAIN_LEVEL_CHANGE, this.intensity)));
|
||||||
|
System.out.println(this.intensity);
|
||||||
if(this.intensity < 1) {
|
if(this.intensity < 1) {
|
||||||
return TaskSchedule.millis(500);
|
return TaskSchedule.millis(500);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ public class CircularPlateGenerator extends HeightTerrainGenerator {
|
|||||||
@Override
|
@Override
|
||||||
public void generate(@NotNull GenerationUnit unit) {
|
public void generate(@NotNull GenerationUnit unit) {
|
||||||
this.execution.singleRun(() -> unit.fork(setter -> {
|
this.execution.singleRun(() -> unit.fork(setter -> {
|
||||||
|
System.out.println(new Pos(-(this.radius + this.centerX), unit.absoluteStart().y(), -(this.radius + this.centerZ)));
|
||||||
|
System.out.println(new Pos(this.radius + this.centerX, this.height, this.radius + this.centerZ));
|
||||||
GeneratorUtils.foreachXZ(
|
GeneratorUtils.foreachXZ(
|
||||||
new Pos(-(this.radius + this.centerX), unit.absoluteStart().y(), -(this.radius + this.centerZ)),
|
new Pos(-(this.radius + this.centerX), unit.absoluteStart().y(), -(this.radius + this.centerZ)),
|
||||||
new Pos(this.radius + this.centerX, this.height, this.radius + this.centerZ),
|
new Pos(this.radius + this.centerX, this.height, this.radius + this.centerZ),
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class HeightTerrainGenerator extends BaseGenerator {
|
|||||||
double heightNoise = this.base.getNoise(bottomPoint.x(), bottomPoint.z());
|
double heightNoise = this.base.getNoise(bottomPoint.x(), bottomPoint.z());
|
||||||
double noiseModifier = heightNoise * this.heightNoiseMultiplier.apply(bottomPoint);
|
double noiseModifier = heightNoise * this.heightNoiseMultiplier.apply(bottomPoint);
|
||||||
double heightModifier = NumberUtil.clamp(this.calculateHeight.apply(bottomPoint) + noiseModifier, 1d, unit.size().y());
|
double heightModifier = NumberUtil.clamp(this.calculateHeight.apply(bottomPoint) + noiseModifier, 1d, unit.size().y());
|
||||||
|
if(heightModifier < 1) System.out.println("HEIGHT MODIFIER ILLEGAL");
|
||||||
|
|
||||||
synchronized(this.batches) {
|
synchronized(this.batches) {
|
||||||
double batchNoise = this.batches.getNoise(bottomPoint.x(), bottomPoint.z());
|
double batchNoise = this.batches.getNoise(bottomPoint.x(), bottomPoint.z());
|
||||||
@@ -68,6 +69,8 @@ public class HeightTerrainGenerator extends BaseGenerator {
|
|||||||
Point absoluteHeight = bottomPoint.add(0, heightModifier, 0);
|
Point absoluteHeight = bottomPoint.add(0, heightModifier, 0);
|
||||||
int seaLevel = this.calculateSeaLevel.apply(bottomPoint);
|
int seaLevel = this.calculateSeaLevel.apply(bottomPoint);
|
||||||
if(absoluteHeight.y() < seaLevel) {
|
if(absoluteHeight.y() < seaLevel) {
|
||||||
|
// System.out.println("HM:" + absoluteHeight.y() + " SL:" + seaLevel);
|
||||||
|
// System.out.println("Filling from " + bottomPoint.y() + " to " + absoluteHeight.withY(seaLevel).y());
|
||||||
unit.modifier().fill(bottomPoint.withY(v -> v + heightModifier), absoluteHeight.add(1, 0, 1).withY(seaLevel), Block.WATER);
|
unit.modifier().fill(bottomPoint.withY(v -> v + heightModifier), absoluteHeight.add(1, 0, 1).withY(seaLevel), Block.WATER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ optionPvpEnabled;pvp enabled;PvP aktiviert
|
|||||||
;;
|
;;
|
||||||
ns:game_Stickfight#;;
|
ns:game_Stickfight#;;
|
||||||
name;Stickfight;Stockschlacht
|
name;Stickfight;Stockschlacht
|
||||||
description;Push your opponents off the Bridge;Stoße deine Gegener von der Brücke
|
description;Push your opponents off the Bridge;Stoße deine Gegener von der Brücke, der Spieler mit den wenigsten Toden gewinnt!
|
||||||
;;
|
;;
|
||||||
ns:game_TrafficlightRace#;;
|
ns:game_TrafficlightRace#;;
|
||||||
name;Red light green light;Rotes licht, Grünes licht
|
name;Red light green light;Rotes licht, Grünes licht
|
||||||
@@ -170,3 +170,16 @@ ns:game_TurtleGame#;;
|
|||||||
name;Turtle Game;Turtle Game
|
name;Turtle Game;Turtle Game
|
||||||
description;Eat snacks and dodge bombs to get the highest score!;Esse Snacks und weiche Bomben aus, um den höchsten Score zu erreichen!
|
description;Eat snacks and dodge bombs to get the highest score!;Esse Snacks und weiche Bomben aus, um den höchsten Score zu erreichen!
|
||||||
startSpeed;Start Speed;Startgeschwindigkeit
|
startSpeed;Start Speed;Startgeschwindigkeit
|
||||||
|
;;
|
||||||
|
ns:game_BoatRace#;;
|
||||||
|
name;Boatrace;Bootrennen
|
||||||
|
description;;
|
||||||
|
;;
|
||||||
|
ns:game_Pillars#;;
|
||||||
|
name;Pillars;Pillars
|
||||||
|
description;Build yourself up with your random blocks to reach your opponents and push them down!;Baue dich mit deinen zufälligen Blöcken zu deinen Gegnern und schupse sie runter!
|
||||||
|
;;
|
||||||
|
ns:game_BlockBattle#;;
|
||||||
|
name;Block Battle;Block Kampf
|
||||||
|
description;The team that fills the center with their color first wins!;Das Team, welches als erstes die Mitte mit seiner Farbe gefüllt hat, gewinnt!
|
||||||
|
itemCount;Block Count;Block Anzahl
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user