From f07d46f98df176c34eeba2743758ff7aa10b45e9 Mon Sep 17 00:00:00 2001 From: SkyNotTheLimit <159592458+ekulxam@users.noreply.github.com> Date: Tue, 15 Apr 2025 03:32:41 +0200 Subject: [PATCH] Expand functionality of PetsCommand --- .../map_utils/command/PetsCommand.java | 93 +++++++++++++------ .../map_utils/registry/MapUtilsTags.java | 11 +++ .../tags/entity_type/savable_entities.json | 3 + 3 files changed, 81 insertions(+), 26 deletions(-) create mode 100644 src/main/java/dev/doublekekse/map_utils/registry/MapUtilsTags.java create mode 100644 src/main/resources/data/map_utils/tags/entity_type/savable_entities.json diff --git a/src/main/java/dev/doublekekse/map_utils/command/PetsCommand.java b/src/main/java/dev/doublekekse/map_utils/command/PetsCommand.java index 51d0c26..00e6ce9 100644 --- a/src/main/java/dev/doublekekse/map_utils/command/PetsCommand.java +++ b/src/main/java/dev/doublekekse/map_utils/command/PetsCommand.java @@ -1,16 +1,28 @@ package dev.doublekekse.map_utils.command; import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.DoubleArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; import dev.doublekekse.map_utils.data.MapUtilsSavedData; +import dev.doublekekse.map_utils.registry.MapUtilsTags; +import net.minecraft.commands.CommandSource; import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.commands.arguments.EntityArgument; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.TamableAnimal; +import net.minecraft.world.entity.OwnableEntity; +import net.minecraft.world.entity.TraceableEntity; import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.StreamSupport; import static net.minecraft.commands.Commands.argument; import static net.minecraft.commands.Commands.literal; @@ -20,31 +32,11 @@ public class PetsCommand { public static void register(CommandDispatcher dispatcher) { dispatcher.register( literal("pets").requires(source -> source.hasPermission(2)) - .then(literal("store").then(argument("player", EntityArgument.player()).then(argument("id", StringArgumentType.string()).executes(ctx -> { - var player = EntityArgument.getPlayer(ctx, "player"); - var id = player.getStringUUID() + "-" + StringArgumentType.getString(ctx, "id"); - - var level = player.level(); - var pets = level.getEntitiesOfClass(TamableAnimal.class, player.getBoundingBox().inflate(20), (animal) -> animal.getOwner() == player); - var data = MapUtilsSavedData.getServerData(ctx.getSource().getServer()); - - var list = new ArrayList(pets.size()); - - for (var pet : pets) { - var tag = new CompoundTag(); - if (pet.save(tag)) { - list.add(tag); - pet.discard(); - } - } - - data.setPets(id, list); - - ctx.getSource().sendSuccess(() -> Component.translatable("commands.map_utils.pets.store", id), false); - - return 1; - } - )))).then(literal("load").then(argument("player", EntityArgument.player()).then(argument("id", StringArgumentType.string()).executes(ctx -> { + .then(literal("store").then(argument("player", EntityArgument.player()).then(argument("id", StringArgumentType.string()) + .then(argument("range", DoubleArgumentType.doubleArg(0)).suggests((ctx, builder) -> builder.suggest(20).buildFuture()) + .executes(ctx -> PetsCommand.executeSave(ctx, Optional.of(DoubleArgumentType.getDouble(ctx, "range"))))) + .then(literal("all").executes(ctx -> PetsCommand.executeSave(ctx, Optional.empty()))) + ))).then(literal("load").then(argument("player", EntityArgument.player()).then(argument("id", StringArgumentType.string()).executes(ctx -> { var player = EntityArgument.getPlayer(ctx, "player"); var id = player.getStringUUID() + "-" + StringArgumentType.getString(ctx, "id"); @@ -76,4 +68,53 @@ public static void register(CommandDispatcher dispatcher) { })) ); } + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private static int executeSave(CommandContext ctx, Optional optional) throws CommandSyntaxException { + var player = EntityArgument.getPlayer(ctx, "player"); + var id = player.getStringUUID() + "-" + StringArgumentType.getString(ctx, "id"); + + Predicate canSave = entity -> { + if (entity == null || !entity.isAlive()) { + return false; + } + if (!entity.getType().is(MapUtilsTags.SAVABLE_ENTITIES)) { + return false; + } + if (entity instanceof TraceableEntity traceable && player.equals(traceable.getOwner())) { + return true; + } + if (entity instanceof OwnableEntity ownable && player.equals(ownable.getOwner())) { + return true; + } + return false; + }; + + var level = ctx.getSource().getLevel(); + List pets; + if (optional.isEmpty()) { + pets = StreamSupport.stream(level.getAllEntities().spliterator(), false) + .filter(canSave).toList(); + } else { + double range = optional.get(); + pets = level.getEntitiesOfClass(Entity.class, player.getBoundingBox().inflate(range), entity -> canSave.test(entity) && entity.distanceTo(player) <= range); + } + var data = MapUtilsSavedData.getServerData(ctx.getSource().getServer()); + + var list = new ArrayList(pets.size()); + + for (var pet : pets) { + var tag = new CompoundTag(); + if (pet.save(tag)) { + list.add(tag); + pet.discard(); + } + } + + data.setPets(id, list); + + ctx.getSource().sendSuccess(() -> Component.translatable("commands.map_utils.pets.store", id), false); + + return 1; + } } diff --git a/src/main/java/dev/doublekekse/map_utils/registry/MapUtilsTags.java b/src/main/java/dev/doublekekse/map_utils/registry/MapUtilsTags.java new file mode 100644 index 0000000..4bc92c3 --- /dev/null +++ b/src/main/java/dev/doublekekse/map_utils/registry/MapUtilsTags.java @@ -0,0 +1,11 @@ +package dev.doublekekse.map_utils.registry; + +import dev.doublekekse.map_utils.MapUtils; +import net.minecraft.core.registries.Registries; +import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.EntityType; + +public class MapUtilsTags { + + public static final TagKey> SAVABLE_ENTITIES = TagKey.create(Registries.ENTITY_TYPE, MapUtils.id("savable_entities")); +} diff --git a/src/main/resources/data/map_utils/tags/entity_type/savable_entities.json b/src/main/resources/data/map_utils/tags/entity_type/savable_entities.json new file mode 100644 index 0000000..f72d209 --- /dev/null +++ b/src/main/resources/data/map_utils/tags/entity_type/savable_entities.json @@ -0,0 +1,3 @@ +{ + "values": [] +} \ No newline at end of file