Compare commits

...
8 Commits
Author SHA1 Message Date
Infinityy a6a19d8e7e fix not being able to go to the nether 2024-08-14 04:13:50 +02:00
Infinityy 0e5f75d258 clean up 2024-08-14 04:13:29 +02:00
Infinityy 58d0a76fd6 fix certain events happening after a uhc is over 2024-08-14 04:13:02 +02:00
Infinityy 51573d49af make shield disables play a sound 2024-08-14 04:12:03 +02:00
Infinityy d874b212af fix not being able to win a game, fix player duplication bug 2024-08-13 15:45:55 +02:00
Infinityy 6cb83af16c bug fixes 2024-08-13 04:57:46 +02:00
Infinityy 9500483332 add basic functionality 2024-08-13 04:10:39 +02:00
Infinityy 4624bab458 initial commit 2024-08-11 03:49:02 +02:00
73 changed files with 980 additions and 2489 deletions

No files matched your search

+8 -3
View File
@@ -3,9 +3,9 @@
<img src="https://notcoded.needs.rest/r/nexia.png" height=150 alt="Nexia Logo"/>
<br>
# Nexia Teams
# Nexia UHC
The shitty thing
The Official UHC Mod for Nexia.
</div>
@@ -17,5 +17,10 @@ The shitty thing
### Build
- Clone the repository
- `git clone https://github.com/nexia-cts/nexia-events`
- `git checkout nexia-teams`
- `git checkout nexia-uhc`
- Run `./gradlew build`
## Known bugs
- Stuck on "Loading Terrain..." when going to the end in a dynamic world
- Nexus bug: can't use horse menu
- Nexus bug: can't use chest minecarts
+15 -48
View File
@@ -1,6 +1,5 @@
plugins {
id 'fabric-loom' version '1.6-SNAPSHOT'
id 'maven-publish'
}
version = project.mod_version
@@ -12,65 +11,51 @@ base {
repositories {
flatDir { dirs("libraries") }
maven { url 'https://repo.minebench.de/' }
maven { url 'https://maven.nucleoid.xyz' }
maven { url 'https://masa.dy.fi/maven' }
}
dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings loom.officialMojangMappings()
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API. This is technically optional, but you probably want it anyway.
modRuntimeOnly(modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}")
modImplementation("com.nexia.nexus:nexus-api:${project.nexus_version}-full")
modImplementation("com.nexia.nexus:nexus-builder:${project.nexus_version}-${project.minecraft_version}-full")
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
include(implementation(annotationProcessor("io.github.llamalad7:mixinextras-fabric:${project.mixin_extras_version}")))
include(implementation("net.kyori:adventure-text-minimessage:4.17.0-SNAPSHOT"))
include(implementation("net.kyori:adventure-text-serializer-gson:4.17.0-SNAPSHOT"))
include(implementation("com.google.code.gson:gson:${project.gson_version}"))
include(modImplementation "eu.pb4:sgui:1.5.1+1.20.5")
include(implementation("net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT"))
}
loom {
accessWidenerPath = file("src/main/resources/nexiateams.accesswidener")
customMinecraftManifest = "https://gist.githubusercontent.com/rizecookey/4c6142baaccc3875f9b227fe22f2ace5/raw/c8ed74b19f7a5315813c9d4b199798b692a8f359/1.16_combat-6.json"
intermediaryUrl = "https://maven.rizecookey.net/net/fabricmc/intermediary/%1\$s/intermediary-%1\$s-v2.jar"
}
processResources {
inputs.property "version", project.version
inputs.property "minecraft_version", project.minecraft_version
inputs.property "nexus_version", project.nexus_version
inputs.property "loader_version", project.loader_version
filteringCharset "UTF-8"
filesMatching("fabric.mod.json") {
expand "version": project.version,
"minecraft_version": project.minecraft_version,
"nexus_version": project.nexus_version,
"loader_version": project.loader_version
}
}
def targetJavaVersion = 21
tasks.withType(JavaCompile).configureEach {
// ensure that the encoding is set to UTF-8, no matter what the system default is
// this fixes some edge cases with special characters not displaying correctly
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
// If Javadoc is generated, this must be specified in that task too.
it.options.encoding = "UTF-8"
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
it.options.release.set(targetJavaVersion)
}
it.options.release = targetJavaVersion
}
java {
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
if (JavaVersion.current() < javaVersion) {
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
}
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
withSourcesJar()
}
@@ -78,22 +63,4 @@ jar {
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"}
}
}
// configure the maven publication
publishing {
publications {
create("mavenJava", MavenPublication) {
artifactId = project.archives_base_name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}
}
+6 -8
View File
@@ -3,17 +3,15 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.20.6
yarn_mappings=1.20.6+build.3
loader_version=0.15.11
minecraft_version=1.16_combat-6
loader_version=0.14.21
# Mod Properties
mod_version = 1.0.0
maven_group = com.nexia
archives_base_name = nexia-teams
archives_base_name = nexia-uhc
# Dependencies
# check this on https://modmuss50.me/fabric.html
fabric_version=0.100.0+1.20.6
gson_version=2.11.0
carpet_version=1.4.141+v240429
fabric_version=0.42.0+1.16
mixin_extras_version=0.4.0
nexus_version=0.1.15
Binary file not shown.
@@ -1,62 +0,0 @@
package com.nexia.teams;
import com.nexia.teams.commands.CommandLoader;
import com.nexia.teams.events.tournament.TournamentFight;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.time.ServerTime;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.kyori.adventure.text.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.GameType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NexiaTeams implements ModInitializer {
public static final String MOD_ID = "nexia-teams";
public static Logger logger = LoggerFactory.getLogger(MOD_ID);
public static boolean pvpEnabled = false;
public static boolean endDisabled = true;
public static boolean netherDisabled = true;
public static boolean hardcoreEnabled = false;
@Override
public void onInitialize() {
ServerLifecycleEvents.SERVER_STARTED.register(ServerTime::firstTick);
ServerLifecycleEvents.SERVER_STOPPING.register(ServerTime::stopServer);
ServerTickEvents.END_SERVER_TICK.register(ServerTime::everyTick);
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
ServerPlayer player = handler.getPlayer();
player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Welcome to Nexia Teams!"))));
});
ServerLivingEntityEvents.AFTER_DEATH.register(((entity, damageSource) -> {
if (entity instanceof ServerPlayer serverPlayer) {
if (TournamentFight.isRunning) {
serverPlayer.setGameMode(GameType.SURVIVAL);
ServerTime.minecraftServer.getCommands().performPrefixedCommand(ServerTime.minecraftServer.createCommandSourceStack().withPermission(4), "protect exclusion remove spawn player " + serverPlayer.getScoreboardName());
TournamentFight.serverPlayers.remove(serverPlayer);
if (TournamentFight.serverPlayers.stream().noneMatch(o -> o.getTeam() == TournamentFight.blueTeam)) {
TournamentFight.end();
}
if (TournamentFight.serverPlayers.stream().noneMatch(o -> o.getTeam() == TournamentFight.redTeam)) {
TournamentFight.end();
}
}
}
}));
logger.info("Loading mod...");
logger.info("Registering commands...");
CommandLoader.registerCommands();
logger.info("Registered commands.");
}
}
@@ -1,19 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.nexia.teams.gui.CalendarGUI;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
public class CalendarCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("calendar").executes(CalendarCommand::execute));
}
private static int execute(CommandContext<CommandSourceStack> context) {
CalendarGUI.openCalendarGUI(context.getSource().getPlayer());
return 0;
}
}
@@ -1,21 +0,0 @@
package com.nexia.teams.commands;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.Event;
public class CommandLoader {
public static void registerCommands() {
Event<CommandRegistrationCallback> callbackEvent = CommandRegistrationCallback.EVENT;
callbackEvent.register(KothCommand::register);
callbackEvent.register(TeamCommand::register);
callbackEvent.register(MeteorCommand::register);
callbackEvent.register(CalendarCommand::register);
callbackEvent.register(HardcoreCommand::register);
callbackEvent.register(PvpCommand::register);
callbackEvent.register(EndCommand::register);
callbackEvent.register(NetherCommand::register);
callbackEvent.register(TournamentCommand::register);
callbackEvent.register(KitCommand::register);
}
}
@@ -1,24 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.teams.NexiaTeams;
import com.nexia.teams.utilities.chat.ChatFormat;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
public class EndCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("end").requires(commandSourceStack -> commandSourceStack.hasPermission(4)).executes(EndCommand::execute));
}
private static int execute(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
NexiaTeams.endDisabled = !NexiaTeams.endDisabled;
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text((NexiaTeams.endDisabled ? "Disabled" : "Enabled") + " end."))));
ChatFormat.nexiaTitle(context.getSource(), "End has been " + (NexiaTeams.endDisabled ? "disabled" : "enabled"));
return 0;
}
}
@@ -1,24 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.teams.NexiaTeams;
import com.nexia.teams.utilities.chat.ChatFormat;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
public class HardcoreCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("hardcore").requires(commandSourceStack -> commandSourceStack.hasPermission(4)).executes(HardcoreCommand::execute));
}
private static int execute(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
NexiaTeams.hardcoreEnabled = !NexiaTeams.hardcoreEnabled;
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text((NexiaTeams.hardcoreEnabled ? "Enabled" : "Disabled") + " hardcore death system."))));
ChatFormat.nexiaTitle(context.getSource(), "Hardcore has been " + (NexiaTeams.hardcoreEnabled ? "enabled" : "disabled"));
return 0;
}
}
@@ -1,28 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.teams.events.tournament.TournamentFight;
import com.nexia.teams.gui.KitGUI;
import com.nexia.teams.utilities.chat.ChatFormat;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
public class KitCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("kit").executes(KitCommand::execute));
}
private static int execute(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
if (!TournamentFight.spawnArea.contains(context.getSource().getPosition())) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You aren't in spawn!"))));
return 1;
}
KitGUI.openKitGUI(context.getSource().getPlayer());
return 0;
}
}
@@ -1,250 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.nexia.teams.commands.suggestions.KothSuggestionProvider;
import com.nexia.teams.events.koth.KothGame;
import com.nexia.teams.events.koth.KothGameHandler;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.data.KothDataManager;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.DataComponents;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import java.io.File;
public class KothCommand {
static String commandSeparator = ": ";
static String[] commands = {
"koth" + commandSeparator + "Display this message",
"koth list" + commandSeparator + "Show all koths.",
"koth create <koth>" + commandSeparator + "Create a KOTH",
"koth pos <koth name>" + commandSeparator + "Set the positions of the KOTH",
"koth time <koth name> <amount of time>" + commandSeparator + "Set the time for how much a player needs to win (in seconds)",
"koth schedule <koth name> <timestamp>" + commandSeparator + "When the KOTH will automatically start.",
"koth start <koth name>" + commandSeparator + "Start the KOTH.",
"koth stop <koth name>" + commandSeparator + "Stop the KOTH."
};
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("koth")
.requires(commandSourceStack -> commandSourceStack.hasPermission(4))
.executes(KothCommand::info)
.then(Commands.literal("list")
.executes(KothCommand::listKothGames))
.then(Commands.literal("create")
.then(Commands.argument("name", StringArgumentType.word()).suggests(new KothSuggestionProvider()).executes(context -> createKoth(context, StringArgumentType.getString(context, "name")))))
.then(Commands.literal("pos")
.then(Commands.argument("name", StringArgumentType.word()).suggests(new KothSuggestionProvider()).executes(context -> setKothPos(context, StringArgumentType.getString(context, "name")))))
.then(Commands.literal("start")
.then(Commands.argument("name", StringArgumentType.word()).suggests(new KothSuggestionProvider()).executes(context -> startKoth(context, StringArgumentType.getString(context, "name")))))
.then(Commands.literal("stop")
.then(Commands.argument("name", StringArgumentType.word()).suggests(new KothSuggestionProvider()).executes(context -> stopKoth(context, StringArgumentType.getString(context, "name")))))
.then(Commands.literal("delete")
.then(Commands.argument("name", StringArgumentType.word()).suggests(new KothSuggestionProvider()).executes(context -> deleteKoth(context, StringArgumentType.getString(context, "name")))))
.then(Commands.literal("time")
.then(Commands.argument("name", StringArgumentType.word()).suggests(new KothSuggestionProvider())
.then(Commands.argument("time", IntegerArgumentType.integer())
.executes(context -> setKothTime(context, StringArgumentType.getString(context, "name"), IntegerArgumentType.getInteger(context, "time"))))))
.then(Commands.literal("schedule")
.then(Commands.argument("name", StringArgumentType.word()).suggests(new KothSuggestionProvider())
.then(Commands.argument("epoch", IntegerArgumentType.integer())
.executes(context -> scheduleKoth(context, StringArgumentType.getString(context, "name"), IntegerArgumentType.getInteger(context, "epoch"))))))
);
}
private static int listKothGames(CommandContext<CommandSourceStack> context) {
if (KothGameHandler.kothGames.isEmpty()) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("There are no KOTH games!"))));
return 1;
}
Component message = Component.text("List of KOTHs:").color(ChatFormat.Minecraft.white);
for (KothGame kothGame : KothGameHandler.kothGames) {
Component component = Component.newline().append(Component.text(kothGame.name).color(kothGame.isRunning ? ChatFormat.Minecraft.green : ChatFormat.Minecraft.white))
.append(Component.text(" | ").color(ChatFormat.Minecraft.dark_gray))
.append(Component.text(kothGame.creator)).color(ChatFormat.Minecraft.white)
.append(Component.text(" | ").color(ChatFormat.Minecraft.dark_gray))
.append(Component.text("Time: " + kothGame.time)).color(ChatFormat.Minecraft.white)
.append(Component.text(" | ").color(ChatFormat.Minecraft.dark_gray))
.append(Component.text(kothGame.level.dimension().location().toString())).color(ChatFormat.Minecraft.white);
if (kothGame.area != null) component = component.append(Component.text(" | ").color(ChatFormat.Minecraft.dark_gray)).append(Component.text(String.format("(%s, %s, %s)", kothGame.area.getCenter().x, kothGame.area.getCenter().y, kothGame.area.getCenter().z))).color(ChatFormat.Minecraft.white);
message = message.append(component);
}
context.getSource().sendSystemMessage(ChatFormat.convertComponent(message));
return 0;
}
private static int info(CommandContext<CommandSourceStack> context) {
Component message = Component.text("");
for (String command : commands) {
String[] commandInfo = command.split(commandSeparator);
if (commandInfo.length < 2) continue;
message = message.append(Component.text("\n/" + commandInfo[0])
.color(ChatFormat.brandColor1)
.append(Component.text(" | ").color(ChatFormat.Minecraft.aqua))
.append(Component.text(commandInfo[1]).color(ChatFormat.brandColor2)));
}
context.getSource().sendSystemMessage(ChatFormat.convertComponent(message));
return 0;
}
private static int createKoth(CommandContext<CommandSourceStack> context, String name) {
if (KothGameHandler.getKothGameByName(name) != null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH name is taken!"))));
return 1;
}
KothGameHandler.kothGames.add(new KothGame(context.getSource().getPlayer().getScoreboardName(), name, null, null, null, context.getSource().getLevel()));
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("KOTH " + name + " has been created!"))));
return 0;
}
private static int setKothPos(CommandContext<CommandSourceStack> context, String name) {
KothGame kothGame = KothGameHandler.getKothGameByName(name);
if (kothGame == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH doesn't exist!"))));
return 1;
}
ItemStack kothEditorItem = new ItemStack(Items.DIAMOND_AXE);
kothEditorItem.applyComponents(DataComponentMap.builder().set(
DataComponents.CUSTOM_NAME,
net.minecraft.network.chat.Component.literal("Koth editor")
).build());
context.getSource().getPlayer().addItem(kothEditorItem);
context.getSource().getPlayer().addTag("koth_" + name);
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You are now editing the KOTH area."))));
return 0;
}
private static int setKothTime(CommandContext<CommandSourceStack> context, String name, int amountOfTime) {
KothGame kothGame = KothGameHandler.getKothGameByName(name);
if (kothGame == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH doesn't exist!"))));
return 1;
}
if (kothGame.isRunning) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH is running!"))));
return 1;
}
if (amountOfTime <= 0) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Invalid amount of time!"))));
return 1;
}
kothGame.time = amountOfTime;
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Changed the amount of time a player needs to win."))));
return 0;
}
private static int scheduleKoth(CommandContext<CommandSourceStack> context, String name, long scheduledTimestamp) {
KothGame kothGame = KothGameHandler.getKothGameByName(name);
if (kothGame == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH doesn't exist!"))));
return 1;
}
if (kothGame.isRunning) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH is running!"))));
return 1;
}
long unixTime = System.currentTimeMillis() / 1000L;
if (scheduledTimestamp < unixTime) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Cannot schedule a KOTH in the past!"))));
return 1;
}
kothGame.scheduledTimestamp = scheduledTimestamp;
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Scheduled KOTH."))));
return 0;
}
private static int startKoth(CommandContext<CommandSourceStack> context, String name) {
KothGame kothGame = KothGameHandler.getKothGameByName(name);
if (kothGame == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH doesn't exist!"))));
return 1;
}
if (kothGame.area == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("KOTH position hasn't been set!"))));
return 1;
}
if (kothGame.isRunning) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH is running!"))));
return 1;
}
kothGame.start();
return 0;
}
private static int stopKoth(CommandContext<CommandSourceStack> context, String name) {
KothGame kothGame = KothGameHandler.getKothGameByName(name);
if (kothGame == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH doesn't exist!"))));
return 1;
}
if (!kothGame.isRunning) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH isn't running!"))));
return 1;
}
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You stopped the KOTH."))));
kothGame.end(null);
return 0;
}
private static int deleteKoth(CommandContext<CommandSourceStack> context, String name) {
KothGame kothGame = KothGameHandler.getKothGameByName(name);
if (kothGame == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH doesn't exist!"))));
return 1;
}
if (kothGame.isRunning) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That KOTH is running!"))));
return 1;
}
KothGameHandler.kothGames.remove(kothGame);
File kothFile = new File(KothDataManager.dataDirectory + "/" + kothGame.name + ".json");
if (kothFile.delete()) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("KOTH has been deleted."))));
} else {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("There has been an issue deleting the KOTH."))));
}
return 0;
}
}
@@ -1,48 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.nexia.teams.events.meteor.Meteor;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.time.ServerTime;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer;
public class MeteorCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("meteor")
.requires(commandSourceStack -> commandSourceStack.hasPermission(4))
.then(Commands.argument("scheduledTimestamp", IntegerArgumentType.integer())
.executes(context -> execute(context, IntegerArgumentType.getInteger(context, "scheduledTimestamp"))))
);
}
private static int execute(CommandContext<CommandSourceStack> context, long scheduledTimestamp) {
long unixTime = System.currentTimeMillis() / 1000L;
if (scheduledTimestamp < unixTime) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Cannot schedule a meteor in the past!"))));
return 1;
}
Meteor.scheduledTimestamp = scheduledTimestamp;
Meteor.serverPlayer = context.getSource().getPlayer();
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You have scheduled a meteor!"))));
int secondsDifference = (int) (scheduledTimestamp - unixTime);
int seconds = secondsDifference % 60;
int hours = secondsDifference / 60;
int minutes = hours % 60;
hours = hours / 60;
Meteor.generateRandomCoordinates();
for (ServerPlayer serverPlayer : ServerTime.minecraftServer.getPlayerList().getPlayers()) {
serverPlayer.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text(String.format("Meteor will strike at (%s, %s) in %s hours, %s minutes and %s seconds.", Meteor.meteorCoordinates[0], Meteor.meteorCoordinates[2], hours, minutes, seconds)))));
}
return 0;
}
}
@@ -1,24 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.teams.NexiaTeams;
import com.nexia.teams.utilities.chat.ChatFormat;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
public class NetherCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("nether").requires(commandSourceStack -> commandSourceStack.hasPermission(4)).executes(NetherCommand::execute));
}
private static int execute(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
NexiaTeams.netherDisabled = !NexiaTeams.netherDisabled;
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text((NexiaTeams.netherDisabled ? "Disabled" : "Enabled") + " nether."))));
ChatFormat.nexiaTitle(context.getSource(), "Nether has been " + (NexiaTeams.netherDisabled ? "disabled" : "enabled"));
return 0;
}
}
@@ -1,24 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.teams.NexiaTeams;
import com.nexia.teams.utilities.chat.ChatFormat;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
public class PvpCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("pvp").requires(commandSourceStack -> commandSourceStack.hasPermission(4)).executes(PvpCommand::execute));
}
private static int execute(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
NexiaTeams.pvpEnabled = !NexiaTeams.pvpEnabled;
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text((NexiaTeams.pvpEnabled ? "Enabled" : "Disabled") + " pvp."))));
ChatFormat.nexiaTitle(context.getSource(), "PVP has been " + (NexiaTeams.pvpEnabled ? "enabled" : "disabled"));
return 0;
}
}
@@ -1,307 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.nexia.teams.commands.suggestions.TeamPlayerSuggestionProvider;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.teams.TeamUtil;
import com.nexia.teams.utilities.time.ServerTime;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.ColorArgument;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.commands.arguments.TeamArgument;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.scores.PlayerTeam;
public class TeamCommand {
static String commandSeparator = ": ";
static String[] commands = {
"t" + commandSeparator + "Display this message",
"t create <name>" + commandSeparator + "Create a team",
"t leave" + commandSeparator + "Leave your current team",
"t invite <player>" + commandSeparator + "Invite a player to a team",
"t kick <player>" + commandSeparator + "Kick a player from your team",
"t accept" + commandSeparator + "Accept an invite to a team",
"t decline" + commandSeparator + "Decline an invite to a team",
"t color <color>" + commandSeparator + "Change the prefix color of your team",
"t list <name>" + commandSeparator + "List of members of a team",
};
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("t")
.executes(TeamCommand::info)
.then(Commands.literal("create")
.then(Commands.argument("name", StringArgumentType.word()).executes(context -> createTeam(context, StringArgumentType.getString(context, "name")))))
.then(Commands.literal("create")
.executes(TeamCommand::leaveTeam))
.then(Commands.literal("invite")
.then(Commands.argument("player", EntityArgument.player()).executes(context -> invitePlayer(context, EntityArgument.getPlayer(context, "player")))))
.then(Commands.literal("kick")
.then(Commands.argument("player", StringArgumentType.word()).suggests(new TeamPlayerSuggestionProvider())
.executes(context -> kickPlayer(context, StringArgumentType.getString(context, "player")))))
.then(Commands.literal("accept")
.executes(TeamCommand::acceptInvite))
.then(Commands.literal("decline")
.executes(TeamCommand::declineInvite))
.then(Commands.literal("leave")
.executes(TeamCommand::leaveTeam))
.then(Commands.literal("color")
.then(Commands.argument("color", ColorArgument.color()).executes(context -> setTeamColor(context, ColorArgument.getColor(context, "color")))))
.then(Commands.literal("list")
.executes(context -> listMembers(context, context.getSource().getPlayer().getTeam()))
.then(Commands.argument("team", TeamArgument.team()).executes(context -> listMembers(context, TeamArgument.getTeam(context, "team")))))
);
}
private static int info(CommandContext<CommandSourceStack> context) {
Component message = Component.text("");
for (String command : commands) {
String[] commandInfo = command.split(commandSeparator);
if (commandInfo.length < 2) continue;
message = message.append(Component.text("\n/" + commandInfo[0])
.color(ChatFormat.brandColor1)
.append(Component.text(" | ").color(ChatFormat.Minecraft.aqua))
.append(Component.text(commandInfo[1]).color(ChatFormat.brandColor2)));
}
context.getSource().sendSystemMessage(ChatFormat.convertComponent(message));
return 0;
}
private static int createTeam(CommandContext<CommandSourceStack> context, String name) {
if (context.getSource().getPlayer().getTeam() != null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You're already in a team!"))));
return 1;
}
if (ServerTime.minecraftServer.getScoreboard().getPlayerTeam(name) != null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That team already exists!"))));
return 1;
}
if (name.length() > 12) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Team name is too long!"))));
return 1;
}
PlayerTeam playerTeam = ServerTime.minecraftServer.getScoreboard().addPlayerTeam(name);
playerTeam.setSeeFriendlyInvisibles(true);
playerTeam.setAllowFriendlyFire(true);
Component teamPrefix = Component.text(playerTeam.getName()).color(NamedTextColor.WHITE)
.append(Component.text(" | ").color(ChatFormat.arrowColor));
playerTeam.setPlayerPrefix(ChatFormat.convertComponent(teamPrefix));
playerTeam.setColor(ChatFormat.getSecondaryColor(ChatFormatting.WHITE));
ServerTime.minecraftServer.getScoreboard().addPlayerToTeam(context.getSource().getPlayer().getScoreboardName(), playerTeam);
context.getSource().getPlayer().addTag("leader_" + playerTeam.getName());
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You have created your own team."))));
return 0;
}
private static int leaveTeam(CommandContext<CommandSourceStack> context) {
PlayerTeam playerTeam = context.getSource().getPlayer().getTeam();
if (playerTeam == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You aren't in a team!"))));
return 1;
}
ServerTime.minecraftServer.getScoreboard().removePlayerFromTeam(context.getSource().getPlayer().getScoreboardName(), playerTeam);
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You have left your team."))));
if (context.getSource().getPlayer().getTags().contains("leader_" + playerTeam.getName())) {
context.getSource().getPlayer().removeTag("leader_" + playerTeam.getName());
ServerTime.minecraftServer.getScoreboard().removePlayerTeam(playerTeam);
}
return 0;
}
private static int invitePlayer(CommandContext<CommandSourceStack> context, ServerPlayer player) {
PlayerTeam playerTeam = context.getSource().getPlayer().getTeam();
if (playerTeam == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You aren't in a team!"))));
return 1;
}
if (player.getTeam() != null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That player is already in a team!"))));
return 1;
}
if (TeamUtil.getInvitedTeam(player) != null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("That player has already been invited to a team!"))));
return 1;
}
if (playerTeam.getPlayers().size() >= 3) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Your team has reached the member limit!"))));
return 1;
}
if (!context.getSource().getPlayer().getTags().contains("leader_" + playerTeam.getName())) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You aren't the team leader!"))));
return 1;
}
Component yes = Component.text("[").color(ChatFormat.Minecraft.dark_gray)
.append(Component.text("ACCEPT")
.color(ChatFormat.Minecraft.green)
.decorate(TextDecoration.BOLD)
.hoverEvent(HoverEvent.showText(Component.text("Click me").color(ChatFormat.brandColor2)))
.clickEvent(ClickEvent.runCommand("/t accept")))
.append(Component.text("] ").color(ChatFormat.Minecraft.dark_gray)
);
Component no = Component.text("[").color(ChatFormat.Minecraft.dark_gray)
.append(Component.text("DECLINE")
.color(ChatFormat.Minecraft.red)
.decoration(TextDecoration.BOLD, true)
.hoverEvent(HoverEvent.showText(Component.text("Click me")
.color(ChatFormat.brandColor2)))
.clickEvent(ClickEvent.runCommand("/t decline")))
.append(Component.text("]").color(ChatFormat.Minecraft.dark_gray)
);
TeamUtil.addInvite(player, context.getSource().getPlayer().getTeam().getName());
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Invite sent has been sent to %s!".formatted(player.getScoreboardName())))));
player.sendSystemMessage(ChatFormat.convertComponent(Component.text("You have been invited to ", ChatFormat.Minecraft.gray).append(Component.text(context.getSource().getPlayer().getTeam().getName(), TextColor.color(context.getSource().getPlayer().getTeam().getColor().getColor())))));
player.sendSystemMessage(ChatFormat.convertComponent(yes.append(no)));
return 0;
}
private static int kickPlayer(CommandContext<CommandSourceStack> context, String player) {
PlayerTeam playerTeam = context.getSource().getPlayer().getTeam();
if (playerTeam == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You aren't in a team!"))));
return 1;
}
if (!playerTeam.getPlayers().contains(player)) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Can't kick a player from another team!"))));
return 1;
}
if (!context.getSource().getPlayer().getTags().contains("leader_" + playerTeam.getName())) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You aren't the team leader!"))));
return 1;
}
if (context.getSource().getPlayer().getScoreboardName().equals(player)) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You can't kick yourself!"))));
return 1;
}
ServerTime.minecraftServer.getScoreboard().removePlayerFromTeam(player, playerTeam);
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Player %s has been kicked.".formatted(player)))));
return 0;
}
private static int acceptInvite(CommandContext<CommandSourceStack> context) {
ServerPlayer player = context.getSource().getPlayer();
assert player != null;
String teamName = TeamUtil.getInvitedTeam(player);
if (player.getTeam() != null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You're already in a team!"))));
return 1;
}
if (teamName == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You're not invited to a team!"))));
return 1;
}
player.getScoreboard().addPlayerToTeam(player.getScoreboardName(), player.getScoreboard().getPlayerTeam(teamName));
for (String teamPlayer : ServerTime.minecraftServer.getScoreboard().getPlayerTeam(teamName).getPlayers()) {
ServerPlayer serverPlayer = ServerTime.minecraftServer.getPlayerList().getPlayerByName(teamPlayer);
if (serverPlayer != null) {
serverPlayer.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("%s has joined your team.".formatted(context.getSource().getPlayer().getScoreboardName())))));
}
}
player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You have accepted the invite."))));
TeamUtil.removeInvite(player);
return 0;
}
private static int declineInvite(CommandContext<CommandSourceStack> context) {
ServerPlayer player = context.getSource().getPlayer();
assert player != null;
String teamName = TeamUtil.getInvitedTeam(player);
if (teamName == null) {
player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You're not invited to a team!"))));
return 1;
}
for (String teamPlayer : ServerTime.minecraftServer.getScoreboard().getPlayerTeam(teamName).getPlayers()) {
ServerPlayer serverPlayer = ServerTime.minecraftServer.getPlayerList().getPlayerByName(teamPlayer);
if (serverPlayer != null) {
serverPlayer.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("%s hasn't joined your team.".formatted(context.getSource().getPlayer().getScoreboardName())))));
}
}
player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You have declined the invite."))));
TeamUtil.removeInvite(player);
return 0;
}
private static int setTeamColor(CommandContext<CommandSourceStack> context, ChatFormatting color) {
PlayerTeam team = context.getSource().getPlayer().getTeam();
if (team == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You aren't in a team!"))));
return 1;
}
Component teamPrefix = Component.text(team.getName()).color(TextColor.color(color.getColor()))
.append(Component.text(" | ").color(ChatFormat.arrowColor));
team.setPlayerPrefix(ChatFormat.convertComponent(teamPrefix));
team.setColor(ChatFormat.getSecondaryColor(color));
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Changed team prefix color!"))));
return 0;
}
private static int listMembers(CommandContext<CommandSourceStack> context, PlayerTeam playerTeam) {
if (playerTeam == null) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("You aren't in a team!"))));
return 1;
}
Component message = Component.text("List of members in %s:".formatted(playerTeam.getName()));
for (String teamPlayer : playerTeam.getPlayers()) {
message = message.append(Component.text("\n" + teamPlayer));
}
context.getSource().sendSystemMessage(ChatFormat.convertComponent(message));
return 0;
}
}
@@ -1,57 +0,0 @@
package com.nexia.teams.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.teams.NexiaTeams;
import com.nexia.teams.events.tournament.TournamentFight;
import com.nexia.teams.gui.SelectorGUI;
import com.nexia.teams.utilities.chat.ChatFormat;
import net.kyori.adventure.text.Component;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.arguments.TeamArgument;
import net.minecraft.world.scores.PlayerTeam;
import java.util.Collection;
public class TournamentCommand {
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext, Commands.CommandSelection commandSelection) {
dispatcher.register(Commands.literal("tournament").requires(commandSourceStack -> commandSourceStack.hasPermission(4))
.then(Commands.literal("create")
.then(Commands.argument("redTeam", TeamArgument.team())
.then(Commands.argument("blueTeam", TeamArgument.team())
.executes(context -> execute(context, TeamArgument.getTeam(context, "redTeam"), TeamArgument.getTeam(context, "blueTeam"))))))
.then(Commands.literal("stop")
.executes(TournamentCommand::stop))
);
}
private static int stop(CommandContext<CommandSourceStack> context) {
if (!TournamentFight.isRunning) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("There is no ongoing tournament fight!"))));
return 1;
}
TournamentFight.end();
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Stopping tournament fight..."))));
return 0;
}
private static int execute(CommandContext<CommandSourceStack> context, PlayerTeam redTeam, PlayerTeam blueTeam) {
if (TournamentFight.isRunning) {
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("There's already a tournament fight going on!"))));
return 1;
}
TournamentFight.redTeam = redTeam;
TournamentFight.blueTeam = blueTeam;
Collection<String> players = redTeam.getPlayers();
players.addAll(blueTeam.getPlayers());
SelectorGUI.openSelectorGUI(context.getSource().getPlayer(), players);
context.getSource().sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Starting tournament fight..."))));
return 0;
}
}
@@ -1,27 +0,0 @@
package com.nexia.teams.commands.suggestions;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import com.nexia.teams.events.koth.KothGame;
import com.nexia.teams.events.koth.KothGameHandler;
import net.minecraft.commands.CommandSourceStack;
import java.util.concurrent.CompletableFuture;
public class KothSuggestionProvider implements SuggestionProvider<CommandSourceStack> {
@Override
public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) throws CommandSyntaxException {
if (KothGameHandler.kothGames.isEmpty()) {
return null;
}
for (KothGame kothGame : KothGameHandler.kothGames) {
builder.suggest(kothGame.name);
}
return builder.buildFuture();
}
}
@@ -1,30 +0,0 @@
package com.nexia.teams.commands.suggestions;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.commands.CommandSourceStack;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
public class TeamPlayerSuggestionProvider implements SuggestionProvider<CommandSourceStack> {
@Override
public CompletableFuture<Suggestions> getSuggestions(CommandContext<CommandSourceStack> context, SuggestionsBuilder builder) throws CommandSyntaxException {
CommandSourceStack source = context.getSource();
if (source.getPlayer().getTeam() == null) {
return null;
}
Collection<String> playerNames = source.getPlayer().getTeam().getPlayers();
for (String playerName : playerNames) {
builder.suggest(playerName);
}
return builder.buildFuture();
}
}
@@ -1,140 +0,0 @@
package com.nexia.teams.events.koth;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.time.ServerTime;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.minecraft.core.BlockPos;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.item.component.SeededContainerLoot;
import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.NotNull;
import java.util.*;
public class KothGame {
public final String creator;
public final String name; // name for the koth
public Long scheduledTimestamp;
public AABB area;
public BlockPos initialCoordinates;
public int time = 300; // measured in seconds
public boolean isRunning = false;
public ServerLevel level;
private ServerPlayer winner;
private final HashMap<ServerPlayer, Integer> playerScores = new HashMap<>();
public KothGame(@NotNull String creator, String name, Long scheduledTimestamp, AABB area, BlockPos initialCoordinates, ServerLevel level) {
this.creator = creator;
this.name = name;
this.scheduledTimestamp = scheduledTimestamp;
this.area = area;
this.initialCoordinates = initialCoordinates;
this.level = level;
}
public void start() {
if(this.isRunning) return;
for (ServerPlayer serverPlayer : ServerTime.minecraftServer.getPlayerList().getPlayers()) {
serverPlayer.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text(String.format("KOTH has started at (%s, %s, %s)!", this.area.getCenter().x, this.area.getCenter().y, this.area.getCenter().z)))));
}
this.isRunning = true;
}
public void end(ServerPlayer winner) {
this.setWinner(winner);
if (winner != null) {
ItemStack reward = Items.CHEST.getDefaultInstance();
reward.set(DataComponents.CONTAINER_LOOT, new SeededContainerLoot(ResourceKey.create(Registries.LOOT_TABLE, new ResourceLocation("nexia:chests/koth")), level.getSeed()));
reward.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(MiniMessage.miniMessage().deserialize(String.format("<bold><gradient:%s:%s>KOTH Reward</gradient></bold> <color:%s>(for %s)</color>", ChatFormat.brandColor1, ChatFormat.brandColor2, ChatFormat.Minecraft.gray, winner.getScoreboardName()))));
List<net.minecraft.network.chat.Component> list2 = new java.util.ArrayList<>();
list2.add(ChatFormat.convertComponent(MiniMessage.miniMessage().deserialize(String.format("<color:%s>Personalized just for </color><bold><gradient:%s:%s>%s</gradient></bold><color:%s>!</color>", ChatFormat.Minecraft.gray, ChatFormat.brandColor1, ChatFormat.brandColor2, winner.getScoreboardName(), ChatFormat.Minecraft.gray)).decoration(TextDecoration.ITALIC, false)));
list2.add(ChatFormat.convertComponent(Component.text("Yours to keep ʕっ·ᴥ·ʔっ", ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
reward.set(DataComponents.LORE, new ItemLore(list2));
winner.addItem(reward);
for (ServerPlayer serverPlayer : ServerTime.minecraftServer.getPlayerList().getPlayers()) {
serverPlayer.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text(String.format("KOTH winner is %s!", this.getWinner().getScoreboardName())))));
}
}
this.isRunning = false;
playerScores.clear();
this.setWinner(null);
this.initialCoordinates = null;
}
public void kothSecond() {
if(!this.isRunning) return;
for (Player player : level.getEntities(EntityType.PLAYER, area, o -> o instanceof ServerPlayer player && !player.isDeadOrDying() && player.gameMode.isSurvival())) {
ServerPlayer serverPlayer = (ServerPlayer) player;
if (playerScores.containsKey(serverPlayer)) {
playerScores.put(serverPlayer, playerScores.get(serverPlayer) + 1);
if (playerScores.get(serverPlayer) == time) {
this.end(serverPlayer);
}
} else {
playerScores.put(serverPlayer, 1);
}
serverPlayer.sendSystemMessage(ChatFormat.convertComponent(
Component.text("Your score » ", ChatFormat.Minecraft.gray)
.append(Component.text(playerScores.get(serverPlayer), ChatFormat.Minecraft.red))
.append(Component.text(" | ", ChatFormat.Minecraft.dark_gray))
.append(Component.text(getWinningPlayer().getScoreboardName() + " (winning)'s score » ", ChatFormat.Minecraft.gray))
.append(Component.text(Collections.max(playerScores.values()), ChatFormat.Minecraft.red))
), true);
}
}
public ServerPlayer getWinningPlayer() {
if (this.isRunning) {
for (Map.Entry<ServerPlayer, Integer> playerEntry : playerScores.entrySet()) {
if (Objects.equals(playerEntry.getValue(), Collections.max(playerScores.values()))) {
return playerEntry.getKey();
}
}
}
return null;
}
public ServerPlayer getWinner() {
return this.winner;
}
public void setWinner(ServerPlayer winner) {
this.winner = winner;
}
public ServerPlayer getCreator() {
return ServerTime.minecraftServer.getPlayerList().getPlayerByName(this.creator);
}
}
@@ -1,37 +0,0 @@
package com.nexia.teams.events.koth;
import java.util.ArrayList;
import java.util.List;
public abstract class KothGameHandler {
public static List<KothGame> kothGames = new ArrayList<>();
public static KothGame getKothGameByName(String name) {
try {
for (KothGame kothGame : kothGames) {
if(kothGame == null || !kothGame.name.equalsIgnoreCase(name)) continue;
return kothGame;
}
} catch (Exception ignored) { }
return null;
}
public static void stopAllKothGames() {
try {
for (KothGame kothGame : kothGames) {
if(kothGame == null || !kothGame.isRunning) continue;
kothGame.end(null);
}
} catch (Exception ignored) { }
}
public static void kothGamesSecond() {
try {
for (KothGame kothGame : kothGames) {
if(kothGame == null || !kothGame.isRunning) continue;
kothGame.kothSecond();
}
} catch (Exception ignored) { }
}
}
@@ -1,69 +0,0 @@
package com.nexia.teams.events.meteor;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.time.ServerTime;
import net.kyori.adventure.text.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.projectile.LargeFireball;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
public abstract class Meteor {
public static Long scheduledTimestamp = null;
public static ServerPlayer serverPlayer = null;
public static int[] meteorCoordinates = new int[]{0, 324, 0};
public static void second() {
if (scheduledTimestamp == null) return;
long unixTime = System.currentTimeMillis() / 1000L;
if (unixTime == scheduledTimestamp) {
scheduledTimestamp = null;
spawn(serverPlayer);
}
}
public static int getRandomNumber(int min, int max) {
return (int) ((Math.random() * (max - min)) + min);
}
public static void generateRandomCoordinates() {
int randomX = getRandomNumber(300, 1000);
int randomZ = getRandomNumber(300, 1000);
if (getRandomNumber(1, 3) % 2 == 0) randomX = randomX * -1;
if (getRandomNumber(1, 3) % 2 == 0) randomZ = randomZ * -1;
meteorCoordinates[0] = randomX;
meteorCoordinates[2] = randomZ;
}
public static void spawn(ServerPlayer serverPlayer) {
for (ServerPlayer player : ServerTime.minecraftServer.getPlayerList().getPlayers()) {
player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text(String.format("Meteor is landing at (%s, %s)", meteorCoordinates[0], meteorCoordinates[2])))));
}
Level world = serverPlayer.getCommandSenderWorld();
LargeFireball largeFireball = new LargeFireball(EntityType.FIREBALL, world);
largeFireball.explosionPower = 12;
largeFireball.addTag("meteor");
largeFireball.setPos(meteorCoordinates[0], meteorCoordinates[1], meteorCoordinates[2]);
largeFireball.setDeltaMovement(calculateViewVector(90, 0).normalize());
largeFireball.yPower = largeFireball.getDeltaMovement().y * 0.1;
world.addFreshEntity(largeFireball);
}
public static Vec3 calculateViewVector(float f, float g) {
float h = f * ((float)Math.PI / 180);
float i = -g * ((float)Math.PI / 180);
float j = Mth.cos(i);
float k = Mth.sin(i);
float l = Mth.cos(h);
float m = Mth.sin(h);
return new Vec3(k * l, -m, j * l);
}
}
@@ -1,23 +0,0 @@
package com.nexia.teams.events.tournament;
public class TournamentConfig {
public double[] redSpawn;
public double[] blueSpawn;
public double[] spawnArea;
public double[] redGate1;
public double[] redGate2;
public double[] blueGate1;
public double[] blueGate2;
public double[] spectatorSpawn;
public TournamentConfig(double[] redSpawn, double[] blueSpawn, double[] spawnArea, double[] redGate1, double[] redGate2, double[] blueGate1, double[] blueGate2, double[] spectatorSpawn) {
this.redSpawn = redSpawn;
this.blueSpawn = blueSpawn;
this.spawnArea = spawnArea;
this.redGate1 = redGate1;
this.redGate2 = redGate2;
this.blueGate1 = blueGate1;
this.blueGate2 = blueGate2;
this.spectatorSpawn = spectatorSpawn;
}
}
@@ -1,177 +0,0 @@
package com.nexia.teams.events.tournament;
import com.google.common.base.Function;
import com.google.gson.Gson;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.time.ServerTime;
import net.fabricmc.loader.api.FabricLoader;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.scores.PlayerTeam;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public abstract class TournamentFight {
public static boolean isRunning = false;
public static boolean isStarting = false;
public static int startTime = 3;
public static int currentStartTime = 3;
public static PlayerTeam redTeam = null;
public static PlayerTeam blueTeam = null;
public static List<ServerPlayer> serverPlayers = new ArrayList<>();
public static double[] redSpawn;
public static double[] blueSpawn;
public static double[] spectatorSpawn;
public static AABB spawnArea;
public static AABB redGate1;
public static AABB redGate2;
public static AABB blueGate1;
public static AABB blueGate2;
public static void loadTournamentConfig() {
try {
String directory = FabricLoader.getInstance().getConfigDir().toString() + "/nexia/tournament";
String json = Files.readString(Path.of(directory + "/config.json"));
Gson gson = new Gson();
TournamentConfig tournamentConfig = gson.fromJson(json, TournamentConfig.class);
redSpawn = tournamentConfig.redSpawn;
blueSpawn = tournamentConfig.blueSpawn;
spectatorSpawn = tournamentConfig.spectatorSpawn;
spawnArea = new AABB(tournamentConfig.spawnArea[0], tournamentConfig.spawnArea[1], tournamentConfig.spawnArea[2], tournamentConfig.spawnArea[3], tournamentConfig.spawnArea[4], tournamentConfig.spawnArea[5]);
redGate1 = new AABB(tournamentConfig.redGate1[0], tournamentConfig.redGate1[1], tournamentConfig.redGate1[2], tournamentConfig.redGate1[3], tournamentConfig.redGate1[4], tournamentConfig.redGate1[5]);
redGate2 = new AABB(tournamentConfig.redGate2[0], tournamentConfig.redGate2[1], tournamentConfig.redGate2[2], tournamentConfig.redGate2[3], tournamentConfig.redGate2[4], tournamentConfig.redGate2[5]);
blueGate1 = new AABB(tournamentConfig.blueGate1[0], tournamentConfig.blueGate1[1], tournamentConfig.blueGate1[2], tournamentConfig.blueGate1[3], tournamentConfig.blueGate1[4], tournamentConfig.blueGate1[5]);
blueGate2 = new AABB(tournamentConfig.blueGate2[0], tournamentConfig.blueGate2[1], tournamentConfig.blueGate2[2], tournamentConfig.blueGate2[3], tournamentConfig.blueGate2[4], tournamentConfig.blueGate2[5]);
} catch (Exception exception) {
exception.printStackTrace();
}
}
public static void clearStuff(AABB area) {
List<EntityType<? extends Entity>> entityTypes = List.of(EntityType.ITEM, EntityType.ARROW, EntityType.SPECTRAL_ARROW, EntityType.TRIDENT, EntityType.EXPERIENCE_ORB);
entityTypes.forEach(entityType -> ServerTime.minecraftServer.overworld().getEntities(entityType, area, o -> true).forEach(Entity::kill));
}
public static void fillBlocks(AABB area, Block block) {
Iterable<BlockPos> blocks = BlockPos.betweenClosed((int) area.minX, (int) area.minY, (int) area.minZ, (int) area.maxX, (int) area.maxY, (int) area.maxZ);
for (BlockPos blockPos : blocks) {
ServerTime.minecraftServer.overworld().setBlockAndUpdate(blockPos, block.defaultBlockState());
}
}
public static void preStart() {
loadTournamentConfig();
clearStuff(spawnArea);
fillBlocks(redGate1, Blocks.RED_STAINED_GLASS);
fillBlocks(redGate2, Blocks.RED_STAINED_GLASS);
fillBlocks(blueGate1, Blocks.CYAN_STAINED_GLASS);
fillBlocks(blueGate2, Blocks.CYAN_STAINED_GLASS);
for (ServerPlayer serverPlayer : serverPlayers) {
if (serverPlayer.getTeam() == redTeam) {
serverPlayer.teleportTo(ServerTime.minecraftServer.overworld(), redSpawn[0], redSpawn[1], redSpawn[2], 90, 0);
}
if (serverPlayer.getTeam() == blueTeam) {
serverPlayer.teleportTo(ServerTime.minecraftServer.overworld(), blueSpawn[0], blueSpawn[1], blueSpawn[2], -90, 0);
}
serverPlayer.setGameMode(GameType.ADVENTURE);
ServerTime.minecraftServer.getCommands().performPrefixedCommand(ServerTime.minecraftServer.createCommandSourceStack().withPermission(4), "protect exclusion add spawn player " + serverPlayer.getScoreboardName());
}
}
public static void teamTitle(String message, SoundEvent soundEvent) {
for (ServerPlayer serverPlayer : serverPlayers) {
try {
net.minecraft.network.chat.Component component = ChatFormat.convertComponent(Component.text(message, getTitleColor(currentStartTime)));
Function<net.minecraft.network.chat.Component, ClientboundSetTitleTextPacket> title = ClientboundSetTitleTextPacket::new;
serverPlayer.connection.send(title.apply(ComponentUtils.updateForEntity(ServerTime.minecraftServer.createCommandSourceStack(), component, serverPlayer, 0)));
serverPlayer.level().playSound(
null,
BlockPos.containing(serverPlayer.getPosition(0)),
soundEvent,
SoundSource.MASTER,
1f,
1f
);
} catch (Exception ignored) {}
}
}
public static TextColor getTitleColor(int currentStartTime) {
if(currentStartTime == 2) {
return ChatFormat.Minecraft.yellow;
} else if(currentStartTime <= 1) {
return ChatFormat.Minecraft.red;
}
return ChatFormat.Minecraft.green;
}
public static void start() {
isStarting = false;
isRunning = true;
teamTitle("Go!", SoundEvents.GOAT_HORN_SOUND_VARIANTS.get(2).value());
fillBlocks(redGate1, Blocks.AIR);
fillBlocks(blueGate1, Blocks.AIR);
}
public static void second() {
if (isStarting) {
if (currentStartTime <= 0) {
start();
return;
}
if (currentStartTime == startTime) preStart();
teamTitle(String.valueOf(currentStartTime), SoundEvents.NOTE_BLOCK_BIT.value());
currentStartTime--;
}
if (isRunning || isStarting) {
for (Player player : ServerTime.minecraftServer.overworld().getEntities(EntityType.PLAYER, spawnArea, o -> true)) {
if (player instanceof ServerPlayer serverPlayer) {
if (!serverPlayers.contains(serverPlayer))
serverPlayer.teleportTo(spectatorSpawn[0], spectatorSpawn[1], spectatorSpawn[2]);
}
}
}
}
public static void end() {
teamTitle("Game over!", SoundEvents.TRIDENT_THUNDER);
serverPlayers.forEach(serverPlayer -> {
serverPlayer.setGameMode(GameType.SURVIVAL);
ServerTime.minecraftServer.getCommands().performPrefixedCommand(ServerTime.minecraftServer.createCommandSourceStack().withPermission(4), "protect exclusion remove spawn player " + serverPlayer.getScoreboardName());
});
isRunning = false;
isStarting = false;
redTeam = null;
blueTeam = null;
serverPlayers.clear();
currentStartTime = startTime;
fillBlocks(redGate2, Blocks.AIR);
fillBlocks(blueGate2, Blocks.AIR);
}
}
@@ -1,136 +0,0 @@
package com.nexia.teams.gui;
import com.nexia.teams.utilities.chat.ChatFormat;
import eu.pb4.sgui.api.gui.SimpleGui;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import net.minecraft.core.component.DataComponents;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.ItemLore;
import java.util.List;
public class CalendarGUI extends SimpleGui {
static final Component title = Component.text("Calendar").decoration(TextDecoration.BOLD, true);
public CalendarGUI(MenuType<?> type, ServerPlayer player, boolean manipulatePlayerSlots) {
super(type, player, manipulatePlayerSlots);
}
private void fillEmptySlots(ItemStack itemStack){
for(int i = 0; i < 45; i++){
this.setSlot(i, itemStack);
}
}
private void setMainLayout() {
ItemStack emptySlot = new ItemStack(Items.BLACK_STAINED_GLASS_PANE, 1);
emptySlot.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(Component.text("")));
fillEmptySlots(emptySlot);
int airSlots = 10;
for(int air = 0; air < 21; air++){
if(airSlots == 17) {
airSlots = 19;
}
if(airSlots == 26) {
airSlots = 28;
}
this.setSlot(airSlots, new ItemStack(Items.AIR));
airSlots++;
}
ItemStack day1 = Items.GRASS_BLOCK.getDefaultInstance();
day1.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(
Component.text("Day 1: Start Of The World")
.decoration(TextDecoration.BOLD, true).decoration(TextDecoration.ITALIC, false)
.color(ChatFormat.Minecraft.green))
);
day1.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, false);
List<net.minecraft.network.chat.Component> list1 = new java.util.ArrayList<>();
list1.add(ChatFormat.convertComponent(Component.text("15 minute grace period.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list1.add(ChatFormat.convertComponent(Component.text("Border starts at 1k and expands to 4k.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
day1.set(DataComponents.LORE, new ItemLore(list1));
this.setSlot(10, day1);
ItemStack day2 = Items.NETHERRACK.getDefaultInstance();
day2.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(
Component.text("Day 2: Nether Opening")
.decoration(TextDecoration.BOLD, true).decoration(TextDecoration.ITALIC, false)
.color(ChatFormat.Minecraft.red))
);
day2.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, false);
List<net.minecraft.network.chat.Component> list2 = new java.util.ArrayList<>();
list2.add(ChatFormat.convertComponent(Component.text("The Nether opens, after 30 minutes").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list2.add(ChatFormat.convertComponent(Component.text("the Nether KOTH begins").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list2.add(ChatFormat.convertComponent(Component.text("at 0, 0 on the Nether roof.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list2.add(ChatFormat.convertComponent(Component.text("Winner gets 3 Netherite.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
day2.set(DataComponents.LORE, new ItemLore(list2));
this.setSlot(13, day2);
ItemStack day3 = Items.FIRE_CHARGE.getDefaultInstance();
day3.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(
Component.text("Day 3: Meteorite Shower")
.decoration(TextDecoration.BOLD, true).decoration(TextDecoration.ITALIC, false)
.color(ChatFormat.Minecraft.dark_gray))
);
day3.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, false);
List<net.minecraft.network.chat.Component> list3 = new java.util.ArrayList<>();
list3.add(ChatFormat.convertComponent(Component.text("Meteors will land around the map").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list3.add(ChatFormat.convertComponent(Component.text("containing useful items, coords").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list3.add(ChatFormat.convertComponent(Component.text("will be displayed before landing.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
day3.set(DataComponents.LORE, new ItemLore(list3));
this.setSlot(16, day3);
ItemStack day4 = Items.END_CRYSTAL.getDefaultInstance();
day4.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(
Component.text("Day 4: End Fight")
.decoration(TextDecoration.BOLD, true).decoration(TextDecoration.ITALIC, false)
.color(ChatFormat.Minecraft.dark_purple))
);
day4.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, true);
List<net.minecraft.network.chat.Component> list4 = new java.util.ArrayList<>();
list4.add(ChatFormat.convertComponent(Component.text("The End will open.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list4.add(ChatFormat.convertComponent(Component.text("The Dragon will drop an elytra.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
day4.set(DataComponents.LORE, new ItemLore(list4));
this.setSlot(28, day4);
ItemStack day5 = Items.GOLDEN_SWORD.getDefaultInstance();
day5.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(
Component.text("Day 5: Tournament")
.decoration(TextDecoration.BOLD, true).decoration(TextDecoration.ITALIC, false)
.color(ChatFormat.Minecraft.yellow))
);
day5.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, false);
List<net.minecraft.network.chat.Component> list5 = new java.util.ArrayList<>();
list5.add(ChatFormat.convertComponent(Component.text("There will be a tournament at spawn.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list5.add(ChatFormat.convertComponent(Component.text("All matches will be equal in players.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list5.add(ChatFormat.convertComponent(Component.text("Reward of 3 totems.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
day5.set(DataComponents.LORE, new ItemLore(list5));
this.setSlot(31, day5);
ItemStack day6 = Items.BARRIER.getDefaultInstance();
day6.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(
Component.text("Day 6: End Of The World")
.decoration(TextDecoration.BOLD, true).decoration(TextDecoration.ITALIC, false)
.color(ChatFormat.Minecraft.white))
);
day6.set(DataComponents.ENCHANTMENT_GLINT_OVERRIDE, false);
List<net.minecraft.network.chat.Component> list6 = new java.util.ArrayList<>();
list6.add(ChatFormat.convertComponent(Component.text("Players no longer respawn and the border shrinks.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list6.add(ChatFormat.convertComponent(Component.text("After 15 minutes all players are teleported to spawn.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
list6.add(ChatFormat.convertComponent(Component.text("The last team standing wins.").color(ChatFormat.Minecraft.gray).decoration(TextDecoration.ITALIC, false)));
day6.set(DataComponents.LORE, new ItemLore(list6));
this.setSlot(34, day6);
}
public static void openCalendarGUI(ServerPlayer player) {
CalendarGUI calendarGUI = new CalendarGUI(MenuType.GENERIC_9x5, player, false);
calendarGUI.setTitle(ChatFormat.convertComponent(title));
calendarGUI.setMainLayout();
calendarGUI.open();
}
}
@@ -1,43 +0,0 @@
package com.nexia.teams.gui;
import com.nexia.teams.utilities.chat.ChatFormat;
import eu.pb4.sgui.api.ClickType;
import eu.pb4.sgui.api.elements.GuiElementInterface;
import eu.pb4.sgui.api.gui.SimpleGui;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.ChestBlockEntity;
public class KitGUI extends SimpleGui {
Component title = Component.text("Kit GUI").decorate(TextDecoration.BOLD);
public KitGUI(MenuType<?> type, ServerPlayer player, boolean manipulatePlayerSlots) {
super(type, player, manipulatePlayerSlots);
}
public void setMainLayout() {
BlockEntity blockEntity = this.player.serverLevel().getBlockEntity(BlockPos.containing(0, 62, 0));
if (blockEntity instanceof ChestBlockEntity chestBlockEntity) {
for (int i = 0; i < chestBlockEntity.getContainerSize(); i++) {
this.setSlot(i, chestBlockEntity.getItem(i));
}
}
}
public static void openKitGUI(ServerPlayer player) {
KitGUI kitGUI = new KitGUI(MenuType.GENERIC_9x3, player, false);
kitGUI.setTitle(ChatFormat.convertComponent(kitGUI.title));
kitGUI.setMainLayout();
kitGUI.open();
}
@Override
public boolean onClick(int index, ClickType type, net.minecraft.world.inventory.ClickType action, GuiElementInterface element) {
if (element != null) this.player.addItem(element.getItemStack().copy());
return false;
}
}
@@ -1,104 +0,0 @@
package com.nexia.teams.gui;
import com.nexia.teams.events.tournament.TournamentFight;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.time.ServerTime;
import eu.pb4.sgui.api.ClickType;
import eu.pb4.sgui.api.elements.GuiElementInterface;
import eu.pb4.sgui.api.gui.SimpleGui;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.minecraft.core.BlockPos;
import net.minecraft.core.component.DataComponents;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.ResolvableProfile;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
public class SelectorGUI extends SimpleGui {
static final Component title = Component.text("Select players").decoration(TextDecoration.BOLD, true);
Collection<String> serverPlayers;
List<ServerPlayer> selectedPlayers = new ArrayList<>();
public SelectorGUI(MenuType<?> type, ServerPlayer player, boolean manipulatePlayerSlots, Collection<String> serverPlayers) {
super(type, player, manipulatePlayerSlots);
this.serverPlayers = serverPlayers;
}
private void setMainLayout() {
int i = 0;
for (String player : serverPlayers) {
ServerPlayer serverPlayer = ServerTime.minecraftServer.getPlayerList().getPlayerByName(player);
if (serverPlayer == null) continue;
ItemStack playerHead = Items.PLAYER_HEAD.getDefaultInstance();
playerHead.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(Component.text(serverPlayer.getScoreboardName()).color(NamedTextColor.namedColor(serverPlayer.getTeamColor())).decoration(TextDecoration.ITALIC, false)));
playerHead.set(DataComponents.PROFILE, new ResolvableProfile(serverPlayer.getGameProfile()));
this.setSlot(i, playerHead);
i++;
}
ItemStack confirmButton = Items.GREEN_STAINED_GLASS_PANE.getDefaultInstance();
confirmButton.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(Component.text("Confirm").color(NamedTextColor.GREEN).decorate(TextDecoration.BOLD).decoration(TextDecoration.ITALIC, false)));
this.setSlot(8, confirmButton);
}
public boolean click(int index, ClickType clickType, net.minecraft.world.inventory.ClickType action){
GuiElementInterface element = this.getSlot(index);
if(element != null && clickType != ClickType.MOUSE_DOUBLE_CLICK) {
this.player.level().playSound(
null,
BlockPos.containing(this.player.getPosition(0)),
SoundEvents.COMPARATOR_CLICK,
SoundSource.MASTER,
1f,
1f
);
ItemStack itemStack = element.getItemStack();
if (itemStack.getItem() == Items.PLAYER_HEAD) {
Component itemComponent = ChatFormat.convertComponent(itemStack.get(DataComponents.CUSTOM_NAME));
assert itemComponent != null;
if (!itemComponent.hasDecoration(TextDecoration.BOLD)) {
ResolvableProfile resolvableProfile = itemStack.get(DataComponents.PROFILE);
assert resolvableProfile != null;
selectedPlayers.add(ServerTime.minecraftServer.getPlayerList().getPlayer(resolvableProfile.gameProfile().getId()));
itemStack.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(itemComponent.decoration(TextDecoration.BOLD, true)));
this.setSlot(index, itemStack);
} else {
ResolvableProfile resolvableProfile = itemStack.get(DataComponents.PROFILE);
assert resolvableProfile != null;
selectedPlayers.remove(ServerTime.minecraftServer.getPlayerList().getPlayer(resolvableProfile.gameProfile().getId()));
itemStack.set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(itemComponent.decoration(TextDecoration.BOLD, false)));
this.setSlot(index, itemStack);
}
}
if (itemStack.getItem() == Items.GREEN_STAINED_GLASS_PANE) {
TournamentFight.serverPlayers = selectedPlayers;
TournamentFight.isStarting = true;
this.close();
}
}
return super.click(index, clickType, action);
}
public static void openSelectorGUI(ServerPlayer player, Collection<String> players) {
SelectorGUI selectorGUI = new SelectorGUI(MenuType.GENERIC_9x1, player, false, players);
selectorGUI.setTitle(ChatFormat.convertComponent(title));
selectorGUI.setMainLayout();
selectorGUI.open();
}
}
@@ -1,53 +0,0 @@
package com.nexia.teams.mixin;
import com.nexia.teams.events.koth.KothGame;
import com.nexia.teams.events.koth.KothGameHandler;
import com.nexia.teams.utilities.chat.ChatFormat;
import net.kyori.adventure.text.Component;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.AxeItem;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.phys.AABB;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(AxeItem.class)
public class AxeItemMixin {
@Inject(method = "useOn", at = @At("HEAD"))
public void kothAxe(UseOnContext useOnContext, CallbackInfoReturnable<InteractionResult> cir) {
Player player = useOnContext.getPlayer();
String kothName = null;
assert player != null;
for (String tag : player.getTags()) {
if (tag.startsWith("koth_")) {
kothName = tag.substring(5);
}
}
if (kothName != null) {
KothGame kothGame = KothGameHandler.getKothGameByName(kothName);
assert kothGame != null;
if (kothGame.initialCoordinates == null) {
kothGame.initialCoordinates = useOnContext.getClickedPos();
Component blockPosMessage = Component.text(String.format("Block position set (%s, %s, %s)", useOnContext.getClickedPos().getX(), useOnContext.getClickedPos().getY(), useOnContext.getClickedPos().getZ()));
player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(blockPosMessage)));
} else {
kothGame.area = new AABB(kothGame.initialCoordinates.getX(), kothGame.initialCoordinates.getY(), kothGame.initialCoordinates.getZ(), useOnContext.getClickedPos().getX(), useOnContext.getClickedPos().getY(), useOnContext.getClickedPos().getZ());
Component blockPosMessage = Component.text(String.format("Block position set (%s, %s, %s)", useOnContext.getClickedPos().getX(), useOnContext.getClickedPos().getY(), useOnContext.getClickedPos().getZ()));
player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(blockPosMessage)));
player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Finished editing koth."))));
kothGame.initialCoordinates = null;
player.getInventory().removeItem(useOnContext.getItemInHand());
player.removeTag("koth_" + kothName);
}
}
}
}
@@ -1,20 +0,0 @@
package com.nexia.teams.mixin;
import com.nexia.teams.NexiaTeams;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.EndPortalBlock;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(EndPortalBlock.class)
public abstract class EndPortalBlockMixin {
@Inject(method = "entityInside", at = @At("HEAD"), cancellable = true)
private void disableEnd(BlockState blockState, Level level, BlockPos blockPos, Entity entity, CallbackInfo ci) {
if (NexiaTeams.endDisabled) ci.cancel();
}
}
@@ -1,15 +0,0 @@
package com.nexia.teams.mixin;
import net.minecraft.world.item.EnderpearlItem;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(EnderpearlItem.class)
public class EnderPearlMixin {
@ModifyArg(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemCooldowns;addCooldown(Lnet/minecraft/world/item/Item;I)V"), method = "use", index = 1)
public int addEnderPearlCooldown(int i) {
// returns 30 seconds in minecraft ticks
return 300;
}
}
@@ -1,62 +0,0 @@
package com.nexia.teams.mixin;
import com.nexia.teams.utilities.chat.ChatFormat;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.minecraft.core.BlockPos;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.RandomizableContainer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.projectile.Fireball;
import net.minecraft.world.entity.projectile.LargeFireball;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.phys.HitResult;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Comparator;
import java.util.List;
@Mixin(LargeFireball.class)
public abstract class LargeFireballMixin extends Fireball {
@Shadow public int explosionPower;
public LargeFireballMixin(EntityType<? extends Fireball> entityType, Level level) {
super(entityType, level);
}
@Inject(method = "onHit", at = @At("HEAD"), cancellable = true)
private void dropSupply(HitResult hitResult, CallbackInfo ci) {
super.onHit(hitResult);
boolean bl = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
Explosion explode = this.level().explode(this, this.getX(), this.getY(), this.getZ(), (float) this.explosionPower, bl, Level.ExplosionInteraction.MOB);
if (this.getTags().contains("meteor")) {
BlockPos chestPosition;
List<BlockPos> toBlow = explode.getToBlow();
if (!toBlow.isEmpty()) {
toBlow.sort(Comparator.comparing(BlockPos::getY));
chestPosition = toBlow.getFirst();
} else {
chestPosition = BlockPos.containing(this.getPosition(0));
}
this.level().setBlockAndUpdate(chestPosition, Blocks.BARREL.defaultBlockState());
this.level().getBlockEntity(chestPosition).applyComponents(DataComponentMap.builder().set(DataComponents.CUSTOM_NAME, ChatFormat.convertComponent(MiniMessage.miniMessage().deserialize(String.format("<bold><gradient:%s:%s>Meteor Supply Drop</gradient></bold>", ChatFormat.brandColor1, ChatFormat.brandColor2)))).build(), DataComponentPatch.builder().build());
RandomizableContainer.setBlockEntityLootTable(this.level(), this.level().getRandom(), chestPosition, ResourceKey.create(Registries.LOOT_TABLE, new ResourceLocation("nexia:chests/meteor")));
}
this.discard();
ci.cancel();
}
}
@@ -1,20 +0,0 @@
package com.nexia.teams.mixin;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.Difficulty;
import net.minecraft.world.level.storage.WorldData;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(MinecraftServer.class)
public abstract class MinecraftServerMixin {
@Shadow @Final protected WorldData worldData;
@ModifyArg(method = "setDifficulty", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/WorldData;setDifficulty(Lnet/minecraft/world/Difficulty;)V"))
public Difficulty makeHardcoreEasy(Difficulty difficulty) {
return this.worldData.isHardcore() ? Difficulty.EASY : difficulty;
}
}
@@ -1,20 +0,0 @@
package com.nexia.teams.mixin;
import com.nexia.teams.NexiaTeams;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.NetherPortalBlock;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(NetherPortalBlock.class)
public abstract class NetherPortalBlockMixin {
@Inject(method = "entityInside", at = @At("HEAD"), cancellable = true)
private void disableNetherPortal(BlockState blockState, Level level, BlockPos blockPos, Entity entity, CallbackInfo ci) {
if (NexiaTeams.netherDisabled) ci.cancel();
}
}
@@ -1,68 +0,0 @@
package com.nexia.teams.mixin;
import com.mojang.authlib.GameProfile;
import com.nexia.teams.NexiaTeams;
import com.nexia.teams.events.tournament.TournamentFight;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.time.ServerTime;
import eu.pb4.sgui.api.ClickType;
import eu.pb4.sgui.api.GuiHelpers;
import net.kyori.adventure.text.Component;
import net.minecraft.network.protocol.game.*;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.damagesource.CombatTracker;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.projectile.LargeFireball;
import net.minecraft.world.entity.vehicle.ContainerEntity;
import net.minecraft.world.inventory.ChestMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.GameType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerGamePacketListenerImpl.class)
public abstract class ServerGamePacketListenerMixin {
@Shadow public ServerPlayer player;
@Shadow public abstract ServerPlayer getPlayer();
@Shadow protected abstract GameProfile playerProfile();
@Inject(method = "handleUseItem", at = @At("TAIL"))
public void pearlCooldownMessage(ServerboundUseItemPacket serverboundUseItemPacket, CallbackInfo ci) {
InteractionHand interactionHand = serverboundUseItemPacket.getHand();
ItemStack itemStack = this.player.getItemInHand(interactionHand);
if (this.player.getCooldowns().isOnCooldown(itemStack.getItem()) && itemStack.getItem() == Items.ENDER_PEARL) {
double secondsLeft = (double) Math.round((15 * this.player.getCooldowns().getCooldownPercent(itemStack.getItem(), 0.0F) * 100)) / 100;
if(secondsLeft >= 14.9) return;
String secondsLeftText = String.format("You're on pearl cooldown. You have %s seconds left.", secondsLeft);
this.player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text(secondsLeftText))));
}
}
@Inject(method = "handleTeleportToEntityPacket", at = @At("HEAD"), cancellable = true)
public void disableSpectatorsTeleporting(ServerboundTeleportToEntityPacket serverboundTeleportToEntityPacket, CallbackInfo ci) {
if (this.player.isSpectator() && !this.player.hasPermissions(4)) ci.cancel();
}
@Inject(method = "handleInteract", at = @At("HEAD"), cancellable = true)
public void disableOrEnablePvp(ServerboundInteractPacket serverboundInteractPacket, CallbackInfo ci) {
final Entity entity = serverboundInteractPacket.getTarget(this.player.serverLevel());
if (entity instanceof LargeFireball && entity.getTags().contains("meteor")) ci.cancel();
if (!NexiaTeams.pvpEnabled && entity instanceof ServerPlayer) ci.cancel();
}
@ModifyArg(method = "handleClientCommand", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;setGameMode(Lnet/minecraft/world/level/GameType;)Z"))
public GameType deathSystem(GameType gameType) {
return NexiaTeams.hardcoreEnabled ? GameType.SPECTATOR : this.getPlayer().gameMode.getGameModeForPlayer();
}
}
@@ -1,45 +0,0 @@
package com.nexia.teams.mixin.mace;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.MaceItem;
import net.minecraft.world.item.enchantment.DensityEnchantment;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import static net.minecraft.world.item.MaceItem.canSmashAttack;
@Mixin(MaceItem.class)
public class MaceItemMixin extends Item {
public MaceItemMixin(Properties properties) {
super(properties);
}
@Inject(method = "getAttackDamageBonus", at = @At("HEAD"), cancellable = true)
public void getAttackDamageBonus(Player player, float f, CallbackInfoReturnable<Float> cir) {
if (!canSmashAttack(player)) {
cir.setReturnValue(0.0F);
} else {
float i = player.fallDistance;
float j;
if (i <= 3.0F) {
j = 4.0F * i;
} else if (i <= 8.0F) {
j = 12.0F + 2.0F * (i - 3.0F);
} else {
j = 22.0F + i - 8.0F;
}
int x = EnchantmentHelper.getEnchantmentLevel(Enchantments.DENSITY, player);
float z = DensityEnchantment.calculateDamageAddition(x, player.fallDistance);
z = (float) (z / 2.8);
j = (float) (j / 1.4);
cir.setReturnValue(j + z);
}
}
}
@@ -1,109 +0,0 @@
package com.nexia.teams.utilities.chat;
import com.google.common.base.Function;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.teams.utilities.time.ServerTime;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Entity;
/*
* Directly taken from Nexus and Nexia-Mod
* https://github.com/nexia-cts/nexus/blob/main/nexus-builder/src/main/java/com/nexia/nexus/builder/implementation/util/ObjectMappings.java#L3291
* https://github.com/nexia-cts/Nexia-Mod/blob/main/src/main/java/com/nexia/core/utilities/chat/ChatFormat.java
*/
public abstract class ChatFormat {
public static RegistryAccess.Frozen provider;
public static TextColor brandColor1 = TextColor.fromHexString("#a400fc");
public static TextColor brandColor2 = TextColor.fromHexString("#e700f0");
public static TextColor arrowColor = TextColor.fromHexString("#4a4a4a");
public static class Minecraft {
public static TextColor dark_red = TextColor.fromHexString("#b51413");
public static TextColor red = TextColor.fromHexString("#ff2b1c");
public static TextColor gold = TextColor.fromHexString("#f5bc42");
public static TextColor yellow = TextColor.fromHexString("#fff60c");
public static TextColor dark_green = TextColor.fromHexString("#1b9c19");
public static TextColor green = TextColor.fromHexString("#38e312");
public static TextColor aqua = TextColor.fromHexString("#28e2ff");
public static TextColor dark_aqua = TextColor.fromHexString("#399ca9");
public static TextColor dark_blue = TextColor.fromHexString("#263daa");
public static TextColor blue = TextColor.fromHexString("#2955ff");
public static TextColor light_purple = ChatFormat.brandColor2;
public static TextColor dark_purple = ChatFormat.brandColor1;
public static TextColor white = TextColor.fromHexString("#ffffff");
public static TextColor gray = TextColor.fromHexString("#c7c7c7");
public static TextColor dark_gray = TextColor.fromHexString("#767676");
public static TextColor black = TextColor.fromHexString("#252525");
}
public static net.kyori.adventure.text.Component nexiaMessage = MiniMessage.miniMessage().deserialize(String.format("<bold><gradient:%s:%s>Nexia</gradient></bold> <color:%s>»</color> ", ChatFormat.brandColor1, ChatFormat.brandColor2, ChatFormat.arrowColor));
public static Component convertComponent(net.kyori.adventure.text.Component component) {
if (component == null || provider == null) return null;
String compString = GsonComponentSerializer.gson().serialize(component);
return Component.Serializer.fromJson(compString, provider);
}
public static net.kyori.adventure.text.Component convertComponent(Component mcComponent) {
if (mcComponent == null || provider == null) return null;
String mcCompString = Component.Serializer.toJson(mcComponent, provider);
return GsonComponentSerializer.gson().deserialize(mcCompString);
}
public static ChatFormatting getSecondaryColor(ChatFormatting primary) {
return switch (primary) {
case ChatFormatting.AQUA -> ChatFormatting.DARK_AQUA;
case ChatFormatting.DARK_AQUA -> ChatFormatting.AQUA;
case ChatFormatting.BLUE -> ChatFormatting.DARK_BLUE;
case ChatFormatting.DARK_BLUE -> ChatFormatting.BLUE;
case ChatFormatting.WHITE -> ChatFormatting.GRAY;
case ChatFormatting.GRAY -> ChatFormatting.WHITE;
case ChatFormatting.DARK_GRAY -> ChatFormatting.BLACK;
case ChatFormatting.BLACK -> ChatFormatting.DARK_GRAY;
case ChatFormatting.RED -> ChatFormatting.DARK_RED;
case ChatFormatting.DARK_RED -> ChatFormatting.RED;
case ChatFormatting.GREEN -> ChatFormatting.DARK_GREEN;
case ChatFormatting.DARK_GREEN -> ChatFormatting.GREEN;
case ChatFormatting.LIGHT_PURPLE -> ChatFormatting.DARK_PURPLE;
case ChatFormatting.DARK_PURPLE -> ChatFormatting.LIGHT_PURPLE;
case ChatFormatting.YELLOW -> ChatFormatting.GOLD;
case ChatFormatting.GOLD -> ChatFormatting.YELLOW;
default -> primary;
};
}
public static void nexiaTitle(CommandSourceStack commandSourceStack, String message) throws CommandSyntaxException {
Component messageComponent = convertComponent(MiniMessage.miniMessage().deserialize(String.format("<bold><gradient:%s:%s>%s</gradient></bold>", ChatFormat.brandColor1, ChatFormat.brandColor2, message)));
for (ServerPlayer serverPlayer : ServerTime.minecraftServer.getPlayerList().getPlayers()) {
Function<Component, ClientboundSetTitleTextPacket> title = ClientboundSetTitleTextPacket::new;
serverPlayer.connection.send(title.apply(ComponentUtils.updateForEntity(commandSourceStack, messageComponent, serverPlayer, 0)));
serverPlayer.level().playSound(
null,
BlockPos.containing(serverPlayer.getPosition(0)),
SoundEvents.ENDER_DRAGON_GROWL,
SoundSource.MASTER,
1f,
1f
);
}
}
}
@@ -1,69 +0,0 @@
package com.nexia.teams.utilities.data;
import com.google.gson.Gson;
import com.nexia.teams.events.koth.KothGame;
import com.nexia.teams.events.koth.KothGameHandler;
import com.nexia.teams.utilities.time.ServerTime;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.world.phys.AABB;
import java.io.File;
import java.io.FileWriter;
import java.nio.file.Files;
import java.nio.file.Path;
public abstract class KothDataManager {
public static String dataDirectory = FabricLoader.getInstance().getConfigDir().toString() + "/nexia/koth";
public static void saveKothGamesData() {
try {
for (KothGame kothGame : KothGameHandler.kothGames) {
Gson gson = new Gson();
SavedKothData savedKothData = new SavedKothData(
kothGame.creator,
kothGame.name,
kothGame.scheduledTimestamp,
(kothGame.area == null) ? null : new double[]{kothGame.area.minX, kothGame.area.minY, kothGame.area.minZ},
(kothGame.area == null) ? null : new double[]{kothGame.area.maxX, kothGame.area.maxY, kothGame.area.maxZ},
kothGame.time,
kothGame.level.dimension().location().toString()
);
String json = gson.toJson(savedKothData);
String directory = getDataDir();
FileWriter fileWriter = new FileWriter(directory + "/" + kothGame.name + ".json");
fileWriter.write(json);
fileWriter.close();
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
public static void loadKothGamesData() {
try {
String directory = getDataDir();
for (File file : new File(directory).listFiles()) {
String json = Files.readString(Path.of(directory + "/" + file.getName()));
Gson gson = new Gson();
SavedKothData savedKothData = gson.fromJson(json, SavedKothData.class);
KothGame kothGame = new KothGame(
savedKothData.creator,
savedKothData.name,
savedKothData.scheduledTimeStamp,
(savedKothData.firstBlockPos == null || savedKothData.lastBlockPos == null) ? null : new AABB(savedKothData.firstBlockPos[0], savedKothData.firstBlockPos[1], savedKothData.firstBlockPos[2], savedKothData.lastBlockPos[0], savedKothData.lastBlockPos[1], savedKothData.lastBlockPos[2]),
null,
ServerTime.getLevelByName(savedKothData.level)
);
KothGameHandler.kothGames.add(kothGame);
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
private static String getDataDir() {
(new File(dataDirectory)).mkdirs();
return dataDirectory;
}
}
@@ -1,49 +0,0 @@
package com.nexia.teams.utilities.data;
import com.google.gson.Gson;
import com.nexia.teams.NexiaTeams;
import net.fabricmc.loader.api.FabricLoader;
import java.io.File;
import java.io.FileWriter;
import java.nio.file.Files;
public class NexiaDataManager {
public static String dataDirectory = FabricLoader.getInstance().getConfigDir().toString() + "/nexia";
public static void saveNexiaData() {
try {
Gson gson = new Gson();
SavedNexiaData savedNexiaData = new SavedNexiaData(NexiaTeams.pvpEnabled, NexiaTeams.endDisabled, NexiaTeams.netherDisabled, NexiaTeams.hardcoreEnabled);
String json = gson.toJson(savedNexiaData);
String directory = getDataDir();
FileWriter fileWriter = new FileWriter(directory + "/nexia.json");
fileWriter.write(json);
fileWriter.close();
} catch (Exception exception) {
exception.printStackTrace();
}
}
public static void loadNexiaData() {
try {
String directory = getDataDir();
File file = new File(directory + "/nexia.json");
String json = Files.readString(file.toPath());
Gson gson = new Gson();
SavedNexiaData savedNexiaData = gson.fromJson(json, SavedNexiaData.class);
NexiaTeams.pvpEnabled = savedNexiaData.pvpEnabled;
NexiaTeams.endDisabled = savedNexiaData.endDisabled;
NexiaTeams.netherDisabled = savedNexiaData.netherDisabled;
NexiaTeams.hardcoreEnabled = savedNexiaData.hardcoreEnabled;
} catch (Exception exception) {
exception.printStackTrace();
}
}
private static String getDataDir() {
(new File(dataDirectory)).mkdirs();
return dataDirectory;
}
}
@@ -1,21 +0,0 @@
package com.nexia.teams.utilities.data;
public class SavedKothData {
public String creator;
public String name;
public Long scheduledTimeStamp;
public double[] firstBlockPos;
public double[] lastBlockPos;
public int time;
public String level;
public SavedKothData(String creator, String name, Long scheduledTimeStamp, double[] firstBlockPos, double[] lastBlockPos, int time, String level) {
this.creator = creator;
this.name = name;
this.scheduledTimeStamp = scheduledTimeStamp;
this.firstBlockPos = firstBlockPos;
this.lastBlockPos = lastBlockPos;
this.time = time;
this.level = level;
}
}
@@ -1,15 +0,0 @@
package com.nexia.teams.utilities.data;
public class SavedNexiaData {
public boolean pvpEnabled;
public boolean endDisabled;
public boolean netherDisabled;
public boolean hardcoreEnabled;
public SavedNexiaData(boolean pvpEnabled, boolean endDisabled, boolean netherDisabled, boolean hardcoreEnabled) {
this.pvpEnabled = pvpEnabled;
this.endDisabled = endDisabled;
this.netherDisabled = netherDisabled;
this.hardcoreEnabled = hardcoreEnabled;
}
}
@@ -1,25 +0,0 @@
package com.nexia.teams.utilities.teams;
import static com.nexia.teams.utilities.teams.TeamUtil.timeout;
public class TeamInvite {
private final String teamName;
private int remainingTicks;
public TeamInvite(String teamName) {
this.remainingTicks = timeout;
this.teamName = teamName;
}
public String getTeamName() {
return this.teamName;
}
public boolean isExpired() {
return this.remainingTicks <= 0;
}
public void hasTicked() {
this.remainingTicks--;
}
}
@@ -1,47 +0,0 @@
package com.nexia.teams.utilities.teams;
import com.nexia.teams.utilities.chat.ChatFormat;
import net.kyori.adventure.text.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public abstract class TeamUtil {
public static final int timeout = 2400; // 2 minutes in minecraft ticks
private static final HashMap<UUID, TeamInvite> invites = new HashMap<>();
public static void addInvite(ServerPlayer player, String teamName) {
invites.put(player.getUUID(), new TeamInvite(teamName));
}
public static String getInvitedTeam(ServerPlayer player) {
TeamInvite invite = invites.get(player.getUUID());
if (invite != null) return invite.getTeamName();
return null;
}
public static void removeInvite(ServerPlayer player) {
invites.remove(player.getUUID());
}
public static void tick(MinecraftServer server) {
for (Map.Entry<UUID, TeamInvite> entry : invites.entrySet()) {
TeamInvite invite = entry.getValue();
if (invite.isExpired()) {
UUID playerUuid = entry.getKey();
invites.remove(playerUuid);
ServerPlayer player = server.getPlayerList().getPlayer(playerUuid);
if (player != null) {
player.sendSystemMessage(ChatFormat.convertComponent(ChatFormat.nexiaMessage.append(Component.text("Your invite has expired!"))));
}
}
invite.hasTicked();
}
}
}
@@ -1,83 +0,0 @@
package com.nexia.teams.utilities.time;
import com.google.common.base.Suppliers;
import com.nexia.teams.events.koth.KothGame;
import com.nexia.teams.events.koth.KothGameHandler;
import com.nexia.teams.events.meteor.Meteor;
import com.nexia.teams.events.tournament.TournamentFight;
import com.nexia.teams.utilities.chat.ChatFormat;
import com.nexia.teams.utilities.data.KothDataManager;
import com.nexia.teams.utilities.data.NexiaDataManager;
import com.nexia.teams.utilities.teams.TeamUtil;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
public abstract class ServerTime {
public static MinecraftServer minecraftServer = null;
private static int totalTickCount = -1;
private static int totalSecondCount = -1;
public static void firstTick(MinecraftServer server) {
ServerTime.minecraftServer = server;
ChatFormat.provider = Suppliers.ofInstance(RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)).get();
NexiaDataManager.loadNexiaData();
KothDataManager.loadKothGamesData();
TournamentFight.loadTournamentConfig();
}
public static void stopServer(MinecraftServer server) {
NexiaDataManager.saveNexiaData();
KothGameHandler.stopAllKothGames();
KothDataManager.saveKothGamesData();
if (TournamentFight.isRunning || TournamentFight.isStarting) TournamentFight.end();
try {
for (ServerPlayer player : server.getPlayerList().getPlayers()) {
player.connection.disconnect(ChatFormat.convertComponent(MiniMessage.miniMessage().deserialize(String.format("<color:%s>Server is restarting!</color>", ChatFormat.Minecraft.red.asHexString()))));
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void everyTick(MinecraftServer server) {
totalTickCount++;
TeamUtil.tick(server);
if (totalTickCount % 20 == 0) {
everySecond();
}
}
static void everySecond() {
totalSecondCount++;
Meteor.second();
TournamentFight.second();
long unixTime = System.currentTimeMillis() / 1000L;
for (KothGame kothGame : KothGameHandler.kothGames) {
if (kothGame.scheduledTimestamp == null) continue;
if (kothGame.scheduledTimestamp == unixTime) {
kothGame.start();
}
}
KothGameHandler.kothGamesSecond();
}
public static ServerLevel getLevelByName(String name) {
for (ServerLevel serverLevel : minecraftServer.getAllLevels()) {
if (serverLevel.dimension().location().toString().equals(name)) {
return serverLevel;
}
}
return null;
}
}
+52
View File
@@ -0,0 +1,52 @@
package com.nexia.uhc;
import com.nexia.nexus.api.NexusAPI;
import com.nexia.nexus.api.NexusServer;
import com.nexia.nexus.api.entrypoint.NexusPlugin;
import com.nexia.nexus.api.scheduler.TaskScheduler;
import com.nexia.nexus.api.util.Identifier;
import com.nexia.nexus.api.world.util.Location;
import com.nexia.uhc.game.GameManager;
import com.nexia.uhc.game.Lobby;
import com.nexia.uhc.utility.CommandLoader;
import com.nexia.uhc.utility.ListenerLoader;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.server.MinecraftServer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class NexiaUHC implements ModInitializer, NexusPlugin {
public static final String MOD_ID = "nexia-uhc";
public static Logger logger = LogManager.getLogger(MOD_ID);
public static MinecraftServer minecraftServer;
public static NexusAPI nexusAPI;
public static NexusServer nexusServer;
public static TaskScheduler taskScheduler;
public static Lobby lobby;
public static GameManager manager;
@Override
public void onInitialize() {
ServerLifecycleEvents.SERVER_STARTED.register(server -> NexiaUHC.minecraftServer = server);
logger.info("Initialized Nexia UHC");
}
@Override
public void onNexusLoad(NexusAPI nexusAPI, NexusServer nexusServer) {
NexiaUHC.nexusAPI = nexusAPI;
NexiaUHC.nexusServer = nexusServer;
NexiaUHC.taskScheduler = nexusAPI.getScheduler();
NexiaUHC.lobby = new Lobby(new Location(0.5, 80.0, 0.5, nexusServer.getWorld(new Identifier("overworld"))));
NexiaUHC.manager = new GameManager();
CommandLoader.registerCommands();
ListenerLoader.registerListeners();
}
}
@@ -0,0 +1,62 @@
package com.nexia.uhc.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.nexus.api.command.CommandSourceInfo;
import com.nexia.nexus.api.command.CommandUtils;
import com.nexia.nexus.api.world.types.Minecraft;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.utility.ChatFormat;
import net.kyori.adventure.text.Component;
public class GameCommand {
public void registerCommand(CommandDispatcher<CommandSourceInfo> commandDispatcher) {
commandDispatcher.register(
CommandUtils.literal("uhc").requires(commandSourceInfo -> commandSourceInfo.getSender().getPermissionLevel() > 2)
.executes(GameCommand::help)
.then(CommandUtils.literal("start")
.executes(GameCommand::start))
.then(CommandUtils.literal("end")
.executes(GameCommand::end))
);
}
private static int help(CommandContext<CommandSourceInfo> context) {
Component helpMessage = ChatFormat.nexia
.append(Component.text("\nuhc start").append(ChatFormat.arrow.append(Component.text("Starts the UHC."))))
.append(Component.text("\nuhc end").append(ChatFormat.arrow.append(Component.text("Ends the UHC."))));
context.getSource().sendMessage(helpMessage);
return 0;
}
private static int start(CommandContext<CommandSourceInfo> context) throws CommandSyntaxException {
if (!NexiaUHC.manager.getGames().isEmpty()) {
context.getSource().sendMessage(Component.text("There is already an ongoing UHC game!").color(ChatFormat.failColor));
context.getSource().getPlayerOrException().playSound(Minecraft.Sound.NOTE_BLOCK_BASS, 1, 1);
return 1;
}
if (NexiaUHC.lobby.getPlayers().size() <= 1) {
context.getSource().sendMessage(Component.text("Not enough players!").color(ChatFormat.failColor));
context.getSource().getPlayerOrException().playSound(Minecraft.Sound.NOTE_BLOCK_BASS, 1, 1);
return 1;
}
NexiaUHC.manager.createGame();
context.getSource().sendMessage(ChatFormat.nexiaMessage.append(Component.text("Successfully started UHC game.")));
return 0;
}
private static int end(CommandContext<CommandSourceInfo> context) throws CommandSyntaxException {
if (NexiaUHC.manager.getGames().isEmpty()) {
context.getSource().sendMessage(Component.text("There isn't an ongoing UHC game!").color(ChatFormat.failColor));
context.getSource().getPlayerOrException().playSound(Minecraft.Sound.NOTE_BLOCK_BASS, 1, 1);
return 1;
}
NexiaUHC.manager.deleteGame(NexiaUHC.manager.getGames().getFirst());
return 0;
}
}
@@ -0,0 +1,32 @@
package com.nexia.uhc.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.nexus.api.command.CommandSourceInfo;
import com.nexia.nexus.api.command.CommandUtils;
import com.nexia.nexus.api.world.entity.player.Player;
import com.nexia.nexus.api.world.types.Minecraft;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.game.Game;
public class LobbyCommand {
public void registerCommand(CommandDispatcher<CommandSourceInfo> commandDispatcher) {
commandDispatcher.register(CommandUtils.literal("lobby").executes(LobbyCommand::execute));
commandDispatcher.register(CommandUtils.literal("hub").executes(LobbyCommand::execute));
commandDispatcher.register(CommandUtils.literal("spawn").executes(LobbyCommand::execute));
}
private static int execute(CommandContext<CommandSourceInfo> context) throws CommandSyntaxException {
Player player = context.getSource().getPlayerOrException();
Game game = NexiaUHC.manager.getGame(player);
if (game != null) {
player.kill();
return 1;
}
NexiaUHC.lobby.returnToLobby(player, Minecraft.GameMode.SURVIVAL, true);
return 0;
}
}
@@ -0,0 +1,36 @@
package com.nexia.uhc.commands;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.nexia.nexus.api.command.CommandSourceInfo;
import com.nexia.nexus.api.command.CommandUtils;
import com.nexia.nexus.api.world.entity.player.Player;
import com.nexia.nexus.api.world.types.Minecraft;
import com.nexia.nexus.api.world.util.Location;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.utility.ChatFormat;
import net.kyori.adventure.text.Component;
public class SpectateCommand {
public void registerCommand(CommandDispatcher<CommandSourceInfo> commandDispatcher) {
commandDispatcher.register(CommandUtils.literal("spectate").executes(SpectateCommand::spectate));
}
private static int spectate(CommandContext<CommandSourceInfo> context) throws CommandSyntaxException {
Player player = context.getSource().getPlayerOrException();
if (NexiaUHC.manager.getGames().isEmpty()) {
context.getSource().sendMessage(Component.text("There isn't an ongoing UHC game!").color(ChatFormat.failColor));
context.getSource().getPlayerOrException().playSound(Minecraft.Sound.NOTE_BLOCK_BASS, 1, 1);
return 1;
}
if (!NexiaUHC.lobby.isInLobby(player)) {
context.getSource().sendMessage(Component.text("You need to be in the lobby to run that command!").color(ChatFormat.failColor));
context.getSource().getPlayerOrException().playSound(Minecraft.Sound.NOTE_BLOCK_BASS, 1, 1);
return 1; }
player.teleport(new Location(0.5, 80, 0.5, NexiaUHC.manager.getGames().getFirst().getOverworld()));
return 0;
}
}
+169
View File
@@ -0,0 +1,169 @@
package com.nexia.uhc.game;
import com.google.gson.JsonParser;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.JsonOps;
import com.nexia.nexus.api.world.entity.player.Player;
import com.nexia.nexus.api.world.types.Minecraft;
import com.nexia.nexus.api.world.util.Location;
import com.nexia.nexus.builder.implementation.world.WrappedWorld;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.utility.ChatFormat;
import com.nexia.uhc.utility.MathUtil;
import net.fabricmc.loader.api.FabricLoader;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.levelgen.Heightmap;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class Game {
String id;
Path instanceDir;
List<Player> players;
WrappedWorld overworld;
long seed;
boolean isRunning;
boolean isPvpEnabled;
// measured in minecraft ticks
int timeUntilPvp;
int timeUntilDeathmatch;
public Game(List<Player> players) {
this.id = UUID.randomUUID().toString();
this.instanceDir = Path.of(NexiaUHC.manager.instancesDir + "/" + this.id);
this.players = new ArrayList<>(players);
this.isRunning = false;
this.isPvpEnabled = false;
this.timeUntilPvp = 18000;
this.timeUntilDeathmatch = 18000;
}
public boolean isPvpEnabled() {
return isPvpEnabled;
}
public List<Player> getPlayers() {
return players;
}
public WrappedWorld getOverworld() {
return this.overworld;
}
CompletableFuture<Void> prepare() {
CompletableFuture<Void> future = new CompletableFuture<>();
long millisecs = System.currentTimeMillis();
try {
Files.createDirectories(instanceDir);
String worldData = Files.readString(Path.of(FabricLoader.getInstance().getConfigDir() + "/nexia-uhc.json"));
this.seed = NexiaUHC.minecraftServer.overworld().random.nextLong();
worldData = worldData.replaceAll("null", String.valueOf(this.seed));
DataResult<CompoundTag> worldDataNbt = CompoundTag.CODEC.parse(JsonOps.INSTANCE, new JsonParser().parse(worldData));
CompoundTag data = new CompoundTag();
data.put("Data", worldDataNbt.result().orElseThrow());
File level = new File(instanceDir.toFile(), "level.dat");
NbtIo.writeCompressed(data, level);
NexiaUHC.nexusServer.loadWorldAsync(instanceDir, this.id).thenRun(() -> {
NexiaUHC.logger.info("Done. (Took {}ms)", System.currentTimeMillis() - millisecs);
this.overworld = new WrappedWorld(NexiaUHC.minecraftServer.getLevel(ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(this.id + ".minecraft", "overworld"))));
future.complete(null);
});
return future;
} catch (IOException e) {
NexiaUHC.logger.error("Error creating world data to instance folder '{}': ", instanceDir.toAbsolutePath(), e);
future.completeExceptionally(e);
return future;
}
}
public void start() {
this.prepare().whenComplete((unused, throwable) -> {
if (throwable == null) {
isRunning = true;
ArrayList<int[]> initialPositions = MathUtil.createInitialPositions(new Random(), this.players.size(), -500, 500);
this.players.forEach(player -> {
player.setGameMode(Minecraft.GameMode.SURVIVAL);
int[] pos = initialPositions.get(this.players.indexOf(player));
int height = this.overworld.unwrap().getChunk(pos[0] >> 4, pos[1] >> 4).getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, pos[0] & 15, pos[1] & 15) + 1;
player.teleport(new Location(pos[0] + 0.5, height, pos[1] + 0.5, this.overworld));
player.runCommand("loadinventory starter");
});
} else {
NexiaUHC.logger.error("Error loading UHC world: {}", throwable);
NexiaUHC.manager.deleteGame(this);
}
});
}
public void tick() {
if (!isPvpEnabled && timeUntilPvp > 0) {
this.players.forEach(player -> player.sendActionBarMessage(ChatFormat.nexiaMessage.append(Component.text("Time until PVP: " + MathUtil.convertTicksToTime(timeUntilPvp)).color(NamedTextColor.GRAY))));
this.timeUntilPvp--;
if (this.timeUntilPvp == 0) this.enablePvp();
}
if (this.isPvpEnabled && this.timeUntilDeathmatch > 0) {
this.players.forEach(player -> player.sendActionBarMessage(ChatFormat.nexiaMessage.append(Component.text("Time until death match: " + MathUtil.convertTicksToTime(timeUntilDeathmatch)).color(NamedTextColor.GRAY))));
this.timeUntilDeathmatch--;
if (this.timeUntilDeathmatch == 0) this.deathMatch();
}
}
public void enablePvp() {
this.isPvpEnabled = true;
this.players.forEach(player -> {
player.sendMessage(ChatFormat.nexiaMessage.append(Component.text("PVP has been enabled!")));
player.playSound(Minecraft.Sound.ENDER_DRAGON_GROWL, 1, 1);
});
}
public void deathMatch() {
ArrayList<int[]> initialPositions = MathUtil.createInitialPositions(new Random(), this.players.size(), -100, 100);
this.players.forEach(player -> {
player.sendMessage(ChatFormat.nexiaMessage.append(Component.text("Death match has started!")));
int[] pos = initialPositions.get(this.players.indexOf(player));
int height = this.overworld.unwrap().getChunk(pos[0] >> 4, pos[1] >> 4).getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, pos[0] & 15, pos[1] & 15) + 1;
player.teleport(new Location(pos[0] + 0.5, height, pos[1] + 0.5, this.overworld));
player.playSound(Minecraft.Sound.RAID_HORN, 1, 1);
});
this.overworld.unwrap().getWorldBorder().setSize(200);
}
public void end() {
this.players.forEach(player -> {
player.sendMessage(ChatFormat.nexiaMessage.append(Component.text("World seed: " + this.seed)));
NexiaUHC.lobby.returnToLobby(player, Minecraft.GameMode.SURVIVAL, true);
});
try {
NexiaUHC.nexusServer.unloadWorld(this.id, false);
FileUtils.forceDeleteOnExit(instanceDir.toFile());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,63 @@
package com.nexia.uhc.game;
import com.nexia.nexus.api.world.entity.player.Player;
import com.nexia.nexus.api.world.types.Minecraft;
import com.nexia.uhc.NexiaUHC;
import net.fabricmc.loader.api.FabricLoader;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.title.Title;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class GameManager {
ArrayList<Game> games = new ArrayList<>();
Path instancesDir = Path.of(FabricLoader.getInstance().getGameDir() + "/uhc");
public List<Game> getGames() {
return this.games;
}
public void createGame() {
List<Player> players = NexiaUHC.lobby.getPlayers();
Game game = new Game(players);
NexiaUHC.lobby.getPlayers().removeAll(players);
games.add(game);
game.start();
}
public void tickAllGames() {
for (Game game : this.games) {
if (game.getPlayers().size() == 1 && game.isRunning) {
Player winner = game.getPlayers().getFirst();
game.getPlayers().forEach(player -> {
player.sendTitle(Title.title(winner.getName().color(NamedTextColor.GOLD), Component.text("has won the game!")));
player.playSound(Minecraft.Sound.UI_TOAST_CHALLENGE_COMPLETE, 1, 1);
});
NexiaUHC.taskScheduler.schedule(() -> NexiaUHC.manager.deleteGame(game), 100);
game.isRunning = false;
}
if (game.isRunning) game.tick();
}
}
public void deleteGame(Game game) {
game.end();
this.games.remove(game);
}
public Game getGame(Player player) {
for (Game game : this.games) {
if (game.players.contains(player)) {
return game;
}
}
return null;
}
}
@@ -0,0 +1,53 @@
package com.nexia.uhc.game;
import com.nexia.nexus.api.util.Identifier;
import com.nexia.nexus.api.world.entity.player.Player;
import com.nexia.nexus.api.world.item.ItemStack;
import com.nexia.nexus.api.world.types.Minecraft;
import com.nexia.nexus.api.world.util.Location;
import com.nexia.uhc.NexiaUHC;
import java.util.ArrayList;
import java.util.List;
public class Lobby {
private final List<Player> lobbyPlayers = new ArrayList<>();
private final Location spawn;
public Lobby(Location spawn) {
this.spawn = spawn;
}
public Location getSpawn() {
return spawn;
}
public List<Player> getPlayers() {
return lobbyPlayers;
}
public boolean isInLobby(Player player) {
return this.lobbyPlayers.contains(player) || player.getWorld().equals(NexiaUHC.nexusServer.getWorld(new Identifier("overworld")));
}
public void returnToLobby(Player player, Minecraft.GameMode gameMode, boolean teleport) {
if (!this.lobbyPlayers.contains(player)) this.lobbyPlayers.add(player);
player.setInvulnerabilityTime(0);
player.clearEffects();
player.getInventory().clear();
player.setRemainingFireTicks(0);
player.setExperienceLevel(0);
player.setExperiencePoints(0);
player.getInventory().setCursorStack(ItemStack.create(Minecraft.Item.AIR));
player.setGlowing(false);
player.setHealth(player.getMaxHealth());
player.setFoodLevel(20);
player.setAbleToFly(false);
if (teleport) {
player.setGameMode(gameMode);
player.teleport(this.spawn);
}
}
}
@@ -0,0 +1,23 @@
package com.nexia.uhc.listeners;
import com.nexia.nexus.api.event.entity.LivingEntityDamageEvent;
import com.nexia.nexus.api.world.entity.player.Player;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.game.Game;
public class PlayerDamageListener {
public void registerListener() {
LivingEntityDamageEvent.BACKEND.register(event -> {
if (event.getLivingEntity() instanceof Player player) {
Game game = NexiaUHC.manager.getGame(player);
if (game != null && !game.isPvpEnabled()) {
event.setCancelled(true);
}
if (NexiaUHC.lobby.isInLobby(player)) {
event.setCancelled(true);
}
}
});
}
}
@@ -0,0 +1,22 @@
package com.nexia.uhc.listeners;
import com.nexia.nexus.api.event.player.PlayerDeathEvent;
import com.nexia.nexus.api.world.entity.player.Player;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.game.Game;
import net.kyori.adventure.text.format.NamedTextColor;
public class PlayerDeathListener {
public void registerListener() {
PlayerDeathEvent.BACKEND.register(event -> {
Player player = event.getPlayer();
Game game = NexiaUHC.manager.getGame(player);
if (game != null) {
game.getPlayers().remove(player);
}
event.setDeathMessage(event.getDeathMessage().color(NamedTextColor.WHITE));
});
}
}
@@ -0,0 +1,14 @@
package com.nexia.uhc.listeners;
import com.nexia.nexus.api.event.player.PlayerFoodLevelsChangeEvent;
import com.nexia.uhc.NexiaUHC;
public class PlayerHungerListener {
public void registerListener() {
PlayerFoodLevelsChangeEvent.BACKEND.register(event -> {
if (NexiaUHC.lobby.isInLobby(event.getPlayer())) {
event.setCancelled(true);
}
});
}
}
@@ -0,0 +1,26 @@
package com.nexia.uhc.listeners;
import com.nexia.nexus.api.event.player.PlayerBreakBlockEvent;
import com.nexia.nexus.api.event.player.PlayerChangeBlockStateEvent;
import com.nexia.nexus.api.event.player.PlayerInteractBlockEvent;
import com.nexia.nexus.api.world.types.Minecraft;
import com.nexia.uhc.NexiaUHC;
public class PlayerInteractListener {
public void registerListener() {
PlayerBreakBlockEvent.BACKEND.register(event -> {
if (!NexiaUHC.lobby.isInLobby(event.getPlayer()) || event.getPlayer().getGameMode() == Minecraft.GameMode.CREATIVE) return;
event.setCancelled(true);
});
PlayerInteractBlockEvent.BACKEND.register(event -> {
if (!NexiaUHC.lobby.isInLobby(event.getPlayer()) || event.getPlayer().getGameMode() == Minecraft.GameMode.CREATIVE) return;
event.setCancelled(true);
});
PlayerChangeBlockStateEvent.BACKEND.register(event -> {
if (!NexiaUHC.lobby.isInLobby(event.getPlayer()) || event.getPlayer().getGameMode() == Minecraft.GameMode.CREATIVE) return;
event.setCancelled(true);
});
}
}
@@ -0,0 +1,25 @@
package com.nexia.uhc.listeners;
import com.nexia.nexus.api.event.player.PlayerJoinEvent;
import com.nexia.nexus.api.world.entity.player.Player;
import com.nexia.nexus.api.world.types.Minecraft;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.utility.ChatFormat;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.title.Title;
public class PlayerJoinListener {
public void registerListener() {
PlayerJoinEvent.BACKEND.register(event -> {
Player player = event.getPlayer();
player.teleport(NexiaUHC.lobby.getSpawn());
NexiaUHC.lobby.returnToLobby(player, Minecraft.GameMode.SURVIVAL, true);
player.sendTitle(Title.title(Component.text("Welcome to"), Component.text("Nexia UHC")));
event.setJoinMessage(ChatFormat.nexiaMessage.append(event.getJoinMessage().color(NamedTextColor.WHITE)));
player.playSound(Minecraft.Sound.CAT_STRAY_AMBIENT, 1, 1);
});
}
}
@@ -0,0 +1,25 @@
package com.nexia.uhc.listeners;
import com.nexia.nexus.api.event.player.PlayerDisconnectEvent;
import com.nexia.nexus.api.world.entity.player.Player;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.game.Game;
import com.nexia.uhc.utility.ChatFormat;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
public class PlayerLeaveListener {
public void registerListener() {
PlayerDisconnectEvent.BACKEND.register(event -> {
Player player = event.getPlayer();
Game game = NexiaUHC.manager.getGame(player);
if (game != null) {
game.getPlayers().remove(player);
}
NexiaUHC.lobby.getPlayers().remove(player);
event.setLeaveMessage(ChatFormat.nexiaMessage.append(player.getName().append(Component.text(" left the game")).color(NamedTextColor.WHITE)));
});
}
}
@@ -0,0 +1,16 @@
package com.nexia.uhc.listeners;
import com.nexia.nexus.api.event.player.PlayerMoveEvent;
import com.nexia.uhc.NexiaUHC;
public class PlayerMoveListener {
public void registerListener() {
PlayerMoveEvent.BACKEND.register(event -> {
if (!NexiaUHC.lobby.isInLobby(event.getPlayer())) return;
if (event.getNewPosition().getY() < -5) {
event.setNewPosition(NexiaUHC.lobby.getSpawn());
}
});
}
}
@@ -0,0 +1,16 @@
package com.nexia.uhc.listeners;
import com.nexia.nexus.api.event.player.PlayerRespawnEvent;
import com.nexia.nexus.api.world.types.Minecraft;
import com.nexia.uhc.NexiaUHC;
public class PlayerRespawnListener {
public void registerListener() {
PlayerRespawnEvent.BACKEND.register(event -> {
NexiaUHC.lobby.returnToLobby(event.getPlayer(), Minecraft.GameMode.SURVIVAL, false);
event.setRespawnMode(Minecraft.GameMode.SURVIVAL);
event.setSpawnpoint(NexiaUHC.lobby.getSpawn());
event.setSpawnpointForced(true);
});
}
}
@@ -0,0 +1,31 @@
package com.nexia.uhc.listeners;
import com.nexia.nexus.api.event.server.ServerStartupFinishEvent;
import com.nexia.nexus.api.event.server.ServerStopEvent;
import com.nexia.nexus.api.event.server.ServerTickEvent;
import com.nexia.nexus.api.world.scoreboard.Scoreboard;
import com.nexia.nexus.api.world.scoreboard.ScoreboardObjective;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.utility.ChatFormat;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
public class ServerEventsListener {
public void registerListener() {
ServerStartupFinishEvent.BACKEND.register(event -> {
Scoreboard serverScoreboard = event.getServer().getServerScoreboard();
ScoreboardObjective health = serverScoreboard.getObjective("hp");
if (health == null) health = serverScoreboard.addObjective("hp", "health");
serverScoreboard.setDisplayedObjective(health, "belowName");
health.setDisplayName(Component.text("❤").color(TextColor.fromHexString("#ff2b1c")));
});
ServerStopEvent.BACKEND.register(event -> NexiaUHC.manager.getGames().forEach(game -> NexiaUHC.manager.deleteGame(game)));
ServerTickEvent.BACKEND.register(event -> {
NexiaUHC.manager.tickAllGames();
NexiaUHC.lobby.getPlayers().forEach(player -> player.sendActionBarMessage(ChatFormat.nexiaIp));
});
}
}
@@ -0,0 +1,19 @@
package com.nexia.uhc.mixin;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseFireBlock;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
@Mixin(BaseFireBlock.class)
public class BaseFireBlockMixin {
/**
* @author NotInfinityy
* @reason This fixes an issue where you can't ignite nether portals in nexus dynamic worlds.
*/
@Overwrite
private static boolean inPortalDimension(Level level) {
String levelName = level.dimension().location().getPath();
return levelName.equals("overworld") || levelName.equals("the_nether");
}
}
@@ -0,0 +1,23 @@
package com.nexia.uhc.mixin;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.EndPortalBlock;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(EndPortalBlock.class)
public class EndPortalBlockMixin {
// Fix getting sent to the wrong end dimension in a dynamic world
@ModifyArg(method = "entityInside", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getLevel(Lnet/minecraft/resources/ResourceKey;)Lnet/minecraft/server/level/ServerLevel;"))
public ResourceKey<Level> handleDynamicEnd(ResourceKey<Level> resourceKey) {
String levelNamespace = resourceKey.location().getNamespace();
ResourceKey<Level> end = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(levelNamespace, "the_end"));
ResourceKey<Level> overworld = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(levelNamespace, "overworld"));
return resourceKey == end ? overworld : end;
}
}
@@ -0,0 +1,51 @@
package com.nexia.uhc.mixin;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(Entity.class)
public abstract class EntityMixin {
@Shadow public Level level;
// Fix getting sent to the wrong nether in a dynamic world
@ModifyArg(method = "handleNetherPortal", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getLevel(Lnet/minecraft/resources/ResourceKey;)Lnet/minecraft/server/level/ServerLevel;"))
private ResourceKey<Level> handleDynamicNether(ResourceKey<Level> resourceKey) {
String levelNamespace = this.level.dimension().location().getNamespace();
ResourceKey<Level> nether = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(levelNamespace, "the_nether"));
ResourceKey<Level> overworld = ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(levelNamespace, "overworld"));
return this.level.dimension() == nether ? overworld : nether;
}
@Redirect(method = "changeDimension", at = @At(value = "FIELD", target = "Lnet/minecraft/world/level/Level;END:Lnet/minecraft/resources/ResourceKey;"))
private ResourceKey<Level> dynamicObsidianPlatform() {
String levelNamespace = this.level.dimension().location().getNamespace();
return ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(levelNamespace, "the_end"));
}
@Redirect(method = "findDimensionEntryPoint", at = @At(value = "FIELD", target = "Lnet/minecraft/world/level/Level;END:Lnet/minecraft/resources/ResourceKey;"))
private ResourceKey<Level> changeEnd() {
String levelNamespace = this.level.dimension().location().getNamespace();
return ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(levelNamespace, "the_end"));
}
@Redirect(method = "findDimensionEntryPoint", at = @At(value = "FIELD", target = "Lnet/minecraft/world/level/Level;NETHER:Lnet/minecraft/resources/ResourceKey;"))
private ResourceKey<Level> changeNether() {
String levelNamespace = this.level.dimension().location().getNamespace();
return ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(levelNamespace, "the_nether"));
}
@Redirect(method = "findDimensionEntryPoint", at = @At(value = "FIELD", target = "Lnet/minecraft/world/level/Level;OVERWORLD:Lnet/minecraft/resources/ResourceKey;"))
private ResourceKey<Level> changeOverworld() {
String levelNamespace = this.level.dimension().location().getNamespace();
return ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(levelNamespace, "overworld"));
}
}
@@ -0,0 +1,43 @@
package com.nexia.uhc.mixin;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemCooldowns;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(Player.class)
public abstract class PlayerMixin extends LivingEntity {
protected PlayerMixin(EntityType<? extends LivingEntity> entityType, Level level) {
super(entityType, level);
}
@Shadow public abstract ItemCooldowns getCooldowns();
/**
* @author NotCoded
* @reason Make shield break actually play the sound to other players.
*/
@Overwrite
public boolean disableShield(float f) {
this.getCooldowns().addCooldown(Items.SHIELD, (int)(f * 20.0F));
this.stopUsingItem();
this.level.broadcastEntityEvent(this, (byte)30);
if (this.getLastDamageSource().getEntity() instanceof ServerPlayer attacker) {
SoundSource soundSource = null;
for (SoundSource source : SoundSource.values()) {
soundSource = source;
}
this.level.playSound(null, new BlockPos(attacker.position()), SoundEvents.SHIELD_BREAK, soundSource, 2f, 1f);
}
return true;
}
}
@@ -0,0 +1,40 @@
package com.nexia.uhc.mixin;
import com.google.common.collect.Maps;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.levelgen.StructureSettings;
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
import net.minecraft.world.level.storage.WritableLevelData;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import java.util.Optional;
import java.util.function.Supplier;
@Mixin(ServerLevel.class)
public abstract class ServerLevelMixin extends Level {
@Shadow public abstract RegistryAccess registryAccess();
protected ServerLevelMixin(WritableLevelData writableLevelData, ResourceKey<Level> resourceKey, DimensionType dimensionType, Supplier<ProfilerFiller> supplier, boolean bl, boolean bl2, long l) {
super(writableLevelData, resourceKey, dimensionType, supplier, bl, bl2, l);
}
@ModifyArg(method = "<init>", index = 5, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;<init>(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;Lcom/mojang/datafixers/DataFixer;Lnet/minecraft/world/level/levelgen/structure/templatesystem/StructureManager;Ljava/util/concurrent/Executor;Lnet/minecraft/world/level/chunk/ChunkGenerator;IZLnet/minecraft/server/level/progress/ChunkProgressListener;Ljava/util/function/Supplier;)V"))
private ChunkGenerator makeOverworldVoid(ChunkGenerator chunkGenerator) {
if (this.dimension().equals(Level.OVERWORLD)) {
return new FlatLevelSource(new FlatLevelGeneratorSettings(new StructureSettings(Optional.empty(), Maps.newHashMap()), this.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)));
}
return chunkGenerator;
}
}
@@ -0,0 +1,17 @@
package com.nexia.uhc.utility;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.minimessage.MiniMessage;
public abstract class ChatFormat {
public static TextColor brandColor1 = TextColor.fromHexString("#a400fc");
public static TextColor brandColor2 = TextColor.fromHexString("#e700f0");
public static TextColor arrowColor = TextColor.fromHexString("#4a4a4a");
public static TextColor failColor = TextColor.fromHexString("#ff2b1c");
public static Component nexia = MiniMessage.get().parse(String.format("<bold><gradient:%s:%s>Nexia UHC</gradient></bold>", ChatFormat.brandColor1, ChatFormat.brandColor2));
public static Component nexiaIp = MiniMessage.get().parse(String.format("<bold><gradient:%s:%s>uhc.nexia.dev</gradient></bold>", ChatFormat.brandColor1, ChatFormat.brandColor2));
public static Component arrow = MiniMessage.get().parse(String.format(" <color:%s>»</color> ", ChatFormat.arrowColor));
public static Component nexiaMessage = nexia.append(arrow);
}
@@ -0,0 +1,18 @@
package com.nexia.uhc.utility;
import com.mojang.brigadier.CommandDispatcher;
import com.nexia.nexus.api.command.CommandSourceInfo;
import com.nexia.uhc.NexiaUHC;
import com.nexia.uhc.commands.GameCommand;
import com.nexia.uhc.commands.LobbyCommand;
import com.nexia.uhc.commands.SpectateCommand;
public class CommandLoader {
public static void registerCommands() {
CommandDispatcher<CommandSourceInfo> commandDispatcher = NexiaUHC.nexusServer.getCommandDispatcher();
new GameCommand().registerCommand(commandDispatcher);
new SpectateCommand().registerCommand(commandDispatcher);
new LobbyCommand().registerCommand(commandDispatcher);
}
}
@@ -0,0 +1,17 @@
package com.nexia.uhc.utility;
import com.nexia.uhc.listeners.*;
public abstract class ListenerLoader {
public static void registerListeners() {
new PlayerDamageListener().registerListener();
new PlayerDeathListener().registerListener();
new PlayerHungerListener().registerListener();
new PlayerInteractListener().registerListener();
new PlayerJoinListener().registerListener();
new PlayerLeaveListener().registerListener();
new PlayerMoveListener().registerListener();
new PlayerRespawnListener().registerListener();
new ServerEventsListener().registerListener();
}
}
@@ -0,0 +1,31 @@
package com.nexia.uhc.utility;
import net.minecraft.util.Mth;
import java.util.ArrayList;
import java.util.Random;
public abstract class MathUtil {
public static String convertTicksToTime(int ticks) {
int totalSeconds = ticks / 20;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
return String.format(
"%s:%s",
(minutes <= 9) ? "0" + minutes : minutes,
(seconds <= 9) ? "0" + seconds : seconds
);
}
public static ArrayList<int[]> createInitialPositions(Random random, int numberOfPositions, int lowerLimit, int upperLimit) {
ArrayList<int[]> positions = new ArrayList<>(numberOfPositions);
for(int j = 0; j < numberOfPositions; ++j) {
int[] ints = {Mth.nextInt(random, lowerLimit, upperLimit), Mth.nextInt(random, lowerLimit, upperLimit)};
positions.add(ints);
}
return positions;
}
}
+11 -9
View File
@@ -1,31 +1,33 @@
{
"schemaVersion": 1,
"id": "nexia-teams",
"id": "nexia-uhc",
"version": "${version}",
"name": "Nexia Teams",
"description": "The shitty thing",
"name": "Nexia UHC",
"description": "Official UHC Mod for Nexia.",
"authors": [
"NotCoded",
"NotInfinityy"
],
"contact": {
"repo": "https://github.com/nexia-cts/nexia-events"
},
"license": "All-Rights-Reserved",
"icon": "assets/nexia-teams/logo.png",
"accessWidener": "nexiateams.accesswidener",
"icon": "assets/nexia-uhc/logo.png",
"environment": "server",
"entrypoints": {
"main": [
"com.nexia.teams.NexiaTeams"
"com.nexia.uhc.NexiaUHC"
],
"nexus": [
"com.nexia.uhc.NexiaUHC"
]
},
"mixins": [
"nexiateams.mixins.json"
"nexiauhc.mixins.json"
],
"depends": {
"fabricloader": ">=${loader_version}",
"fabric": "*",
"minecraft": "~${minecraft_version}"
"minecraft": ["1.16.3-combat.8.c", "1.16.2-1.16.combat-6"],
"nexus-api": ">=${nexus_version}"
}
}
@@ -1,7 +0,0 @@
accessWidener v1 named
accessible field net/minecraft/world/damagesource/CombatTracker inCombat Z
accessible field net/minecraft/world/entity/projectile/LargeFireball explosionPower I
accessible method net/minecraft/world/entity/Display$BlockDisplay setBlockState (Lnet/minecraft/world/level/block/state/BlockState;)V
accessible method net/minecraft/world/entity/Display setTransformation (Lcom/mojang/math/Transformation;)V
accessible method net/minecraft/world/entity/LivingEntity dropExperience ()V
accessible method net/minecraft/world/entity/player/Player dropEquipment ()V
-19
View File
@@ -1,19 +0,0 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.nexia.teams.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
"AxeItemMixin",
"EnderPearlMixin",
"EndPortalBlockMixin",
"LargeFireballMixin",
"MinecraftServerMixin",
"NetherPortalBlockMixin",
"ServerGamePacketListenerMixin",
"mace.MaceItemMixin"
],
"injectors": {
"defaultRequire": 1
}
}
+16
View File
@@ -0,0 +1,16 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.nexia.uhc.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
"BaseFireBlockMixin",
"EndPortalBlockMixin",
"EntityMixin",
"PlayerMixin",
"ServerLevelMixin"
],
"injectors": {
"defaultRequire": 1
}
}