commit
7c9c5b8ab1
32 files changed
+1488
No files matched your search
@@ -0,0 +1,21 @@
|
||||
package ciomek.quetzal;
|
||||
|
||||
import ciomek.quetzal.teleport.TeleportRequest;
|
||||
import ciomek.quetzal.tick.TickTimer;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
import net.minecraft.core.world.World;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface IWorldUtils {
|
||||
void addTickCallback(int delayTicks, Consumer<World> callback);
|
||||
|
||||
void addRequestToTeleportTo(Player sender, Player receiver);
|
||||
void addRequestToTeleportFrom(Player sender, Player receiver);
|
||||
|
||||
List<TeleportRequest> getPendingRequests(Player receiver);
|
||||
TeleportRequest getNewestRequest(Player receiver);
|
||||
|
||||
TickTimer getTickTimer();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package ciomek.quetzal;
|
||||
|
||||
import ciomek.quetzal.commands.HomeCommand;
|
||||
import ciomek.quetzal.commands.TeleportAcceptCommand;
|
||||
import ciomek.quetzal.commands.TeleportCommand;
|
||||
import ciomek.quetzal.commands.TeleportDeclineCommand;
|
||||
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 static final String MOD_ID = "quetzal";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LOGGER.info("quetzal initialized.");
|
||||
|
||||
CommandManager.registerCommand(new TeleportCommand());
|
||||
CommandManager.registerCommand(new TeleportAcceptCommand());
|
||||
CommandManager.registerCommand(new TeleportDeclineCommand());
|
||||
CommandManager.registerCommand(new HomeCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecipesReady() {}
|
||||
|
||||
@Override
|
||||
public void initNamespaces() {}
|
||||
|
||||
@Override
|
||||
public void beforeGameStart() {}
|
||||
|
||||
@Override
|
||||
public void afterGameStart() {}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package ciomek.quetzal;
|
||||
|
||||
import ciomek.quetzal.tick.TickTimer;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
import net.minecraft.server.entity.player.PlayerServer;
|
||||
|
||||
public class Utils {
|
||||
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...");
|
||||
|
||||
timer.addTickTask(100, (world) -> {
|
||||
if (round1(fromPlayer.x) != startX || round1(fromPlayer.y) != startY || round1(fromPlayer.z) != startZ) {
|
||||
fromPlayer.sendMessage("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!");
|
||||
});
|
||||
}
|
||||
|
||||
private static double round1(double value) {
|
||||
return Math.round(value * 10.0) / 10.0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package ciomek.quetzal.commands;
|
||||
|
||||
import ciomek.quetzal.IWorldUtils;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilderLiteral;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
import net.minecraft.core.net.command.CommandManager;
|
||||
import net.minecraft.core.net.command.CommandSource;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.minecraft.server.entity.player.PlayerServer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
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");
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
loadHomes();
|
||||
}
|
||||
|
||||
private void loadHomes() {
|
||||
if (!homesFile.exists()) return;
|
||||
try (FileReader reader = new FileReader(homesFile)) {
|
||||
Type type = new TypeToken<Map<String, double[]>>(){}.getType();
|
||||
Map<String, double[]> loaded = gson.fromJson(reader, type);
|
||||
if (loaded != null) homes.putAll(loaded);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Failed to load homes: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void saveHomes() {
|
||||
try (FileWriter writer = new FileWriter(homesFile)) {
|
||||
gson.toJson(homes, writer);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Failed to save homes: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(CommandDispatcher<CommandSource> dispatcher) {
|
||||
dispatcher.register(
|
||||
ArgumentBuilderLiteral.<CommandSource>literal("sethome")
|
||||
.executes(context -> {
|
||||
CommandSource source = context.getSource();
|
||||
Player player = source.getSender();
|
||||
|
||||
if (player == null) {
|
||||
source.sendMessage("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.");
|
||||
return 1;
|
||||
})
|
||||
);
|
||||
|
||||
dispatcher.register(
|
||||
ArgumentBuilderLiteral.<CommandSource>literal("home")
|
||||
.executes(context -> {
|
||||
CommandSource source = context.getSource();
|
||||
Player player = source.getSender();
|
||||
|
||||
IWorldUtils worldUtils = (IWorldUtils) source.getWorld();
|
||||
|
||||
if (player == null) {
|
||||
source.sendMessage("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.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
double[] home = homes.get(player.username);
|
||||
|
||||
double startX = round1(player.x);
|
||||
double startY = round1(player.y);
|
||||
double startZ = round1(player.z);
|
||||
|
||||
player.sendMessage("Teleporting home. 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.");
|
||||
return;
|
||||
}
|
||||
|
||||
((PlayerServer)player).playerNetServerHandler.teleport(home[0], home[1], home[2]);
|
||||
player.sendMessage("Teleported home.");
|
||||
});
|
||||
|
||||
return 1;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private double round1(double value) {
|
||||
return Math.round(value * 10.0) / 10.0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package ciomek.quetzal.commands;
|
||||
|
||||
import ciomek.quetzal.IWorldUtils;
|
||||
import ciomek.quetzal.teleport.TeleportRequest;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilderLiteral;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
import net.minecraft.core.net.command.CommandManager;
|
||||
import net.minecraft.core.net.command.CommandSource;
|
||||
|
||||
import static com.mojang.brigadier.builder.ArgumentBuilderLiteral.literal;
|
||||
|
||||
public class TeleportAcceptCommand implements CommandManager.CommandRegistry {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void register(CommandDispatcher<CommandSource> commandDispatcher) {
|
||||
commandDispatcher
|
||||
.register(
|
||||
(ArgumentBuilderLiteral<CommandSource>) (Object) literal("tpa")
|
||||
.executes(context -> {
|
||||
CommandSource source = (CommandSource) context.getSource();
|
||||
Player player = source.getSender();
|
||||
|
||||
IWorldUtils worldUtils = (IWorldUtils) source.getWorld();
|
||||
|
||||
TeleportRequest tpr = worldUtils.getNewestRequest(player);
|
||||
|
||||
tpr.accept(worldUtils.getTickTimer());
|
||||
|
||||
return 1;
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package ciomek.quetzal.commands;
|
||||
|
||||
import ciomek.quetzal.IWorldUtils;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilderLiteral;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilderRequired;
|
||||
import net.minecraft.core.entity.Entity;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
import net.minecraft.core.net.command.CommandManager;
|
||||
import net.minecraft.core.net.command.CommandSource;
|
||||
import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
|
||||
import net.minecraft.core.net.command.helpers.EntitySelector;
|
||||
|
||||
import static com.mojang.brigadier.builder.ArgumentBuilderLiteral.literal;
|
||||
|
||||
public class TeleportCommand implements CommandManager.CommandRegistry {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void register(CommandDispatcher<CommandSource> commandDispatcher) {
|
||||
commandDispatcher
|
||||
.register(
|
||||
(ArgumentBuilderLiteral<CommandSource>) (Object) literal("tpr")
|
||||
.then(
|
||||
ArgumentBuilderRequired.argument("player", ArgumentTypeEntity.username())
|
||||
.executes(context -> {
|
||||
CommandSource source = (CommandSource) context.getSource();
|
||||
|
||||
EntitySelector entitySelector = context.getArgument("player", EntitySelector.class);
|
||||
|
||||
if (entitySelector.get(source).isEmpty()) {
|
||||
source.sendMessage("None selected!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Entity entity = entitySelector.get(source).get(0);
|
||||
Player target = (Player) entity;
|
||||
|
||||
Player player = source.getSender();
|
||||
IWorldUtils worldUtils = (IWorldUtils) source.getWorld();
|
||||
|
||||
if (player == null) {
|
||||
source.sendMessage("This command can only be run by a player!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
worldUtils.addRequestToTeleportTo(player, target);
|
||||
|
||||
player.sendMessage("Sent request to " + target.username + ".");
|
||||
|
||||
target.sendMessage("Do you want " + target.username + " to teleport to you?");
|
||||
return 1;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
commandDispatcher
|
||||
.register(
|
||||
(ArgumentBuilderLiteral<CommandSource>) (Object) literal("tpfr")
|
||||
.then(
|
||||
ArgumentBuilderRequired.argument("player", ArgumentTypeEntity.username())
|
||||
.executes(context -> {
|
||||
CommandSource source = (CommandSource) context.getSource();
|
||||
|
||||
EntitySelector entitySelector = context.getArgument("player", EntitySelector.class);
|
||||
|
||||
if (entitySelector.get(source).isEmpty()) {
|
||||
source.sendMessage("None selected!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Entity entity = entitySelector.get(source).get(0);
|
||||
Player target = (Player) entity;
|
||||
|
||||
Player player = source.getSender();
|
||||
IWorldUtils worldUtils = (IWorldUtils) source.getWorld();
|
||||
|
||||
if (player == null) {
|
||||
source.sendMessage("This command can only be run by a player!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
worldUtils.addRequestToTeleportFrom(player, target);
|
||||
|
||||
player.sendMessage("Sent request to " + target.username + ".");
|
||||
|
||||
target.sendMessage("Do you want to teleport to " + target.username + "?");
|
||||
return 1;
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package ciomek.quetzal.commands;
|
||||
|
||||
import ciomek.quetzal.IWorldUtils;
|
||||
import ciomek.quetzal.teleport.TeleportRequest;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilderLiteral;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
import net.minecraft.core.net.command.CommandManager;
|
||||
import net.minecraft.core.net.command.CommandSource;
|
||||
|
||||
import static com.mojang.brigadier.builder.ArgumentBuilderLiteral.literal;
|
||||
|
||||
public class TeleportDeclineCommand implements CommandManager.CommandRegistry {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void register(CommandDispatcher<CommandSource> commandDispatcher) {
|
||||
commandDispatcher
|
||||
.register(
|
||||
(ArgumentBuilderLiteral<CommandSource>) (Object) literal("tpd")
|
||||
.executes(context -> {
|
||||
CommandSource source = (CommandSource) context.getSource();
|
||||
Player player = source.getSender();
|
||||
|
||||
IWorldUtils worldUtils = (IWorldUtils) source.getWorld();
|
||||
|
||||
TeleportRequest tpr = worldUtils.getNewestRequest(player);
|
||||
|
||||
tpr.decline();
|
||||
|
||||
return 1;
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package ciomek.quetzal.mixin;
|
||||
|
||||
import ciomek.quetzal.IWorldUtils;
|
||||
import ciomek.quetzal.teleport.TeleportRequest;
|
||||
import ciomek.quetzal.teleport.TeleportToRequest;
|
||||
import ciomek.quetzal.tick.TickTimer;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
import net.minecraft.core.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mixin(value = World.class, remap = false)
|
||||
public class WorldOverwriteMixin implements IWorldUtils {
|
||||
@Unique
|
||||
private final TickTimer tickTimer = new TickTimer();
|
||||
|
||||
@Unique
|
||||
private final List<TeleportRequest> teleportRequests = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public TickTimer getTickTimer()
|
||||
{
|
||||
return tickTimer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTickCallback(int delayTicks, Consumer<World> callback) {
|
||||
tickTimer.addTickTask(delayTicks, callback);
|
||||
}
|
||||
|
||||
@Inject(method = "tick", at = @At(value = "TAIL"))
|
||||
public void tick(CallbackInfo ci) {
|
||||
tickTimer.tick((World) (Object) this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequestToTeleportTo(Player sender, Player receiver) {
|
||||
TeleportRequest tpr = new TeleportToRequest(sender, receiver, LocalDate.now());
|
||||
|
||||
teleportRequests.add(tpr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRequestToTeleportFrom(Player sender, Player receiver) {
|
||||
TeleportRequest tpr = new TeleportToRequest(sender, receiver, LocalDate.now());
|
||||
|
||||
teleportRequests.add(tpr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeleportRequest getNewestRequest(Player receiver)
|
||||
{
|
||||
return teleportRequests.stream()
|
||||
.filter(tr -> Objects.equals(tr.receiver, receiver))
|
||||
.max(Comparator.comparing(tr -> tr.sentAt))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TeleportRequest> getPendingRequests(Player receiver) {
|
||||
return teleportRequests.stream()
|
||||
.filter(tr -> Objects.equals(tr.receiver, receiver))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package ciomek.quetzal.teleport;
|
||||
|
||||
import ciomek.quetzal.Utils;
|
||||
import ciomek.quetzal.tick.TickTimer;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class TeleportFromRequest extends TeleportRequest {
|
||||
public TeleportFromRequest(Player sender, Player receiver, LocalDate sentAt) {
|
||||
super(sender, receiver, sentAt);
|
||||
}
|
||||
|
||||
public void accept(TickTimer timer)
|
||||
{
|
||||
sender.sendMessage(receiver.username + " has accepted the teleportation request. ");
|
||||
Utils.TeleportPlayer(receiver, sender, timer);
|
||||
}
|
||||
|
||||
public void decline()
|
||||
{
|
||||
sender.sendMessage(receiver.username + " has declined the teleportation request. ");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package ciomek.quetzal.teleport;
|
||||
|
||||
import ciomek.quetzal.tick.TickTimer;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
public abstract class TeleportRequest {
|
||||
public Player sender;
|
||||
public Player receiver;
|
||||
|
||||
public LocalDate sentAt;
|
||||
|
||||
public TeleportRequest(Player sender, Player receiver, LocalDate sentAt) {
|
||||
this.sender = sender;
|
||||
this.receiver = receiver;
|
||||
|
||||
this.sentAt = sentAt;
|
||||
}
|
||||
|
||||
public abstract void accept(TickTimer timer);
|
||||
|
||||
public abstract void decline();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package ciomek.quetzal.teleport;
|
||||
|
||||
import ciomek.quetzal.Utils;
|
||||
import ciomek.quetzal.tick.TickTimer;
|
||||
import net.minecraft.core.entity.player.Player;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class TeleportToRequest extends TeleportRequest {
|
||||
public TeleportToRequest(Player sender, Player receiver, LocalDate sentAt) {
|
||||
super(sender, receiver, sentAt);
|
||||
}
|
||||
|
||||
public void accept(TickTimer timer)
|
||||
{
|
||||
sender.sendMessage(receiver.username + " has accepted the teleportation request. ");
|
||||
Utils.TeleportPlayer(sender, receiver, timer);
|
||||
}
|
||||
|
||||
public void decline()
|
||||
{
|
||||
sender.sendMessage(receiver.username + " has declined the teleportation request. ");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package ciomek.quetzal.tick;
|
||||
|
||||
import net.minecraft.core.world.World;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TickTask {
|
||||
public int ticksLeft;
|
||||
public Consumer<World> callback;
|
||||
|
||||
public TickTask(int ticksLeft, Consumer<World> callback) {
|
||||
this.ticksLeft = ticksLeft;
|
||||
this.callback = callback;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package ciomek.quetzal.tick;
|
||||
|
||||
import net.minecraft.core.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TickTimer {
|
||||
|
||||
private final List<TickTask> tickTasks = new ArrayList<>();
|
||||
|
||||
public void addTickTask(int delayTicks, Consumer<World> callback) {
|
||||
tickTasks.add(new TickTask(delayTicks, callback));
|
||||
}
|
||||
|
||||
public void tick(World world) {
|
||||
Iterator<TickTask> iterator = tickTasks.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
TickTask task = iterator.next();
|
||||
|
||||
task.ticksLeft--;
|
||||
|
||||
if (task.ticksLeft <= 0) {
|
||||
task.callback.accept(world);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "quetzal",
|
||||
"version": "${version}",
|
||||
"name": "Quetzal",
|
||||
"description": "Basic stuff for servers.",
|
||||
"authors": [
|
||||
"ciomek"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "",
|
||||
"sources": ""
|
||||
},
|
||||
"icon": "icon.png",
|
||||
"license": "CC0-1.0",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"ciomek.quetzal.Quetzal"
|
||||
],
|
||||
"beforeGameStart": [
|
||||
"ciomek.quetzal.Quetzal"
|
||||
],
|
||||
"afterGameStart": [
|
||||
"ciomek.quetzal.Quetzal"
|
||||
],
|
||||
"recipesReady": [
|
||||
"ciomek.quetzal.Quetzal"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"quetzal.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=${fabricloader}",
|
||||
"halplibe": ">=${halplibe}",
|
||||
"minecraft": "*",
|
||||
"java": ">=${java}"
|
||||
},
|
||||
"suggests": {
|
||||
"modmenu": ">=${modmenu}"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
Whitespace-only changes.
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "ciomek.quetzal.mixin",
|
||||
"compatibilityLevel": "JAVA_${java}",
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
"mixins": [
|
||||
"WorldOverwriteMixin"
|
||||
],
|
||||
"client": []
|
||||
}
|
||||
Reference in new issue
Block a user