diff --git a/src/main/java/de/jottyfan/minecraft/quickiefabric/items/ItemBag.java b/src/main/java/de/jottyfan/minecraft/quickiefabric/items/ItemBag.java index d6d27b1..2634a19 100644 --- a/src/main/java/de/jottyfan/minecraft/quickiefabric/items/ItemBag.java +++ b/src/main/java/de/jottyfan/minecraft/quickiefabric/items/ItemBag.java @@ -1,5 +1,8 @@ package de.jottyfan.minecraft.quickiefabric.items; +import java.util.ArrayList; +import java.util.List; + import de.jottyfan.minecraft.quickiefabric.container.BackpackInventory; import de.jottyfan.minecraft.quickiefabric.item.ModdedItemUsageContext; import net.minecraft.block.Blocks; @@ -21,6 +24,20 @@ import net.minecraft.world.World; */ public class ItemBag extends ItemBackpack { + private Integer useItemsOfStack(ItemStack stack, List posList, ItemUsageContext context, World world, + PlayerEntity player, Item item) { + for (BlockPos pos : posList) { + BlockHitResult hit = new BlockHitResult(context.getHitPos(), context.getSide(), pos, context.hitsInsideBlock()); + ModdedItemUsageContext iuc = new ModdedItemUsageContext(world, player, Hand.MAIN_HAND, stack, hit); + item.useOnBlock(iuc); + stack.decrement(1); + if (stack.getCount() < 1) { // interrupt if stack is empty + break; + } + } + return stack.getCount(); + } + @Override public ActionResult useOnBlock(ItemUsageContext context) { BlockPos pos = context.getBlockPos(); @@ -34,18 +51,18 @@ public class ItemBag extends ItemBackpack { for (int slot = 0; slot < ItemBackpack.SLOTSIZE; slot++) { ItemStack stack = bi.getStack(slot); if (stack.getCount() > 0) { - Item item = stack.getItem(); + // not yet working recursive calls of findFreeFields; do not use this now! +// List posList = findFreeFields(new ArrayList<>(), world, pos, stack.getCount()); + List posList = hackedFindFields(world, pos); for (int i = stack.getCount(); i > 0; i--) { - pos = findNextFreeField(world, pos); - if (pos == null) { - break; + int beforeUsage = stack.getCount(); + int afterUsage = useItemsOfStack(stack, posList, context, world, player, stack.getItem()); + if (afterUsage == beforeUsage) { + break; // no more fields found + } else { + stack.setCount(afterUsage); + bi.setStack(slot, stack); } - BlockHitResult hit = new BlockHitResult(context.getHitPos(), context.getSide(), pos, - context.hitsInsideBlock()); - ModdedItemUsageContext iuc = new ModdedItemUsageContext(world, player, Hand.MAIN_HAND, stack, hit); - item.useOnBlock(iuc); - stack.decrement(1); - bi.setStack(slot, stack); } } } @@ -59,68 +76,71 @@ public class ItemBag extends ItemBackpack { } /** - * find the next free field that can be used to set a sapling to... + * add pos to list if it is farmland * + * @param list the list * @param world the world - * @param start the starting position - * @return the next free block of farmland - might be even the one on start + * @param pos the pos + * @return the added pos; might be up or down also; if null, no farmland was + * found or the element has been already added or there are more + * farmland fields than seed */ - private final BlockPos findNextFreeField(World world, BlockPos start) { - if (isFreeFarmland(world, start)) { - return start; - } else if (isFreeFarmland(world, start.east())) { - return start.east(); - } else if (isFreeFarmland(world, start.west())) { - return start.west(); - } else if (isFreeFarmland(world, start.south())) { - return start.south(); - } else if (isFreeFarmland(world, start.north())) { - return start.north(); - } else if (isFreeFarmland(world, start.east().south())) { - return start.east().south(); - } else if (isFreeFarmland(world, start.west().south())) { - return start.west().south(); - } else if (isFreeFarmland(world, start.east().north())) { - return start.east().north(); - } else if (isFreeFarmland(world, start.west().north())) { - return start.west().north(); - } else if (isFreeFarmland(world, start.east().up())) { - return start.east().up(); - } else if (isFreeFarmland(world, start.west().up())) { - return start.west().up(); - } else if (isFreeFarmland(world, start.south().up())) { - return start.south().up(); - } else if (isFreeFarmland(world, start.north().up())) { - return start.north().up(); - } else if (isFreeFarmland(world, start.east().south().up())) { - return start.east().south().up(); - } else if (isFreeFarmland(world, start.west().south().up())) { - return start.west().south().up(); - } else if (isFreeFarmland(world, start.east().north().up())) { - return start.east().north().up(); - } else if (isFreeFarmland(world, start.west().north().up())) { - return start.west().north().up(); - } else if (isFreeFarmland(world, start.east().down())) { - return start.east().down(); - } else if (isFreeFarmland(world, start.west().down())) { - return start.west().down(); - } else if (isFreeFarmland(world, start.south().down())) { - return start.south().down(); - } else if (isFreeFarmland(world, start.north().down())) { - return start.north().down(); - } else if (isFreeFarmland(world, start.east().south().down())) { - return start.east().south().down(); - } else if (isFreeFarmland(world, start.west().south().down())) { - return start.west().south().down(); - } else if (isFreeFarmland(world, start.east().north().down())) { - return start.east().north().down(); - } else if (isFreeFarmland(world, start.west().north().down())) { - return start.west().north().down(); + private BlockPos addToListIfNotYetDone(List list, World world, BlockPos pos, Integer limit) { + if (limit < list.size()) { + return null; // interrupt here to reduce calculation time + } else if (!list.contains(pos) && isFreeFarmland(world, pos)) { + list.add(pos); + return pos; + } else if (!list.contains(pos.up()) && isFreeFarmland(world, pos.up())) { + list.add(pos.up()); + return pos.up(); + } else if (!list.contains(pos.down()) && isFreeFarmland(world, pos.down())) { + list.add(pos.down()); + return pos.down(); } else { return null; } } + /** + * find the next free fields that can be used to set a sapling to... + * + * @param world the world + * @param start the starting position + * @return the next free blocks of farmland - might be even the one on start + * @deprecated not yet safe abort condition; do not use it in the game + */ + @Deprecated + private final List findFreeFields(List list, World world, BlockPos start, Integer limit) { + addToListIfNotYetDone(list, world, start, limit); + BlockPos east = addToListIfNotYetDone(list, world, start.east(), limit); + if (east != null) { + list.addAll(findFreeFields(list, world, east, limit)); + } + BlockPos west = addToListIfNotYetDone(list, world, start.west(), limit); + if (west != null) { + list.addAll(findFreeFields(list, world, west, limit)); + } + BlockPos south = addToListIfNotYetDone(list, world, start.south(), limit); + if (south != null) { + list.addAll(findFreeFields(list, world, south, limit)); + } + BlockPos north = addToListIfNotYetDone(list, world, start.north(), limit); + if (north != null) { + list.addAll(findFreeFields(list, world, north, limit)); + } + return list; + } + + @Deprecated + private final List hackedFindFields(World world, BlockPos pos) { + List list = new ArrayList<>(); + if (isFreeFarmland(world, pos)) { + list.add(pos); + } + return list; + } + /** * check if the block on pos is farmland and the one above is air *