public void setIngredients(List<?> items) {
   ingredients.clear();
   for (int ingred = 0; ingred < items.size(); ingred++) {
     PositionedStack stack =
         new PositionedStack(
             items.get(ingred), 25 + stackorder[ingred][0] * 18, 6 + stackorder[ingred][1] * 18);
     stack.setMaxSize(1);
     ingredients.add(stack);
   }
 }
 public void setIngredients(int width, int height, Object[] items) {
   for (int x = 0; x < width; x++) {
     for (int y = 0; y < height; y++) {
       if (items[y * width + x] == null) {
         continue;
       }
       PositionedStack stack =
           new PositionedStack(items[y * width + x], 25 + x * 18, 6 + y * 18, false);
       stack.setMaxSize(1);
       ingredients.add(stack);
     }
   }
 }
    @Override
    public boolean contains(Collection<PositionedStack> ingredients, ItemStack ingredient) {
      if (ingredients == inputs) {
        boolean skippedPool = false;

        for (PositionedStack stack : ingredients) {
          if (!skippedPool) {
            skippedPool = true;
            continue;
          }

          if (stack.contains(ingredient)) return true;
        }
      }

      return super.contains(ingredients, ingredient);
    }
    public CachedChiselRecipe(List<ItemStack> variations, ItemStack base, ItemStack focus) {
      PositionedStack pStack = new PositionedStack(base != null ? base : variations, 74, 4);
      pStack.setMaxSize(1);
      this.input.add(pStack);

      int row = 0;
      int col = 0;
      for (ItemStack v : variations) {
        this.outputs.add(new PositionedStack(v, 3 + 18 * col, 37 + 18 * row));

        if (focus != null && NEIServerUtils.areStacksSameTypeCrafting(focus, v)) {
          this.focus = new Point(2 + 18 * col, 36 + 18 * row);
        }

        col++;
        if (col > 8) {
          col = 0;
          row++;
        }
      }
    }