mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 23:27:59 +01:00
Added /trait
This commit is contained in:
parent
3cec6de107
commit
de6f9a92d4
6 changed files with 232 additions and 49 deletions
|
@ -3,19 +3,19 @@ package com.minelittlepony.unicopia.command;
|
|||
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.command.argument.ArgumentTypes;
|
||||
import net.minecraft.command.argument.serialize.ConstantArgumentSerializer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class Commands {
|
||||
@SuppressWarnings({ "deprecation", "unchecked", "rawtypes" })
|
||||
public static void bootstrap() {
|
||||
ArgumentTypes.register("unicopia:race", RaceArgument.class, new ConstantArgumentSerializer<>(RaceArgument::new));
|
||||
ArgumentTypes.register("unicopia:enumeration", EnumArgumentType.class, new EnumArgumentType.Serializer());
|
||||
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> {
|
||||
SpeciesCommand.register(dispatcher);
|
||||
RacelistCommand.register(dispatcher);
|
||||
GravityCommand.register(dispatcher);
|
||||
DisguiseCommand.register(dispatcher);
|
||||
TraitCommand.register(dispatcher);
|
||||
});
|
||||
@SuppressWarnings("deprecation")
|
||||
Object game = FabricLoader.getInstance().getGameInstance();
|
||||
if (game instanceof MinecraftServer) {
|
||||
((MinecraftServer)game).setFlightEnabled(true);
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
package com.minelittlepony.unicopia.command;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
import net.minecraft.command.argument.serialize.ArgumentSerializer;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
class EnumArgumentType<T extends Enum<T>> implements ArgumentType<T>, Serializable {
|
||||
private static final long serialVersionUID = 3731493854867412243L;
|
||||
|
||||
private static final EnumArgumentType<Race> RACE = of(Race.class, Race::isUsable, Race.EARTH);
|
||||
|
||||
public static EnumArgumentType<Race> race() {
|
||||
return RACE;
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumArgumentType<T> of(Class<T> type, Predicate<T> filter, T def) {
|
||||
return new EnumArgumentType<>(type, filter, def);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumArgumentType<T> of(Class<T> type, T def) {
|
||||
return new EnumArgumentType<>(type, s -> true, def);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> EnumArgumentType<T> of(Class<T> type) {
|
||||
return new EnumArgumentType<>(type, s -> true, null);
|
||||
}
|
||||
|
||||
private final T def;
|
||||
private final T[] values;
|
||||
private final List<String> suggestions;
|
||||
|
||||
private EnumArgumentType(Class<T> type, Predicate<T> filter, T def) {
|
||||
this.def = def;
|
||||
values = type.getEnumConstants();
|
||||
suggestions = Arrays.stream(values).filter(filter).map(T::name).toList();
|
||||
}
|
||||
|
||||
private EnumArgumentType(List<String> suggestions, T[] values, T def) {
|
||||
this.suggestions = suggestions;
|
||||
this.values = values;
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parse(StringReader reader) throws CommandSyntaxException {
|
||||
return fromName(reader.readUnquotedString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
|
||||
suggestions.stream()
|
||||
.filter(i -> i.toLowerCase().startsWith(builder.getRemaining().toLowerCase()))
|
||||
.forEach(builder::suggest);
|
||||
|
||||
return builder.buildFuture();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unlikely-arg-type")
|
||||
private T fromName(String s) {
|
||||
if (!Strings.isNullOrEmpty(s)) {
|
||||
for (T i : values) {
|
||||
if (i.equals(s) || i.name().equalsIgnoreCase(s)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
int ordinal = Integer.parseInt(s);
|
||||
if (ordinal >= 0 && ordinal < values.length) {
|
||||
return values[ordinal];
|
||||
}
|
||||
} catch (NumberFormatException e) { }
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getExamples() {
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
public static class Serializer<T extends Enum<T>> implements ArgumentSerializer<EnumArgumentType<T>> {
|
||||
@Override
|
||||
public void toPacket(EnumArgumentType<T> type, PacketByteBuf buf) {
|
||||
try (ObjectOutputStream stream = new ObjectOutputStream(new ByteBufOutputStream(buf))) {
|
||||
stream.writeObject(type);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public EnumArgumentType<T> fromPacket(PacketByteBuf buf) {
|
||||
try (ObjectInputStream stream = new ObjectInputStream(new ByteBufInputStream(buf))) {
|
||||
return (EnumArgumentType<T>)stream.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toJson(EnumArgumentType<T> type, JsonObject json) { }
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package com.minelittlepony.unicopia.command;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
class RaceArgument implements ArgumentType<Race> {
|
||||
static final Collection<String> EXAMPLES = Arrays.stream(Race.values())
|
||||
.filter(Race::isUsable)
|
||||
.map(Race::name)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@Override
|
||||
public Race parse(StringReader reader) throws CommandSyntaxException {
|
||||
return Race.fromName(reader.readUnquotedString(), Race.EARTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
|
||||
Arrays.stream(Race.values())
|
||||
.filter(Race::isUsable)
|
||||
.map(i -> i.name().toLowerCase())
|
||||
.filter(i -> i.startsWith(builder.getRemaining().toLowerCase()))
|
||||
.forEach(i -> builder.suggest(i.toLowerCase()));
|
||||
|
||||
return builder.buildFuture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getExamples() {
|
||||
return EXAMPLES;
|
||||
}
|
||||
}
|
|
@ -19,8 +19,10 @@ class RacelistCommand {
|
|||
static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
|
||||
LiteralArgumentBuilder<ServerCommandSource> builder = CommandManager.literal("racelist").requires(s -> s.hasPermissionLevel(4));
|
||||
|
||||
EnumArgumentType<Race> raceArgument = EnumArgumentType.of(Race.class, Race::isUsable, Race.EARTH);
|
||||
|
||||
builder.then(CommandManager.literal("allow")
|
||||
.then(CommandManager.argument("race", new RaceArgument())
|
||||
.then(CommandManager.argument("race", raceArgument)
|
||||
.executes(context -> toggle(context.getSource(), context.getSource().getPlayer(), context.getArgument("race", Race.class), "allowed", race -> {
|
||||
boolean result = Unicopia.getConfig().speciesWhiteList.get().add(race);
|
||||
|
||||
|
@ -30,7 +32,7 @@ class RacelistCommand {
|
|||
}))
|
||||
));
|
||||
builder.then(CommandManager.literal("disallow")
|
||||
.then(CommandManager.argument("race", new RaceArgument())
|
||||
.then(CommandManager.argument("race", raceArgument)
|
||||
.executes(context -> toggle(context.getSource(), context.getSource().getPlayer(), context.getArgument("race", Race.class), "disallowed", race -> {
|
||||
boolean result = Unicopia.getConfig().speciesWhiteList.get().remove(race);
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ class SpeciesCommand {
|
|||
static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
|
||||
LiteralArgumentBuilder<ServerCommandSource> builder = CommandManager.literal("race");
|
||||
|
||||
EnumArgumentType<Race> raceArgument = EnumArgumentType.of(Race.class, Race::isUsable, Race.EARTH);
|
||||
|
||||
builder.then(CommandManager.literal("get")
|
||||
.executes(context -> get(context.getSource(), context.getSource().getPlayer(), true))
|
||||
.then(CommandManager.argument("target", EntityArgumentType.player())
|
||||
|
@ -27,14 +29,14 @@ class SpeciesCommand {
|
|||
));
|
||||
|
||||
builder.then(CommandManager.literal("set")
|
||||
.then(CommandManager.argument("race", new RaceArgument())
|
||||
.then(CommandManager.argument("race", raceArgument)
|
||||
.executes(context -> set(context.getSource(), context.getSource().getPlayer(), context.getArgument("race", Race.class), true))
|
||||
.then(CommandManager.argument("target", EntityArgumentType.player())
|
||||
.executes(context -> set(context.getSource(), EntityArgumentType.getPlayer(context, "target"), context.getArgument("race", Race.class), false))
|
||||
)));
|
||||
|
||||
builder.then(CommandManager.literal("describe")
|
||||
.then(CommandManager.argument("race", new RaceArgument())
|
||||
.then(CommandManager.argument("race", raceArgument)
|
||||
.executes(context -> describe(context.getSource().getPlayer(), context.getArgument("race", Race.class))
|
||||
)));
|
||||
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package com.minelittlepony.unicopia.command;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.FloatArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.Hand;
|
||||
|
||||
class TraitCommand {
|
||||
static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
|
||||
LiteralArgumentBuilder<ServerCommandSource> builder = CommandManager
|
||||
.literal("trait")
|
||||
.requires(s -> s.hasPermissionLevel(4));
|
||||
|
||||
builder.then(CommandManager.literal("add")
|
||||
.then(CommandManager.argument("trait", EnumArgumentType.of(Trait.class))
|
||||
.then(CommandManager.argument("value", FloatArgumentType.floatArg()).executes(source -> add(
|
||||
source.getSource(),
|
||||
source.getSource().getPlayer(),
|
||||
source.getArgument("trait", Trait.class),
|
||||
FloatArgumentType.getFloat(source, "value")
|
||||
)))
|
||||
));
|
||||
builder.then(CommandManager.literal("remove")
|
||||
.then(CommandManager.argument("trait", EnumArgumentType.of(Trait.class)).executes(source -> remove(
|
||||
source.getSource(),
|
||||
source.getSource().getPlayer(),
|
||||
source.getArgument("trait", Trait.class)
|
||||
))
|
||||
));
|
||||
|
||||
dispatcher.register(builder);
|
||||
}
|
||||
|
||||
static int add(ServerCommandSource source, PlayerEntity player, Trait trait, float amount) throws CommandSyntaxException {
|
||||
if (trait == null) {
|
||||
source.sendError(new LiteralText("Invalid trait"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ItemStack stack = player.getMainHandStack();
|
||||
if (stack.isEmpty()) {
|
||||
source.sendError(new LiteralText("That trait cannot be added to the current item"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
player.setStackInHand(Hand.MAIN_HAND, SpellTraits.union(SpellTraits.of(stack), new SpellTraits.Builder().with(trait, amount).build()).applyTo(stack));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int remove(ServerCommandSource source, PlayerEntity player, Trait trait) throws CommandSyntaxException {
|
||||
if (trait == null) {
|
||||
source.sendError(new LiteralText("Invalid trait"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ItemStack stack = player.getMainHandStack();
|
||||
|
||||
SpellTraits existing = SpellTraits.of(stack);
|
||||
if (existing.get(trait) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
player.setStackInHand(Hand.MAIN_HAND, existing.map((t, v) -> t == trait ? 0 : v).applyTo(stack));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get(ServerCommandSource source, PlayerEntity player, Trait trait, float amount) throws CommandSyntaxException {
|
||||
String translationKey = "commands.gravity.get";
|
||||
|
||||
Pony iplayer = Pony.of(player);
|
||||
|
||||
float gravity = iplayer.getPhysics().getGravityModifier();
|
||||
|
||||
if (source.getPlayer() == player) {
|
||||
player.sendMessage(new TranslatableText(translationKey, gravity), false);
|
||||
} else {
|
||||
source.sendFeedback(new TranslatableText(translationKey + ".other", player.getName(), gravity), true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue