- 22
- 1
- 0
День добрый, я пытаюсь создать кастомный тип рецепта на Forge версии 1.20.2, но все мои попытки создать его или найти какой-либо более-менее рабочий гайд приводят к тому, что ничего не работает. Что именно не работает - понятия не имею, и прошу помочь хотя бы определиться, что мне нужно фиксить.
Код рецепта крафта:
Использование в BlockEntity:
Ни единой ошибки я не получаю (Если бы получал, может быть, пофиксил бы), прошу помочь хоть чем-нибудь
Код рецепта крафта:
Java:
public class CoalExtruderRecipe implements Recipe<Container> {
private final NonNullList<Ingredient> inputs;
private final ItemStack output;
public CoalExtruderRecipe(List<Ingredient> inputs, ItemStack output) {
this.inputs = NonNullList.withSize(2, Ingredient.EMPTY);
for (int index = 0; index < inputs.size(); index++) {
this.inputs.set(index, inputs.get(index));
}
this.output = output;
}
public NonNullList<Ingredient> getInputs() {
return this.inputs;
}
public ItemStack getOutput() {
return this.output;
}
@Override
public boolean matches(Container pContainer, Level pLevel) {
ItemStack input0 = pContainer.getItem(0);
ItemStack input1 = pContainer.getItem(1);
return matches(input0, input1);
}
public boolean matches(ItemStack... inputs) {
List<Boolean> matched = new ArrayList<>(inputs.length);
for (int i = 0; i < inputs.length; i++) {
matched.add(false);
}
for (Ingredient recipeIngredient : this.inputs) {
for (int inputIndex = 0; inputIndex < inputs.length; inputIndex++) {
ItemStack input = inputs[inputIndex];
if (!matched.get(inputIndex) && recipeIngredient.test(input)) {
matched.set(inputIndex, true);
break; // Move to the next recipe ingredient
}
}
}
// Check if all ingredients were matched
return matched.stream().allMatch(Boolean::valueOf);
}
@Override
public ItemStack assemble(Container pContainer, RegistryAccess pRegistryAccess) {
ItemStack input0 = pContainer.getItem(0);
ItemStack input1 = pContainer.getItem(1);
return matches(input0, input1) ? this.output.copy() : ItemStack.EMPTY;
}
@Override
public boolean canCraftInDimensions(int pWidth, int pHeight) {
return true;
}
@Override
public ItemStack getResultItem(RegistryAccess pRegistryAccess) {
return this.output;
}
@Override
public RecipeSerializer<?> getSerializer() {
return Serializer.INSTANCE;
}
@Override
public RecipeType<?> getType() {
return Type.INSTANCE;
}
public void assemble(CoalExtruderBlockEntity coalExtruderBlockEntity) {
ItemStack input0 = coalExtruderBlockEntity.getInventory().getStackInSlot(0);
ItemStack input1 = coalExtruderBlockEntity.getInventory().getStackInSlot(1);
if (matches(input0, input1)) {
coalExtruderBlockEntity.getInventory().insertItem(2, this.output.copy(), false);
// Remove the items from the inputs that were used
for (Ingredient input : this.inputs) {
if(input.test(input0))
coalExtruderBlockEntity.getInventory().extractItem(0, 1, false);
else if(input.test(input1))
coalExtruderBlockEntity.getInventory().extractItem(1, 1, false);
}
}
}
public static class Serializer implements RecipeSerializer<CoalExtruderRecipe> {
public static final Serializer INSTANCE = new Serializer();
private static final Codec<CoalExtruderRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Ingredient.CODEC_NONEMPTY.listOf().fieldOf("inputs").forGetter(recipe -> recipe.inputs),
ItemStack.CODEC.fieldOf("output").forGetter(recipe -> recipe.output)).apply(instance, CoalExtruderRecipe::new));
@Override
public Codec<CoalExtruderRecipe> codec() {
return CODEC;
}
@Override
public @Nullable CoalExtruderRecipe fromNetwork(FriendlyByteBuf pBuffer) {
int inputCount = pBuffer.readInt();
NonNullList<Ingredient> inputs = NonNullList.withSize(2, Ingredient.EMPTY);
for (int index = 0; index < inputCount; index++) {
inputs.add(Ingredient.fromNetwork(pBuffer));
}
ItemStack output = pBuffer.readItem();
int processTime = pBuffer.readInt();
return new CoalExtruderRecipe(inputs, output);
}
@Override
public void toNetwork(FriendlyByteBuf pBuffer, CoalExtruderRecipe pRecipe) {
pBuffer.writeInt(pRecipe.inputs.size());
for (Ingredient input : pRecipe.inputs) {
input.toNetwork(pBuffer);
}
pBuffer.writeItem(pRecipe.output);
}
}
public static class Type implements RecipeType<CoalExtruderRecipe> {
public static final Type INSTANCE = new Type();
private static final String ID = new ResourceLocation(TutorialMod.MOD_ID, "coal_extruding").toString();
@Override
public String toString() {
return ID;
}
}
}
Java:
public void tick() {
if(this.level.isClientSide() || this.level == null) {
return;
}
if(hasRecipe()) {
increaseCraftingProgress();
setChanged(this.level, this.worldPosition, this.getBlockState());
if(hasProgressFinished()) {
craftItem();
resetProgress();
}
} else {
resetProgress();
}
}
private boolean hasRecipe() {
Optional<RecipeHolder<CoalExtruderRecipe>> recipe = getCurrentRecipe();
if(recipe.isEmpty()) {
return false;
}
ItemStack result = recipe.get().value().getResultItem(null);
return canInsertAmountInSlot(result.getCount()) && canInsertItemInSlot(result.getItem());
}
private boolean canInsertItemInSlot(Item item) {
return this.inventory.getStackInSlot(2).isEmpty() || this.inventory.getStackInSlot(2).is(item);
}
private boolean canInsertAmountInSlot(int count) {
return this.inventory.getStackInSlot(2).getCount() + count <= this.inventory.getStackInSlot(2).getMaxStackSize();
}
private Optional<RecipeHolder<CoalExtruderRecipe>> getCurrentRecipe() {
SimpleContainer Inventory = new SimpleContainer(this.inventory.getSlots());
for (int i = 0; i < inventory.getSlots(); i++) {
Inventory.setItem(i, this.inventory.getStackInSlot(i));
}
return this.level.getRecipeManager().getRecipeFor(CoalExtruderRecipe.Type.INSTANCE, Inventory, level);
}