Compare commits

...
8 Commits
Author SHA1 Message Date
ciomek cdf6116fac Version bump
build / build (push) Successful in 3m9s
2026-07-25 10:54:03 +02:00
ciomek 9de33dc984 Version bump
build / build (push) Successful in 3m16s
2026-07-25 10:51:48 +02:00
ciomek e4847c9084 Version bump
build / build (push) Failing after 1m28s
2026-07-25 10:50:49 +02:00
ciomek 60491cb591 Version bump
build / build (push) Successful in 3m0s
2026-07-25 10:43:41 +02:00
ciomek 2e47df4375 Version bump
build / build (push) Successful in 5m37s
2026-07-25 10:32:35 +02:00
ciomek 5350242f97 Fixes and colors
build / build (push) Successful in 7m0s
2026-06-24 18:44:00 +02:00
ciomek 3619df118b Refactor
build / build (push) Successful in 3m43s
2026-03-16 21:02:06 +01:00
ciomek 6e86c47bbb Better conf dir 2026-03-16 20:57:15 +01:00
10 changed files with 143 additions and 122 deletions

No files matched your search

+72 -40
View File
@@ -1,10 +1,11 @@
import com.smushytaco.lwjgl_gradle.Preset
plugins {
alias(libs.plugins.loom)
alias(libs.plugins.lwjgl)
java
}
val modVersion: Provider<String> = providers.gradleProperty("mod_version")
val lwjglNatives = resolveLwjglNatives()
val modVersion = "${providers.gradleProperty("mod_version").get()}+${libs.versions.bta.get()}"
val modGroup: Provider<String> = providers.gradleProperty("mod_group")
val modName: Provider<String> = providers.gradleProperty("mod_name")
@@ -12,56 +13,48 @@ val javaVersion: Provider<Int> = libs.versions.java.map { it.toInt() }
base.archivesName = modName
group = modGroup.get()
version = modVersion.get()
version = modVersion
loom {
customMinecraftMetadata.set("https://downloads.betterthanadventure.net/bta-client/${libs.versions.btaChannel.get()}/v${libs.versions.bta.get()}/manifest.json")
val btaChannel = libs.versions.btaChannel.get()
val btaVersion = (if (btaChannel == "nightly") "" else "v") + libs.versions.bta.get()
customMinecraftMetadata.set("https://downloads.betterthanadventure.net/bta-client/${btaChannel}/$btaVersion/manifest.json")
}
repositories {
mavenCentral()
maven("https://maven.fabricmc.net/") { name = "Fabric" }
maven("https://maven.thesignalumproject.net/infrastructure") { name = "SignalumMavenInfrastructure" }
maven("https://maven.thesignalumproject.net/releases") { name = "SignalumMavenReleases" }
ivy("https://github.com/Better-than-Adventure") {
patternLayout { artifact("[organisation]/releases/download/[revision]/[module]-bta-[revision].jar") }
metadataSources { artifact() }
}
ivy("https://downloads.betterthanadventure.net/bta-client/${libs.versions.btaChannel.get()}/") {
patternLayout { artifact("/v[revision]/client.jar") }
metadataSources { artifact() }
}
ivy("https://downloads.betterthanadventure.net/bta-server/${libs.versions.btaChannel.get()}/") {
patternLayout { artifact("/v[revision]/server.jar") }
metadataSources { artifact() }
}
maven("https://maven.thesignalumproject.net/nightly") { name = "SignalumMavenNightly" }
ivy("https://piston-data.mojang.com") {
patternLayout { artifact("v1/[organisation]/[revision]/[module].jar") }
metadataSources { artifact() }
}
}
lwjgl {
version = libs.versions.lwjgl
implementation(Preset.MINIMAL_OPENGL)
}
dependencies {
minecraft("::${libs.versions.bta.get()}")
runtimeOnly(libs.clientJar)
// Required at compilation & runtime
// included in builds as a runtime dependency
implementation(libs.loader)
// If you do not need Halplibe you can comment out or delete this line.
implementation(libs.halplibe)
implementation(libs.modMenu)
implementation(libs.legacyLwjgl)
implementation(libs.halplibe) // If you do not need halplibe you can delete this line
implementation(libs.slf4jApi)
implementation(libs.guava)
implementation(libs.log4j.slf4j2.impl)
implementation(libs.log4j.core)
implementation(libs.log4j.api)
implementation(libs.log4j.api12)
implementation(libs.gson)
// Only required at compilation
// provides documentation, can be removed if that isn't needed
compileOnly(libs.bundles.btaLwjgl)
compileOnly(libs.joml)
compileOnly(libs.joml.primitives)
compileOnly(libs.slf4jApi)
implementation(libs.commonsLang3)
include(libs.commonsLang3)
// Only required for development/launch at runtime, won't be part of any builds
localRuntime(libs.modMenu) // Optional, can be removed
runtimeClasspath(libs.clientJar)
val lwjglVer = libs.versions.lwjgl.get()
localRuntime(platform("org.lwjgl:lwjgl-bom:${lwjglVer}"))
localRuntime("org.lwjgl:lwjgl::$lwjglNatives")
localRuntime("org.lwjgl:lwjgl-glfw::$lwjglNatives")
localRuntime("org.lwjgl:lwjgl-openal::$lwjglNatives")
localRuntime("org.lwjgl:lwjgl-opengl::$lwjglNatives")
localRuntime("org.lwjgl:lwjgl-stb::$lwjglNatives")
}
java {
toolchain {
@@ -113,16 +106,55 @@ tasks {
}
processResources {
val resourceMap = mapOf(
"version" to modVersion.get(),
"version" to modVersion,
"fabricloader" to libs.versions.loader.get(),
"halplibe" to libs.versions.halplibe.get(),
"java" to libs.versions.java.get(),
"modmenu" to libs.versions.modMenu.get()
)
// This is needed for gradle to recognize changes
// made to expanded files
inputs.properties(resourceMap)
filesMatching("fabric.mod.json") { expand(resourceMap) }
filesMatching("**/*.mixins.json") { expand(resourceMap.filterKeys { it == "java" }) }
duplicatesStrategy = DuplicatesStrategy.INCLUDE
with(copySpec {
from("src/main/resources/") {
include("fabric.mod.json")
include("*.mixins.json")
expand(resourceMap)
}
})
}
}
// Removes all outdated manifest.json dependencies
configurations.configureEach {
exclude(group = "org.lwjgl.lwjgl")
exclude(group = "net.java.jutils")
exclude(group = "net.java.jinput")
exclude(group = "net.sf.jopt-simple")
exclude(group = "net.minecraft", module = "launchwrapper")
}
fun resolveLwjglNatives(): String { // Sourced from https://www.lwjgl.org/
return Pair(
System.getProperty("os.name")!!,
System.getProperty("os.arch")!!
).let { (name, arch) ->
when {
arrayOf("Linux", "SunOS", "Unit").any { name.startsWith(it) } ->
if (arrayOf("arm", "aarch64").any { arch.startsWith(it) })
"natives-linux${if (arch.contains("64") || arch.startsWith("armv8")) "-arm64" else "-arm32"}"
else
"natives-linux"
arrayOf("Mac OS X", "Darwin").any { name.startsWith(it) } ->
"natives-macos${if (arch.startsWith("aarch64")) "-arm64" else ""}"
arrayOf("Windows").any { name.startsWith(it) } ->
if (arch.contains("64"))
"natives-windows${if (arch.startsWith("aarch64")) "-arm64" else ""}"
else
"natives-windows-x86"
else ->
throw Error("Unrecognized or unsupported platform. Please set \"lwjglNatives\" manually")
}
}
}
// Removes LWJGL2 dependencies
configurations.configureEach { exclude(group = "org.lwjgl.lwjgl") }
+1 -1
View File
@@ -8,7 +8,7 @@ org.gradle.warning.mode = all
org.gradle.configuration-cache = false
##########################################################################
# Mod Properties
mod_version = 0.1.0
mod_version = 0.1.1
mod_group = ciomek
mod_name = quetzal
##########################################################################
+20 -24
View File
@@ -3,60 +3,56 @@
# Plugins
# Check this on https://github.com/FabricMC/fabric-loom/releases/latest/
loom = "1.15-SNAPSHOT"
# Check this on https://plugins.gradle.org/plugin/com.smushytaco.lwjgl3/
lwjglPlugin = "1.0.2"
##########################################################################
# Java Configuration
# The Java version the JDK will be for compiling and running code.
java = "8"
java = "17"
# The Java version the JDK will be for running Gradle.
gradleJava = "21"
##########################################################################
# Mod Dependencies
# Check this on https://downloads.betterthanadventure.net/bta-client/
bta = "7.3_04"
bta = "8.0"
# Options are release, prerelease, nightly, and misc.
btaChannel = "release"
# Check this on https://maven.thesignalumproject.net/#/infrastructure/net/fabricmc/fabric-loader/
loader = "0.18.4-bta.10"
loader = "0.18.4-bta.11"
# Check this on https://github.com/Turnip-Labs/ModMenu/releases/latest/
modMenu = "4.0.0"
modMenu = "5.0.2"
# Check this on https://github.com/Turnip-Labs/bta-halplibe/releases/latest/
halplibe = "5.4.0"
halplibe = "6.1.3+8.0"
# Check this on https://github.com/Better-than-Adventure/legacy-lwjgl3/releases/latest/
legacyLwjgl = "1.0.6"
##########################################################################
# Dependencies
# Check this on https://central.sonatype.com/artifact/org.slf4j/slf4j-api/
slf4jApi = "2.0.17"
# Check this on https://central.sonatype.com/artifact/com.google.guava/guava/
guava = "33.5.0-jre"
# Check this on https://central.sonatype.com/artifact/org.apache.logging.log4j/log4j-api/
log4j = "2.20.0"
# Check this on https://central.sonatype.com/artifact/com.google.code.gson/gson/
gson = "2.13.2"
# Check this on https://central.sonatype.com/artifact/org.apache.commons/commons-lang3/
commonsLang3 = "3.20.0"
# This should match the version used by the current BTA release.
lwjgl = "3.3.3"
joml = "1.10.8" # Note: BTA uses 1.10.7, patch 8 removes the kotlin stdlib dependency
jomlPrimitivess = "1.10.0"
##########################################################################
[libraries]
loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "loader" }
halplibe = { group = "turniplabs", name = "halplibe", version.ref = "halplibe" }
modMenu = { group = "turniplabs", name = "modmenu-bta", version.ref = "modMenu" }
legacyLwjgl = { group = "legacy-lwjgl3", name = "legacy-lwjgl3", version.ref = "legacyLwjgl" }
legacyLwjgl = { group = "com.github.Better-than-Adventure", name = "legacy-lwjgl3", version.ref = "legacyLwjgl" }
slf4jApi = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4jApi" }
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
log4j-slf4j2-impl = { group = "org.apache.logging.log4j", name = "log4j-slf4j2-impl", version.ref = "log4j" }
log4j-core = { group = "org.apache.logging.log4j", name = "log4j-core", version.ref = "log4j" }
log4j-api = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j" }
log4j-api12 = { group = "org.apache.logging.log4j", name = "log4j-1.2-api", version.ref = "log4j" }
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
commonsLang3 = { group = "org.apache.commons", name = "commons-lang3", version.ref = "commonsLang3" }
# https://piston-data.mojang.com/v1/objects/43db9b498cb67058d2e12d394e6507722e71bb45/client.jar
clientJar = { group = "objects", name = "client", version = "43db9b498cb67058d2e12d394e6507722e71bb45" }
joml = { group = "org.joml", name = "joml", version.ref = "joml" }
joml-primitives = { group = "org.joml", name = "joml-primitives", version.ref = "jomlPrimitivess" }
lwjgl = { group = "org.lwjgl", name = "lwjgl", version.ref = "lwjgl"}
lwjgl-glfw = { group = "org.lwjgl", name = "lwjgl-glfw", version.ref = "lwjgl"}
lwjgl-openal = { group = "org.lwjgl", name = "lwjgl-openal", version.ref = "lwjgl"}
lwjgl-opengl = { group = "org.lwjgl", name = "lwjgl-opengl", version.ref = "lwjgl"}
lwjgl-stb = { group = "org.lwjgl", name = "lwjgl-stb", version.ref = "lwjgl"}
[bundles]
btaLwjgl = [ "lwjgl", "lwjgl-glfw", "lwjgl-openal", "lwjgl-opengl", "lwjgl-stb", "legacyLwjgl" ]
[plugins]
loom = { id = "net.fabricmc.fabric-loom", version.ref = "loom" }
lwjgl = { id = "com.smushytaco.lwjgl3", version.ref = "lwjglPlugin" }
+1 -15
View File
@@ -8,10 +8,8 @@ import net.fabricmc.api.ModInitializer;
import net.minecraft.core.net.command.CommandManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import turniplabs.halplibe.util.GameStartEntrypoint;
import turniplabs.halplibe.util.RecipeEntrypoint;
public class Quetzal implements ModInitializer, RecipeEntrypoint, GameStartEntrypoint {
public class Quetzal implements ModInitializer {
public static final String MOD_ID = "quetzal";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
@@ -24,16 +22,4 @@ public class Quetzal implements ModInitializer, RecipeEntrypoint, GameStartEntry
CommandManager.registerCommand(new TeleportDeclineCommand());
CommandManager.registerCommand(new HomeCommand());
}
@Override
public void onRecipesReady() {}
@Override
public void initNamespaces() {}
@Override
public void beforeGameStart() {}
@Override
public void afterGameStart() {}
}
+21 -5
View File
@@ -5,28 +5,44 @@ import net.minecraft.core.entity.player.Player;
import net.minecraft.server.entity.player.PlayerServer;
public class Utils {
public static String msg(String body) {
return "§6[Quetzal]§r " + body;
}
public static String highlight(String text) {
return "§e" + text + "§r";
}
public static String success(String text) {
return "§a" + text + "§r";
}
public static String error(String text) {
return "§c" + text + "§r";
}
public static void TeleportPlayer(Player fromPlayer, Player toPlayer, TickTimer timer)
{
double startX = round1(fromPlayer.x);
double startY = round1(fromPlayer.y);
double startZ = round1(fromPlayer.z);
fromPlayer.sendMessage("Teleporting home. Don't move for 5 seconds...");
fromPlayer.sendMessage(msg("Teleporting to " + highlight(toPlayer.username) + ". " + error("Don't move for 5 seconds...")));
timer.addTickTask(100, (world) -> {
if (round1(fromPlayer.x) != startX || round1(fromPlayer.y) != startY || round1(fromPlayer.z) != startZ) {
fromPlayer.sendMessage("Teleport cancelled because you moved.");
fromPlayer.sendMessage(msg(error("Teleport cancelled") + " because you moved."));
return;
}
((PlayerServer)fromPlayer).playerNetServerHandler.teleportAndRotate(toPlayer.x, toPlayer.y, toPlayer.z, toPlayer.yRot, toPlayer.xRot);
fromPlayer.sendMessage("Teleported to " + toPlayer.username + "!");
toPlayer.sendMessage(fromPlayer.username + " teleported to you!");
fromPlayer.sendMessage(msg(success("Teleported") + " to " + highlight(toPlayer.username) + "!"));
toPlayer.sendMessage(msg(highlight(fromPlayer.username) + " teleported to you!"));
});
}
private static double round1(double value) {
public static double round1(double value) {
return Math.round(value * 10.0) / 10.0;
}
}
@@ -1,10 +1,12 @@
package ciomek.quetzal.commands;
import ciomek.quetzal.IWorldUtils;
import ciomek.quetzal.Utils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.ArgumentBuilderLiteral;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.core.entity.player.Player;
import net.minecraft.core.net.command.CommandManager;
import net.minecraft.core.net.command.CommandSource;
@@ -22,7 +24,8 @@ import java.util.Map;
public class HomeCommand implements CommandManager.CommandRegistry, ModInitializer {
private static final Map<String, double[]> homes = new HashMap<>();
private static final Gson gson = new Gson();
private static final File homesFile = new File("homes.json");
private static final File homesFile =
new File(FabricLoader.getInstance().getConfigDir().toFile(), "homes.json");
@Override
public void onInitialize() {
@@ -57,13 +60,13 @@ public class HomeCommand implements CommandManager.CommandRegistry, ModInitializ
Player player = source.getSender();
if (player == null) {
source.sendMessage("This command can only be run by a player!");
source.sendMessage(Utils.msg(Utils.error("This command can only be run by a player!")));
return 0;
}
homes.put(player.username, new double[]{player.x, player.y, player.z});
saveHomes();
player.sendMessage("Home set.");
player.sendMessage(Utils.msg(Utils.success("Home set.")));
return 1;
})
);
@@ -77,41 +80,37 @@ public class HomeCommand implements CommandManager.CommandRegistry, ModInitializ
IWorldUtils worldUtils = (IWorldUtils) source.getWorld();
if (player == null) {
source.sendMessage("This command can only be run by a player!");
source.sendMessage(Utils.msg(Utils.error("This command can only be run by a player!")));
return 0;
}
if (!homes.containsKey(player.username)) {
homes.put(player.username, new double[]{player.x, player.y, player.z});
saveHomes();
player.sendMessage("Home was not set. Setting it to your current location.");
player.sendMessage(Utils.msg(Utils.highlight("Home") + " was not set. Setting it to your " + Utils.highlight("current location") + "."));
return 1;
}
double[] home = homes.get(player.username);
double startX = round1(player.x);
double startY = round1(player.y);
double startZ = round1(player.z);
double startX = Utils.round1(player.x);
double startY = Utils.round1(player.y);
double startZ = Utils.round1(player.z);
player.sendMessage("Teleporting home. Don't move for 5 seconds...");
player.sendMessage(Utils.msg("Teleporting " + Utils.highlight("home") + ". " + Utils.error("Don't move for 5 seconds...")));
worldUtils.addTickCallback(100, (w) -> {
if (round1(player.x) != startX || round1(player.y) != startY || round1(player.z) != startZ) {
player.sendMessage("Teleport cancelled because you moved.");
if (Utils.round1(player.x) != startX || Utils.round1(player.y) != startY || Utils.round1(player.z) != startZ) {
player.sendMessage(Utils.msg(Utils.error("Teleport cancelled") + " because you moved."));
return;
}
((PlayerServer)player).playerNetServerHandler.teleport(home[0], home[1], home[2]);
player.sendMessage("Teleported home.");
player.sendMessage(Utils.msg(Utils.success("Teleported home.")));
});
return 1;
})
);
}
private double round1(double value) {
return Math.round(value * 10.0) / 10.0;
}
}
@@ -1,6 +1,7 @@
package ciomek.quetzal.commands;
import ciomek.quetzal.IWorldUtils;
import ciomek.quetzal.Utils;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.ArgumentBuilderLiteral;
import com.mojang.brigadier.builder.ArgumentBuilderRequired;
@@ -28,7 +29,7 @@ public class TeleportCommand implements CommandManager.CommandRegistry {
EntitySelector entitySelector = context.getArgument("player", EntitySelector.class);
if (entitySelector.get(source).isEmpty()) {
source.sendMessage("None selected!");
source.sendMessage(Utils.msg(Utils.error("None selected!")));
return 0;
}
@@ -39,15 +40,15 @@ public class TeleportCommand implements CommandManager.CommandRegistry {
IWorldUtils worldUtils = (IWorldUtils) source.getWorld();
if (player == null) {
source.sendMessage("This command can only be run by a player!");
source.sendMessage(Utils.msg(Utils.error("This command can only be run by a player!")));
return 0;
}
worldUtils.addRequestToTeleportTo(player, target);
player.sendMessage("Sent request to " + target.username + ".");
player.sendMessage(Utils.msg("Sent request to " + Utils.highlight(target.username) + "."));
target.sendMessage("Do you want " + target.username + " to teleport to you?");
target.sendMessage(Utils.msg("Do you want " + Utils.highlight(player.username) + " to teleport to you?"));
return 1;
})
)
@@ -64,7 +65,7 @@ public class TeleportCommand implements CommandManager.CommandRegistry {
EntitySelector entitySelector = context.getArgument("player", EntitySelector.class);
if (entitySelector.get(source).isEmpty()) {
source.sendMessage("None selected!");
source.sendMessage(Utils.msg(Utils.error("None selected!")));
return 0;
}
@@ -75,15 +76,15 @@ public class TeleportCommand implements CommandManager.CommandRegistry {
IWorldUtils worldUtils = (IWorldUtils) source.getWorld();
if (player == null) {
source.sendMessage("This command can only be run by a player!");
source.sendMessage(Utils.msg(Utils.error("This command can only be run by a player!")));
return 0;
}
worldUtils.addRequestToTeleportFrom(player, target);
player.sendMessage("Sent request to " + target.username + ".");
player.sendMessage(Utils.msg("Sent request to " + Utils.highlight(target.username) + "."));
target.sendMessage("Do you want to teleport to " + target.username + "?");
target.sendMessage(Utils.msg("Do you want " + Utils.highlight(player.username) + " to teleport to you?"));
return 1;
})
)
@@ -13,12 +13,12 @@ public class TeleportFromRequest extends TeleportRequest {
public void accept(TickTimer timer)
{
sender.sendMessage(receiver.username + " has accepted the teleportation request. ");
sender.sendMessage(Utils.msg(Utils.highlight(receiver.username) + " has " + Utils.success("accepted") + " the teleportation request."));
Utils.TeleportPlayer(receiver, sender, timer);
}
public void decline()
{
sender.sendMessage(receiver.username + " has declined the teleportation request. ");
sender.sendMessage(Utils.msg(Utils.highlight(receiver.username) + " has " + Utils.error("declined") + " the teleportation request."));
}
}
@@ -13,12 +13,12 @@ public class TeleportToRequest extends TeleportRequest {
public void accept(TickTimer timer)
{
sender.sendMessage(receiver.username + " has accepted the teleportation request. ");
sender.sendMessage(Utils.msg(Utils.highlight(receiver.username) + " has " + Utils.success("accepted") + " the teleportation request."));
Utils.TeleportPlayer(sender, receiver, timer);
}
public void decline()
{
sender.sendMessage(receiver.username + " has declined the teleportation request. ");
sender.sendMessage(Utils.msg(Utils.highlight(receiver.username) + " has " + Utils.error("declined") + " the teleportation request."));
}
}
-9
View File
@@ -17,15 +17,6 @@
"entrypoints": {
"main": [
"ciomek.quetzal.Quetzal"
],
"beforeGameStart": [
"ciomek.quetzal.Quetzal"
],
"afterGameStart": [
"ciomek.quetzal.Quetzal"
],
"recipesReady": [
"ciomek.quetzal.Quetzal"
]
},
"mixins": [