CC-Tweaked/projects/common/src/main/java/dan200/computercraft/shared/media/recipes/PrintoutRecipe.java

123 lines
4.9 KiB
Java

// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
//
// SPDX-License-Identifier: LicenseRef-CCPL
package dan200.computercraft.shared.media.recipes;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.media.items.PrintoutData;
import dan200.computercraft.shared.media.items.PrintoutItem;
import dan200.computercraft.shared.platform.PlatformHelper;
import dan200.computercraft.shared.util.DataComponentUtil;
import net.minecraft.core.HolderLookup;
import net.minecraft.world.inventory.CraftingContainer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.CraftingBookCategory;
import net.minecraft.world.item.crafting.CustomRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.level.Level;
import java.util.List;
public final class PrintoutRecipe extends CustomRecipe {
private final Ingredient leather;
private final Ingredient string;
public PrintoutRecipe(CraftingBookCategory category) {
super(category);
var ingredients = PlatformHelper.get().getRecipeIngredients();
leather = ingredients.leather();
string = ingredients.string();
}
@Override
public boolean canCraftInDimensions(int x, int y) {
return x >= 3 && y >= 3;
}
@Override
public ItemStack getResultItem(HolderLookup.Provider registryAccess) {
return new ItemStack(ModRegistry.Items.PRINTED_PAGES.get());
}
@Override
public boolean matches(CraftingContainer inventory, Level world) {
return !assemble(inventory, world.registryAccess()).isEmpty();
}
@Override
public ItemStack assemble(CraftingContainer inventory, HolderLookup.Provider registryAccess) {
// See if we match the recipe, and extract the input disk ID and dye colour
var numPages = 0;
var numPrintouts = 0;
ItemStack[] printouts = null;
var stringFound = false;
var leatherFound = false;
var printoutFound = false;
for (var y = 0; y < inventory.getHeight(); y++) {
for (var x = 0; x < inventory.getWidth(); x++) {
var stack = inventory.getItem(x + y * inventory.getWidth());
if (!stack.isEmpty()) {
if (stack.getItem() instanceof PrintoutItem printout && printout.getType() != PrintoutItem.Type.BOOK) {
if (printouts == null) printouts = new ItemStack[9];
printouts[numPrintouts] = stack;
numPages += PrintoutItem.getPageCount(stack);
numPrintouts++;
printoutFound = true;
} else if (stack.getItem() == Items.PAPER) {
if (printouts == null) {
printouts = new ItemStack[9];
}
printouts[numPrintouts] = stack;
numPages++;
numPrintouts++;
} else if (string.test(stack) && !stringFound) {
stringFound = true;
} else if (leather.test(stack) && !leatherFound) {
leatherFound = true;
} else {
return ItemStack.EMPTY;
}
}
}
}
// Build some pages with what was passed in
if (numPages <= PrintoutData.MAX_PAGES && stringFound && printoutFound && numPrintouts >= (leatherFound ? 1 : 2)) {
if (printouts == null) throw new IllegalStateException("Printouts must be non-null");
var lines = new PrintoutData.Line[numPages * PrintoutData.LINES_PER_PAGE];
var line = 0;
for (var printout = 0; printout < numPrintouts; printout++) {
var pageText = printouts[printout].get(ModRegistry.DataComponents.PRINTOUT.get());
if (pageText != null) {
// Add a printout
for (var pageLine : pageText.lines()) lines[line++] = pageLine;
} else {
// Add a blank page
for (var pageLine = 0; pageLine < PrintoutData.LINES_PER_PAGE; pageLine++) {
lines[line++] = PrintoutData.Line.EMPTY;
}
}
}
var title = PrintoutItem.getTitle(printouts[0]);
return DataComponentUtil.createStack(
leatherFound ? ModRegistry.Items.PRINTED_BOOK.get() : ModRegistry.Items.PRINTED_PAGES.get(),
ModRegistry.DataComponents.PRINTOUT.get(), new PrintoutData(title, List.of(lines))
);
}
return ItemStack.EMPTY;
}
@Override
public RecipeSerializer<?> getSerializer() {
return ModRegistry.RecipeSerializers.PRINTOUT.get();
}
}