|
7 | 7 | import com.mojang.brigadier.context.CommandContext; |
8 | 8 | import com.mojang.brigadier.context.ContextChain; |
9 | 9 | import com.mojang.brigadier.exceptions.CommandSyntaxException; |
| 10 | +import com.mojang.brigadier.exceptions.Dynamic3CommandExceptionType; |
10 | 11 | import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; |
11 | 12 | import com.mojang.brigadier.suggestion.SuggestionProvider; |
12 | 13 | import io.github.misode.packtest.*; |
| 14 | +import it.unimi.dsi.fastutil.ints.IntList; |
13 | 15 | import net.minecraft.advancements.critereon.MinMaxBounds; |
14 | 16 | import net.minecraft.commands.CommandBuildContext; |
15 | 17 | import net.minecraft.commands.CommandSourceStack; |
16 | 18 | import net.minecraft.commands.SharedSuggestionProvider; |
17 | 19 | import net.minecraft.commands.arguments.*; |
18 | 20 | import net.minecraft.commands.arguments.blocks.BlockPredicateArgument; |
19 | 21 | import net.minecraft.commands.arguments.coordinates.BlockPosArgument; |
| 22 | +import net.minecraft.commands.arguments.item.ItemPredicateArgument; |
20 | 23 | import net.minecraft.commands.arguments.selector.EntitySelector; |
21 | 24 | import net.minecraft.commands.execution.ChainModifiers; |
22 | 25 | import net.minecraft.commands.execution.CustomCommandExecutor; |
|
32 | 35 | import net.minecraft.server.ReloadableServerRegistries; |
33 | 36 | import net.minecraft.server.commands.data.DataCommands; |
34 | 37 | import net.minecraft.server.level.ServerPlayer; |
| 38 | +import net.minecraft.world.Container; |
35 | 39 | import net.minecraft.world.entity.Entity; |
| 40 | +import net.minecraft.world.inventory.SlotRange; |
| 41 | +import net.minecraft.world.item.ItemStack; |
| 42 | +import net.minecraft.world.level.block.entity.BlockEntity; |
36 | 43 | import net.minecraft.world.level.block.state.pattern.BlockInWorld; |
37 | 44 | import net.minecraft.world.level.storage.loot.LootContext; |
38 | 45 | import net.minecraft.world.level.storage.loot.LootParams; |
@@ -61,6 +68,9 @@ public class AssertCommand { |
61 | 68 | private static final SimpleCommandExceptionType ERROR_NO_HELPER = new SimpleCommandExceptionType( |
62 | 69 | Component.literal("Not inside a test") |
63 | 70 | ); |
| 71 | + private static final Dynamic3CommandExceptionType ERROR_SOURCE_NOT_A_CONTAINER = new Dynamic3CommandExceptionType( |
| 72 | + (x, y, z) -> Component.translatableEscape("commands.item.source.not_a_container", x, y, z) |
| 73 | + ); |
64 | 74 | private static final SuggestionProvider<CommandSourceStack> SUGGEST_PREDICATE = (ctx, suggestions) -> { |
65 | 75 | ReloadableServerRegistries.Holder registries = ctx.getSource().getServer().reloadableRegistries(); |
66 | 76 | return SharedSuggestionProvider.suggestResource(registries.getKeys(Registries.PREDICATE), suggestions); |
@@ -92,6 +102,17 @@ public static void addConditions(LiteralArgumentBuilder<CommandSourceStack> buil |
92 | 102 | .then(argument("predicate", ResourceOrIdArgument.lootPredicate(buildContext)) |
93 | 103 | .suggests(SUGGEST_PREDICATE) |
94 | 104 | .executes(expect.apply(AssertCommand::assertPredicate)))) |
| 105 | + .then(literal("items") |
| 106 | + .then(literal("entity") |
| 107 | + .then(argument("entities", EntityArgument.entities()) |
| 108 | + .then(argument("slots", SlotsArgument.slots()) |
| 109 | + .then(argument("item_predicate", ItemPredicateArgument.itemPredicate(buildContext)) |
| 110 | + .executes(expect.apply(AssertCommand::assertItemsEntity)))))) |
| 111 | + .then(literal("block") |
| 112 | + .then(argument("pos", BlockPosArgument.blockPos()) |
| 113 | + .then(argument("slots", SlotsArgument.slots()) |
| 114 | + .then(argument("item_predicate", ItemPredicateArgument.itemPredicate(buildContext)) |
| 115 | + .executes(expect.apply(AssertCommand::assertItemsBlock))))))) |
95 | 116 | .then(literal("score") |
96 | 117 | .then(argument("target", ScoreHolderArgument.scoreHolder()) |
97 | 118 | .suggests(ScoreHolderArgument.SUGGEST_SCORE_HOLDERS) |
@@ -177,6 +198,59 @@ private static AssertResult assertPredicate(CommandContext<CommandSourceStack> c |
177 | 198 | return err(expected); |
178 | 199 | } |
179 | 200 |
|
| 201 | + private static AssertResult assertItemsEntity(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException { |
| 202 | + EntitySelector selector = ctx.getArgument("entities", EntitySelector.class); |
| 203 | + String selectorSource = ((PackTestArgumentSource)selector).packtest$getSource(); |
| 204 | + List<? extends Entity> entities = selector.findEntities(ctx.getSource()); |
| 205 | + SlotRange slotRange = SlotsArgument.getSlots(ctx, "slots"); |
| 206 | + ItemPredicateArgument.Result itemPredicate = ItemPredicateArgument.getItemPredicate(ctx, "item_predicate"); |
| 207 | + String itemPredicateSource = ((PackTestItemPredicate)itemPredicate).source(); |
| 208 | + int count = 0; |
| 209 | + for(Entity entity : entities) { |
| 210 | + IntList slots = slotRange.slots(); |
| 211 | + for(int i = 0; i < slots.size(); ++i) { |
| 212 | + ItemStack itemStack = entity.getSlot(slots.getInt(i)).get(); |
| 213 | + if (itemPredicate.test(itemStack)) { |
| 214 | + count += itemStack.getCount(); |
| 215 | + } |
| 216 | + } |
| 217 | + } |
| 218 | + String expected = selectorSource + " to have items " + itemPredicateSource; |
| 219 | + if (count > 0) { |
| 220 | + return ok(expected); |
| 221 | + } |
| 222 | + return err(expected); |
| 223 | + } |
| 224 | + |
| 225 | + private static AssertResult assertItemsBlock(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException { |
| 226 | + BlockPos pos = BlockPosArgument.getLoadedBlockPos(ctx, "pos"); |
| 227 | + SlotRange slotRange = SlotsArgument.getSlots(ctx, "slots"); |
| 228 | + ItemPredicateArgument.Result itemPredicate = ItemPredicateArgument.getItemPredicate(ctx, "item_predicate"); |
| 229 | + String itemPredicateSource = ((PackTestItemPredicate)itemPredicate).source(); |
| 230 | + BlockEntity blockEntity = ctx.getSource().getLevel().getBlockEntity(pos); |
| 231 | + if (blockEntity instanceof Container container) { |
| 232 | + int count = 0; |
| 233 | + int lvt6 = container.getContainerSize(); |
| 234 | + IntList slots = slotRange.slots(); |
| 235 | + for(int i = 0; i < slots.size(); ++i) { |
| 236 | + int slot = slots.getInt(i); |
| 237 | + if (slot >= 0 && slot < lvt6) { |
| 238 | + ItemStack itemStack = container.getItem(slot); |
| 239 | + if (itemPredicate.test(itemStack)) { |
| 240 | + count += itemStack.getCount(); |
| 241 | + } |
| 242 | + } |
| 243 | + } |
| 244 | + String expected = "block to have items " + itemPredicateSource; |
| 245 | + if (count > 0) { |
| 246 | + return ok(expected); |
| 247 | + } |
| 248 | + return err(expected); |
| 249 | + } else { |
| 250 | + throw ERROR_SOURCE_NOT_A_CONTAINER.create(pos.getX(), pos.getY(), pos.getZ()); |
| 251 | + } |
| 252 | + } |
| 253 | + |
180 | 254 | private static LiteralArgumentBuilder<CommandSourceStack> addScoreCheck(String op, BiPredicate<Integer, Integer> predicate, Function<AssertPredicate, Command<CommandSourceStack>> expect) { |
181 | 255 | return literal(op) |
182 | 256 | .then(argument("source", ScoreHolderArgument.scoreHolder()) |
|
0 commit comments