Skip to content

Commit

Permalink
feat: Handle alloy smelting vanilla inheritance with recipe manager.
Browse files Browse the repository at this point in the history
Intended to help with the Kube JS addon, but also simplifies the logic somewhat.
  • Loading branch information
rlnt authored Sep 26, 2024
1 parent a274b67 commit c42b0c9
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.SmeltingRecipe;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.data.event.GatherDataEvent;
Expand Down Expand Up @@ -76,13 +75,4 @@ default Optional<BlockState> getFacadeOf(ItemStack stack) {
default boolean canBlockTeleport(Player player) {
return false;
}

/**
* Usage intended for kubejs io, tell us if you need it for something else
* @param recipe The smelting recipe that is tried to be used in the AlloySmelter.
* @return true if this recipe can be used
*/
default boolean acceptSmeltingRecipe(SmeltingRecipe recipe) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.enderio.EnderIOBase;
import com.enderio.base.api.capacitor.CapacitorModifier;
import com.enderio.base.api.capacitor.QuadraticScalable;
import com.enderio.base.api.integration.IntegrationManager;
import com.enderio.base.api.io.energy.EnergyIOMode;
import com.enderio.core.common.blockentity.EnderBlockEntity;
import com.enderio.core.common.network.NetworkDataSlot;
Expand All @@ -15,7 +14,6 @@
import com.enderio.machines.common.init.MachineBlockEntities;
import com.enderio.machines.common.init.MachineDataComponents;
import com.enderio.machines.common.init.MachineRecipes;
import com.enderio.machines.common.integrations.vanilla.VanillaAlloySmeltingRecipe;
import com.enderio.machines.common.io.energy.IMachineEnergyStorage;
import com.enderio.machines.common.io.item.MachineInventory;
import com.enderio.machines.common.io.item.MachineInventoryLayout;
Expand All @@ -28,15 +26,12 @@
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.SingleRecipeInput;
import net.minecraft.world.item.crafting.SmeltingRecipe;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
Expand Down Expand Up @@ -232,7 +227,7 @@ public AlloySmeltingMachineTask(@NotNull Level level, MachineInventory inventory
@Override
protected AlloySmeltingRecipe.Input prepareToDetermineOutputs(AlloySmeltingRecipe recipe, AlloySmeltingRecipe.Input recipeInput) {
// This handles the output multiplication for vanilla smelting recipes.
if (recipe instanceof VanillaAlloySmeltingRecipe) {
if (recipe.isSmelting()) {
SizedIngredient input = recipe.inputs().getFirst();

int inputCount = 0;
Expand All @@ -255,7 +250,7 @@ protected AlloySmeltingRecipe.Input prepareToDetermineOutputs(AlloySmeltingRecip
protected void consumeInputs(AlloySmeltingRecipe recipe) {
MachineInventory inv = getInventory();

if (recipe instanceof VanillaAlloySmeltingRecipe) {
if (recipe.isSmelting()) {
SizedIngredient input = recipe.inputs().get(0);

int consumed = 0;
Expand Down Expand Up @@ -301,20 +296,6 @@ protected void consumeInputs(AlloySmeltingRecipe recipe) {
}
}

@Nullable
@Override
protected RecipeHolder<AlloySmeltingRecipe> loadRecipe(ResourceLocation id) {
return level.getRecipeManager().byKey(id).map(recipe -> {
if (recipe.value().getType() == MachineRecipes.ALLOY_SMELTING.type().get()) {
//noinspection unchecked
return (RecipeHolder<AlloySmeltingRecipe>) recipe;
} else if (recipe.value().getType() == RecipeType.SMELTING) {
return new RecipeHolder<AlloySmeltingRecipe>(id, new VanillaAlloySmeltingRecipe((SmeltingRecipe) recipe.value()));
}
return null;
}).orElse(null);
}

@Override
public void deserializeNBT(HolderLookup.Provider lookupProvider, CompoundTag nbt) {
super.deserializeNBT(lookupProvider, nbt);
Expand Down Expand Up @@ -343,28 +324,16 @@ protected Optional<RecipeHolder<AlloySmeltingRecipe>> findRecipe() {
return Optional.empty();
}

// Get alloy smelting recipe (Default)
if (getMode().canAlloy()) {
var recipe = super.findRecipe();
if (recipe.isPresent()) {
return recipe;
}
var optionalRecipe = super.findRecipe();
if (optionalRecipe.isEmpty()) {
return Optional.empty();
}

// Get vanilla smelting recipe.
if (getMode().canSmelt()) {
AlloySmeltingRecipe.Input recipeInput = createRecipeInput();

for (int i = 0; i < recipeInput.size(); i++) {
var recipe = level.getRecipeManager()
.getRecipeFor(RecipeType.SMELTING, new SingleRecipeInput(recipeInput.getItem(i)), level);

if (recipe.isPresent() && IntegrationManager.allMatch(integration -> integration.acceptSmeltingRecipe(recipe.get().value()))) {
return Optional.of(new RecipeHolder<>(recipe.get().id(), new VanillaAlloySmeltingRecipe(recipe.get().value())));
}
}
if (optionalRecipe.get().value().isSmelting() ? !getMode().canSmelt() : !getMode().canAlloy()) {
return Optional.empty();
}
return Optional.empty();

return optionalRecipe;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.enderio.machines.common.init.MachineRecipes;
import com.enderio.machines.common.integrations.jei.util.WrappedEnchanterRecipe;
import com.enderio.machines.common.integrations.vanilla.VanillaAlloySmeltingRecipe;
import com.enderio.machines.common.recipe.AlloySmeltingRecipe;
import com.enderio.machines.common.recipe.FermentingRecipe;
import com.enderio.machines.common.recipe.SagMillingRecipe;
Expand All @@ -14,7 +13,6 @@
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.item.crafting.RecipeType;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -36,8 +34,6 @@ public List<RecipeHolder<AlloySmeltingRecipe>> getAlloySmeltingRecipes() {
public List<RecipeHolder<AlloySmeltingRecipe>> getAlloySmeltingRecipesWithSmelting() {
List<RecipeHolder<AlloySmeltingRecipe>> recipes = new ArrayList<>();
recipes.addAll(recipeManager.getAllRecipesFor(MachineRecipes.ALLOY_SMELTING.type().get()));
recipes.addAll(recipeManager.getAllRecipesFor(RecipeType.SMELTING).stream()
.map(h -> new RecipeHolder<AlloySmeltingRecipe>(h.id(), new VanillaAlloySmeltingRecipe(h.value()))).toList());
return recipes;
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.enderio.machines.common.recipe;

import com.enderio.core.common.recipes.OutputStack;
import com.enderio.machines.common.blockentity.AlloySmelterBlockEntity;
import com.enderio.machines.common.blockentity.PrimitiveAlloySmelterBlockEntity;
import com.enderio.machines.common.init.MachineRecipes;
import com.enderio.machines.common.io.item.MultiSlotAccess;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
Expand All @@ -20,8 +17,6 @@
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
import net.neoforged.neoforge.common.crafting.SizedIngredient;
import net.neoforged.neoforge.items.IItemHandlerModifiable;
import net.neoforged.neoforge.items.wrapper.RecipeWrapper;

import java.util.List;

Expand All @@ -30,12 +25,18 @@ public class AlloySmeltingRecipe implements MachineRecipe<AlloySmeltingRecipe.In
private final ItemStack output;
private final int energy;
private final float experience;
private final boolean isSmelting;

public AlloySmeltingRecipe(List<SizedIngredient> inputs, ItemStack output, int energy, float experience) {
public AlloySmeltingRecipe(List<SizedIngredient> inputs, ItemStack output, int energy, float experience, boolean isSmelting) {
this.inputs = inputs;
this.output = output;
this.energy = energy;
this.experience = experience;
this.isSmelting = isSmelting;
}

public AlloySmeltingRecipe(List<SizedIngredient> inputs, ItemStack output, int energy, float experience) {
this(inputs, output, energy, experience, false);
}

public List<SizedIngredient> inputs() {
Expand All @@ -54,6 +55,10 @@ public float experience() {
return experience;
}

public boolean isSmelting() {
return isSmelting;
}

@Override
public int getBaseEnergyCost() {
return energy;
Expand Down Expand Up @@ -103,7 +108,11 @@ public boolean matches(Input recipeInput, Level level) {

@Override
public List<OutputStack> craft(Input container, RegistryAccess registryAccess) {
return List.of(OutputStack.of(output.copy()));
ItemStack outputStack = output.copy();
if (isSmelting) {
outputStack.setCount(container.inputsConsumed);
}
return List.of(OutputStack.of(outputStack));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.enderio.machines.mixin;

import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(AbstractCookingRecipe.class)
public interface AbstractCookingRecipeAccessor {

@Accessor
Ingredient getIngredient();

@Accessor
ItemStack getResult();

@Accessor
float getExperience();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.enderio.machines.mixin;

import com.enderio.EnderIOBase;
import com.enderio.machines.common.config.MachinesConfig;
import com.enderio.machines.common.init.MachineRecipes;
import com.enderio.machines.common.recipe.AlloySmeltingRecipe;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.SmeltingRecipe;
import net.neoforged.neoforge.common.conditions.WithConditions;
import net.neoforged.neoforge.common.crafting.SizedIngredient;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.List;

@Mixin(RecipeManager.class)
public class RecipeManagerMixin {

@Inject(method = "lambda$apply$0", at = @At("TAIL"))
private static void collectRecipe(ResourceLocation recipeId, ImmutableMultimap.Builder<RecipeType<?>, RecipeHolder<?>> byType,
ImmutableMap.Builder<ResourceLocation, RecipeHolder<?>> byName, WithConditions<Recipe<?>> recipeWithConditions, CallbackInfo ci) {
if (recipeWithConditions.carrier() instanceof SmeltingRecipe smeltingRecipe) {
RecipeHolder<AlloySmeltingRecipe> convertedHolder = enderio$convert(recipeId, smeltingRecipe);
byType.put(MachineRecipes.ALLOY_SMELTING.type().get(), convertedHolder);
byName.put(convertedHolder.id(), convertedHolder);
}
}

@Unique
private static RecipeHolder<AlloySmeltingRecipe> enderio$convert(ResourceLocation originalId, SmeltingRecipe smeltingRecipe) {
AbstractCookingRecipeAccessor accessor = (AbstractCookingRecipeAccessor) smeltingRecipe;
SizedIngredient input = new SizedIngredient(accessor.getIngredient(), 1);
int energy = MachinesConfig.COMMON.ENERGY.ALLOY_SMELTER_VANILLA_ITEM_ENERGY.get();
AlloySmeltingRecipe recipe = new AlloySmeltingRecipe(List.of(input), accessor.getResult(), energy, accessor.getExperience(), true);

String path = "smelting/" + originalId.getPath();
ResourceLocation id = EnderIOBase.loc(path);
return new RecipeHolder<>(id, recipe);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@javax.annotation.ParametersAreNonnullByDefault
@net.minecraft.MethodsReturnNonnullByDefault

package com.enderio.machines.common.integrations.vanilla;
package com.enderio.machines.mixin;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ description="The machines module for Ender IO"
displayURL="https://enderio.com/"
logoFile="logo.png"

[[mixins]]
config="enderio-machines.mixins.json"

[[dependencies.enderio_machines]]
modId="minecraft"
type="required"
Expand Down
Loading

0 comments on commit c42b0c9

Please sign in to comment.