Skip to content

Commit

Permalink
feat: ✨ Added support for recipe types other than just crafting to tr…
Browse files Browse the repository at this point in the history
…ansfer from JEI functionality
  • Loading branch information
P3pp3rF1y committed Dec 30, 2024
1 parent 2fd2b32 commit bf05bcd
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 28 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ org.gradle.daemon=false

mod_id=sophisticatedcore
mod_group_id=sophisticatedcore
mod_version=1.0.3
mod_version=1.0.4
sonar_project_key=sophisticatedcore:SophisticatedCore
github_package_url=https://maven.pkg.github.com/P3pp3rF1y/SophisticatedCore

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.Container;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.crafting.RecipeType;

import java.util.List;

public interface ICraftingContainer {
List<Slot> getRecipeSlots();

Container getCraftMatrix();

void setRecipeUsed(ResourceLocation recipeId);

RecipeType<?> getRecipeType();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import net.minecraftforge.items.SlotItemHandler;
import net.p3pp3rf1y.sophisticatedcore.SophisticatedCore;
Expand Down Expand Up @@ -773,10 +774,10 @@ public void setUpgradeChangeListener(Consumer<StorageContainerMenuBase<?>> upgra
protected abstract boolean storageItemHasChanged();

@SuppressWarnings("unchecked") // both conditions of T are checked before casting it in the result
public <T extends UpgradeContainerBase<?, ?> & ICraftingContainer> Optional<T> getOpenOrFirstCraftingContainer() {
public <T extends UpgradeContainerBase<?, ?> & ICraftingContainer> Optional<T> getOpenOrFirstCraftingContainer(RecipeType<?> recipeType) {
T firstContainer = null;
for (UpgradeContainerBase<?, ?> container : upgradeContainers.values()) {
if (container instanceof ICraftingContainer) {
if (container instanceof ICraftingContainer craftingContainer && craftingContainer.getRecipeType() == recipeType) {
if (container.isOpen()) {
return Optional.of((T) container);
} else if (firstContainer == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
import mezz.jei.common.transfer.RecipeTransferUtil;
import mezz.jei.common.transfer.TransferOperation;
import mezz.jei.common.util.StringUtil;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraftforge.registries.ForgeRegistries;
import net.p3pp3rf1y.sophisticatedcore.SophisticatedCore;
import net.p3pp3rf1y.sophisticatedcore.common.gui.ICraftingContainer;
import net.p3pp3rf1y.sophisticatedcore.common.gui.StorageContainerMenuBase;
Expand All @@ -29,7 +33,7 @@
import java.util.*;
import java.util.stream.Collectors;

public abstract class CraftingContainerRecipeTransferHandlerBase<C extends StorageContainerMenuBase<?>> implements IRecipeTransferHandler<C, CraftingRecipe> {
public abstract class CraftingContainerRecipeTransferHandlerBase<C extends StorageContainerMenuBase<?>, R extends Recipe<?>> implements IRecipeTransferHandler<C, R> {
private final IRecipeTransferHandlerHelper handlerHelper;
private final IStackHelper stackHelper;

Expand All @@ -43,15 +47,10 @@ public Optional<MenuType<C>> getMenuType() {
return Optional.empty();
}

@Override
public RecipeType<CraftingRecipe> getRecipeType() {
return RecipeTypes.CRAFTING;
}

@Nullable
@Override
public IRecipeTransferError transferRecipe(C container, CraftingRecipe recipe, IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) {
Optional<? extends UpgradeContainerBase<?, ?>> potentialCraftingContainer = container.getOpenOrFirstCraftingContainer();
public IRecipeTransferError transferRecipe(C container, R recipe, IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) {
Optional<? extends UpgradeContainerBase<?, ?>> potentialCraftingContainer = container.getOpenOrFirstCraftingContainer(recipe.getType());
if (potentialCraftingContainer.isEmpty()) {
return handlerHelper.createInternalError();
}
Expand Down Expand Up @@ -108,13 +107,17 @@ public IRecipeTransferError transferRecipe(C container, CraftingRecipe recipe, I
openOrFirstCraftingContainer.setIsOpen(true);
container.setOpenTabId(openOrFirstCraftingContainer.getUpgradeContainerId());
}
TransferRecipeMessage message = new TransferRecipeMessage(
recipe.getId(),
toMap(transferOperations.results),
craftingSlotIndexes,
inventorySlotIndexes,
maxTransfer);
PacketHandler.INSTANCE.sendToServer(message);
ResourceLocation recipeTypeId = ForgeRegistries.RECIPE_TYPES.getKey(recipe.getType());
if (recipeTypeId != null) {
TransferRecipeMessage message = new TransferRecipeMessage(
recipe.getId(),
recipeTypeId,
toMap(transferOperations.results),
craftingSlotIndexes,
inventorySlotIndexes,
maxTransfer);
PacketHandler.INSTANCE.sendToServer(message);
}
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeType;
import net.p3pp3rf1y.sophisticatedcore.common.gui.StorageContainerMenuBase;

import javax.annotation.Nullable;
Expand All @@ -16,7 +17,7 @@ private CraftingContainerRecipeTransferHandlerServer() {}
/**
* Called server-side to actually put the items in place.
*/
public static void setItems(Player player, ResourceLocation recipeId, Map<Integer, Integer> slotIdMap, List<Integer> craftingSlots, List<Integer> inventorySlots, boolean maxTransfer) {
public static void setItems(Player player, ResourceLocation recipeId, RecipeType<?> recipeType, Map<Integer, Integer> slotIdMap, List<Integer> craftingSlots, List<Integer> inventorySlots, boolean maxTransfer) {
if (!(player.containerMenu instanceof StorageContainerMenuBase<?> container)) {
return;
}
Expand All @@ -41,7 +42,7 @@ public static void setItems(Player player, ResourceLocation recipeId, Map<Intege
}

// clear the crafting grid
List<ItemStack> clearedCraftingItems = clearAndPutItemsIntoGrid(player, recipeId, craftingSlots, container, toTransfer);
List<ItemStack> clearedCraftingItems = clearAndPutItemsIntoGrid(player, recipeId, recipeType, craftingSlots, container, toTransfer);

putIntoInventory(player, inventorySlots, container, clearedCraftingItems);

Expand All @@ -57,7 +58,7 @@ private static void putIntoInventory(Player player, List<Integer> inventorySlots
}
}

private static List<ItemStack> clearAndPutItemsIntoGrid(Player player, ResourceLocation recipeId, List<Integer> craftingSlots, AbstractContainerMenu container, Map<Integer, ItemStack> toTransfer) {
private static List<ItemStack> clearAndPutItemsIntoGrid(Player player, ResourceLocation recipeId, RecipeType<?> recipeType, List<Integer> craftingSlots, AbstractContainerMenu container, Map<Integer, ItemStack> toTransfer) {
List<ItemStack> clearedCraftingItems = new ArrayList<>();
int minSlotStackLimit = Integer.MAX_VALUE;
for (int craftingSlotNumberIndex = 0; craftingSlotNumberIndex < craftingSlots.size(); craftingSlotNumberIndex++) {
Expand All @@ -80,7 +81,7 @@ private static List<ItemStack> clearAndPutItemsIntoGrid(Player player, ResourceL
// put items into the crafting grid
putItemIntoGrid(container, toTransfer, clearedCraftingItems, minSlotStackLimit);
if (container instanceof StorageContainerMenuBase<?> storageContainerMenu) {
storageContainerMenu.getOpenOrFirstCraftingContainer().ifPresent(c -> c.setRecipeUsed(recipeId));
storageContainerMenu.getOpenOrFirstCraftingContainer(recipeType).ifPresent(c -> c. setRecipeUsed(recipeId));
}
return clearedCraftingItems;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.registries.ForgeRegistries;

import javax.annotation.Nullable;
import java.util.ArrayList;
Expand All @@ -13,14 +15,16 @@
import java.util.function.Supplier;

public class TransferRecipeMessage {
private final ResourceLocation recipeTypeId;
private final Map<Integer, Integer> matchingItems;
private final List<Integer> craftingSlotIndexes;
private final List<Integer> inventorySlotIndexes;
private final boolean maxTransfer;
private final ResourceLocation recipeId;

public TransferRecipeMessage(ResourceLocation recipeId, Map<Integer, Integer> matchingItems, List<Integer> craftingSlotIndexes, List<Integer> inventorySlotIndexes, boolean maxTransfer) {
public TransferRecipeMessage(ResourceLocation recipeId, ResourceLocation recipeTypeId, Map<Integer, Integer> matchingItems, List<Integer> craftingSlotIndexes, List<Integer> inventorySlotIndexes, boolean maxTransfer) {
this.recipeId = recipeId;
this.recipeTypeId = recipeTypeId;
this.matchingItems = matchingItems;
this.craftingSlotIndexes = craftingSlotIndexes;
this.inventorySlotIndexes = inventorySlotIndexes;
Expand All @@ -29,6 +33,7 @@ public TransferRecipeMessage(ResourceLocation recipeId, Map<Integer, Integer> ma

public static void encode(TransferRecipeMessage msg, FriendlyByteBuf packetBuffer) {
packetBuffer.writeResourceLocation(msg.recipeId);
packetBuffer.writeResourceLocation(msg.recipeTypeId);
writeMap(packetBuffer, msg.matchingItems);
writeList(packetBuffer, msg.craftingSlotIndexes);
writeList(packetBuffer, msg.inventorySlotIndexes);
Expand All @@ -49,7 +54,7 @@ private static void writeList(FriendlyByteBuf packetBuffer, List<Integer> list)
}

public static TransferRecipeMessage decode(FriendlyByteBuf packetBuffer) {
return new TransferRecipeMessage(packetBuffer.readResourceLocation(), readMap(packetBuffer), readList(packetBuffer), readList(packetBuffer), packetBuffer.readBoolean());
return new TransferRecipeMessage(packetBuffer.readResourceLocation(), packetBuffer.readResourceLocation(), readMap(packetBuffer), readList(packetBuffer), readList(packetBuffer), packetBuffer.readBoolean());
}

private static Map<Integer, Integer> readMap(FriendlyByteBuf packetBuffer) {
Expand Down Expand Up @@ -80,6 +85,11 @@ private static void handleMessage(TransferRecipeMessage msg, @Nullable ServerPla
if (sender == null) {
return;
}
CraftingContainerRecipeTransferHandlerServer.setItems(sender, msg.recipeId, msg.matchingItems, msg.craftingSlotIndexes, msg.inventorySlotIndexes, msg.maxTransfer);

RecipeType<?> recipeType = ForgeRegistries.RECIPE_TYPES.getValue(msg.recipeTypeId);
if (recipeType == null) {
return;
}
CraftingContainerRecipeTransferHandlerServer.setItems(sender, msg.recipeId, recipeType, msg.matchingItems, msg.craftingSlotIndexes, msg.inventorySlotIndexes, msg.maxTransfer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ public void setRecipeUsed(ResourceLocation recipeId) {
});
}

@Override
public RecipeType<?> getRecipeType() {
return RecipeType.CRAFTING;
}

public boolean shouldShiftClickIntoStorage() {
return upgradeWrapper.shouldShiftClickIntoStorage();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.NonNullList;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player;
Expand All @@ -26,6 +28,7 @@
import net.minecraftforge.registries.ForgeRegistries;
import net.p3pp3rf1y.sophisticatedcore.SophisticatedCore;

import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -279,7 +282,7 @@ public boolean stillValid(Player playerIn) {
}

public static <T extends AbstractCookingRecipe> Optional<T> getCookingRecipe(ItemStack stack, RecipeType<T> recipeType) {
return getLevel().flatMap(w -> safeGetRecipeFor(recipeType, new RecipeWrapper(new ItemStackHandler(NonNullList.of(ItemStack.EMPTY, stack))), w));
return getLevel().flatMap(w -> safeGetRecipeFor(recipeType, new RecipeWrapper(new ItemStackHandler(NonNullList.of(ItemStack.EMPTY, stack))), w, null));
}

public static Set<CompactingShape> getItemCompactingShapes(Item item) {
Expand All @@ -290,9 +293,13 @@ public static <T extends Recipe<Container>> List<T> getRecipesOfType(RecipeType<
return getLevel().map(w -> w.getRecipeManager().getRecipesFor(recipeType, inventory, w)).orElse(Collections.emptyList());
}

public static <C extends Container, T extends Recipe<C>> Optional<T> safeGetRecipeFor(RecipeType<T> recipeType, C inventory, Level level) {
public static <C extends Container, T extends Recipe<C>> Optional<T> safeGetRecipeFor(RecipeType<T> recipeType, C inventory, @Nullable ResourceLocation recipeId) {
return getLevel().flatMap(w -> safeGetRecipeFor(recipeType, inventory, w, recipeId));
}

public static <C extends Container, T extends Recipe<C>> Optional<T> safeGetRecipeFor(RecipeType<T> recipeType, C inventory, Level level, @Nullable ResourceLocation recipeId) {
try {
return level.getRecipeManager().getRecipeFor(recipeType, inventory, level);
return level.getRecipeManager().getRecipeFor(recipeType, inventory, level, recipeId).map(Pair::getSecond);
} catch (Exception e) {
SophisticatedCore.LOGGER.error("Error while getting recipe ", e);
return Optional.empty();
Expand Down

0 comments on commit bf05bcd

Please sign in to comment.