Skip to content

Commit

Permalink
wip: Continue port to Minecraft 1.21.2
Browse files Browse the repository at this point in the history
  • Loading branch information
BlayTheNinth committed Oct 22, 2024
1 parent 20992da commit 35c7e08
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ public interface KitchenRecipeHandler<T extends Recipe<?>> {

List<Optional<Ingredient>> getIngredients(T recipe);

ItemStack predictResultItem(T recipe);

ItemStack assemble(CraftingContext context, T recipe, List<IngredientToken> ingredientTokens, RegistryAccess registryAccess);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import net.minecraft.network.chat.Component;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.display.FurnaceRecipeDisplay;

public class CookingForBlockheadsClient {
public static void initialize() {
Expand All @@ -39,10 +40,10 @@ public static void initialize() {
return;
}

final var selectedRecipe = selectedRecipeWithStatus.recipe(player).value();
final var selectedRecipeDisplay = selectedRecipeWithStatus.recipeDisplayEntry().display();

if (menu.isSelectedSlot(listingSlot) && kitchen.canProcess(RecipeType.CRAFTING)) {
if (selectedRecipe.getType() == RecipeType.SMELTING) {
if (selectedRecipeDisplay instanceof FurnaceRecipeDisplay) {
if (!kitchen.canProcess(RecipeType.SMELTING)) {
event.getToolTip().add(Component.translatable("tooltip.cookingforblockheads.missing_oven").withStyle(ChatFormatting.RED));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.display.FurnaceRecipeDisplay;
import org.lwjgl.glfw.GLFW;

import java.util.ArrayList;
Expand Down Expand Up @@ -242,7 +243,7 @@ protected void renderBg(GuiGraphics guiGraphics, float partialTicks, int mouseX,
guiGraphics.drawString(font, s, leftPos + 23 + 27 - font.width(s) / 2, curY, 0xFFFFFFFF, true);
curY += font.lineHeight + 5;
}
} else if (selection.recipe(Minecraft.getInstance().player).value().getType() == RecipeType.SMELTING) {
} else if (selection.recipeDisplayEntry().display() instanceof FurnaceRecipeDisplay) {
guiGraphics.blit(RenderType::guiTextured, guiTexture, leftPos + 23, topPos + 19, 54, 184, 54, 54, 256, 256);
} else {
guiGraphics.blit(RenderType::guiTextured, guiTexture, leftPos + 23, topPos + 19, 0, 184, 54, 54, 256, 256);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package net.blay09.mods.cookingforblockheads.crafting;

import net.blay09.mods.cookingforblockheads.mixin.ShapedRecipeAccessor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.ShapedRecipe;

Expand All @@ -23,4 +25,9 @@ public int mapToMatrixSlot(ShapedRecipe recipe, int ingredientIndex) {
public List<Optional<Ingredient>> getIngredients(ShapedRecipe recipe) {
return recipe.getIngredients();
}

@Override
public ItemStack predictResultItem(ShapedRecipe recipe) {
return ((ShapedRecipeAccessor) recipe).getResult();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.blay09.mods.cookingforblockheads.crafting;

import net.blay09.mods.cookingforblockheads.mixin.ShapelessRecipeAccessor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.ShapelessRecipe;

Expand All @@ -17,4 +18,9 @@ public int mapToMatrixSlot(ShapelessRecipe recipe, int ingredientIndex) {
public List<Optional<Ingredient>> getIngredients(ShapelessRecipe recipe) {
return recipe instanceof ShapelessRecipeAccessor accessor ? accessor.getIngredients() : List.of();
}

@Override
public ItemStack predictResultItem(ShapelessRecipe recipe) {
return ((ShapelessRecipeAccessor) recipe).getResult();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.blay09.mods.cookingforblockheads.api.IngredientToken;
import net.blay09.mods.cookingforblockheads.api.KitchenRecipeHandler;
import net.blay09.mods.cookingforblockheads.mixin.SingleItemRecipeAccessor;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
Expand Down Expand Up @@ -32,4 +33,9 @@ public ItemStack assemble(CraftingContext context, SmeltingRecipe recipe, List<I

return ItemStack.EMPTY;
}

@Override
public ItemStack predictResultItem(SmeltingRecipe recipe) {
return ((SingleItemRecipeAccessor) recipe).getResult();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,19 @@
import net.blay09.mods.cookingforblockheads.tag.ModItemTags;
import net.minecraft.core.NonNullList;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.display.RecipeDisplayEntry;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

public record RecipeWithStatus(ResourceLocation recipeId, ItemStack resultItem, List<Ingredient> missingIngredients,
public record RecipeWithStatus(RecipeDisplayEntry recipeDisplayEntry, List<Ingredient> missingIngredients,
int missingIngredientsMask, NonNullList<ItemStack> lockedInputs) {

public RecipeHolder<?> recipe(Player player) {
return player.level().getRecipeManager().byKey(recipeId).orElse(null);
}

public void toNetwork(RegistryFriendlyByteBuf buf) {
buf.writeResourceLocation(recipeId);
ItemStack.STREAM_CODEC.encode(buf, resultItem);
RecipeDisplayEntry.STREAM_CODEC.encode(buf, recipeDisplayEntry);
buf.writeInt(missingIngredientsMask);
buf.writeInt(missingIngredients.size());
for (final var ingredient : missingIngredients) {
Expand All @@ -39,8 +32,7 @@ public void toNetwork(RegistryFriendlyByteBuf buf) {
}

public static RecipeWithStatus fromNetwork(RegistryFriendlyByteBuf buf) {
final var recipeId = buf.readResourceLocation();
final var resultItem = ItemStack.STREAM_CODEC.decode(buf);
final var recipeDisplayEntry = RecipeDisplayEntry.STREAM_CODEC.decode(buf);
final var missingIngredientsMask = buf.readInt();
final var missingIngredientCount = buf.readInt();
final var missingIngredients = new ArrayList<Ingredient>(missingIngredientCount);
Expand All @@ -52,7 +44,7 @@ public static RecipeWithStatus fromNetwork(RegistryFriendlyByteBuf buf) {
for (int j = 0; j < lockedInputCount; j++) {
lockedInputs.set(j, ItemStack.OPTIONAL_STREAM_CODEC.decode(buf));
}
return new RecipeWithStatus(recipeId, resultItem, missingIngredients, missingIngredientsMask, lockedInputs);
return new RecipeWithStatus(recipeDisplayEntry, missingIngredients, missingIngredientsMask, lockedInputs);
}

public static RecipeWithStatus best(@Nullable RecipeWithStatus first, @Nullable RecipeWithStatus second) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeInput;
import net.minecraft.world.item.crafting.display.RecipeDisplayId;
import org.jetbrains.annotations.Nullable;

import java.util.*;
Expand Down Expand Up @@ -230,10 +231,7 @@ public void handleRequestSelectionRecipes(ItemStack resultItem, NonNullList<Item
private void requestCraft(boolean craftFullStack, boolean addToInventory) {
final var selectedRecipe = getSelectedRecipe();
if (selectedRecipe != null) {
final var recipe = selectedRecipe.recipe(player);
if (kitchen.canProcess(recipe.value().getType())) {
Balm.getNetworking().sendToServer(new CraftRecipeMessage(recipe.id(), lockedInputs, craftFullStack, addToInventory));
}
Balm.getNetworking().sendToServer(new CraftRecipeMessage(selectedRecipe.recipeDisplayEntry().id(), lockedInputs, craftFullStack, addToInventory));
}
}

Expand Down Expand Up @@ -295,43 +293,41 @@ public void broadcastAvailableRecipes() {

public void broadcastRecipesForResultItem(ItemStack resultItem) {
final List<RecipeWithStatus> result = new ArrayList<>();
final var recipeManager = player.getServer().getRecipeManager();

final var context = new CraftingContext(kitchen, player);
final var recipesForResult = getRecipesFor(resultItem);
for (final var recipe : recipesForResult) {
final var recipeResultItem = recipe.value().getResultItem(player.level().registryAccess());
final var operation = context.createOperation(recipe).withLockedInputs(lockedInputs).prepare();

result.add(new RecipeWithStatus(recipe.id(),
recipeResultItem,
recipeManager.listDisplaysForRecipe(recipe.id(), recipeDisplayEntry -> result.add(new RecipeWithStatus(recipeDisplayEntry,
operation.getMissingIngredients(),
operation.getMissingIngredientsMask(),
operation.getLockedInputs()));
operation.getLockedInputs())));
}

result.sort(currentSorting);
this.recipesForSelection = result;
Balm.getNetworking().sendTo(player, new SelectionRecipesListMessage(result));
}

public void craft(ResourceLocation recipeId, NonNullList<ItemStack> lockedInputs, boolean craftFullStack, boolean addToInventory) {
public void craft(RecipeDisplayId recipeDisplayId, NonNullList<ItemStack> lockedInputs, boolean craftFullStack, boolean addToInventory) {
final var level = player.level();
final var recipe = (RecipeHolder<Recipe<?>>) level.getRecipeManager().byKey(recipeId).orElse(null);
final var recipe = (RecipeHolder<Recipe<?>>) level.getServer().getRecipeManager().getRecipeFromDisplay(recipeDisplayId).parent();
if (recipe == null) {
CookingForBlockheads.logger.error("Received invalid recipe from client: {}", recipeId);
CookingForBlockheads.logger.error("Received invalid recipe from client: {}", recipeDisplayId);
return;
}

if (!kitchen.canProcess(recipe.value().getType())) {
CookingForBlockheads.logger.error("Received invalid craft request, unprocessable recipe {}", recipeId);
CookingForBlockheads.logger.error("Received invalid craft request, unprocessable recipe {}", recipeDisplayId);
return;
}

var craftable = this.craftables.stream().filter(it -> it.recipe(player) == recipe).findAny().orElse(null);
if (craftable == null) {
craftable = this.recipesForSelection.stream().filter(it -> it.recipe(player) == recipe).findAny().orElse(null);
if (craftable == null) {
CookingForBlockheads.logger.error("Received invalid craft request, unknown recipe {}", recipeId);
CookingForBlockheads.logger.error("Received invalid craft request, unknown recipe {}", recipeDisplayId);
return;
}
}
Expand Down Expand Up @@ -417,7 +413,8 @@ public void updateCraftableSlots() {
for (final var slot : recipeListingSlots) {
if (i < filteredCraftables.size()) {
final var craftable = filteredCraftables.get(i);
if (craftable != null && selectedCraftable != null && ItemStack.isSameItemSameComponents(selectedCraftable.resultItem(), craftable.resultItem())) {
if (craftable != null && selectedCraftable != null && ItemStack.isSameItemSameComponents(selectedCraftable.resultItem(),
craftable.resultItem())) {
final var selectedRecipe = getSelectedRecipe();
slot.setCraftable(selectedRecipe != null ? selectedRecipe : craftable);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package net.blay09.mods.cookingforblockheads.mixin;

import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.item.crafting.RecipeMap;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(RecipeManager.class)
public interface RecipeManagerAccessor {
@Accessor
RecipeMap getRecipes();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package net.blay09.mods.cookingforblockheads.mixin;

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

@Mixin(ShapedRecipe.class)
public interface ShapedRecipeAccessor {
@Accessor
ItemStack getResult();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.blay09.mods.cookingforblockheads.mixin;

import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.ShapelessRecipe;
import org.spongepowered.asm.mixin.Mixin;
Expand All @@ -12,4 +13,7 @@
public interface ShapelessRecipeAccessor {
@Accessor
List<Optional<Ingredient>> getIngredients();

@Accessor
ItemStack getResult();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package net.blay09.mods.cookingforblockheads.mixin;

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

@Mixin(SingleItemRecipe.class)
public interface SingleItemRecipeAccessor {
@Accessor
ItemStack getResult();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,28 @@
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.display.RecipeDisplayId;
import org.jetbrains.annotations.Nullable;

public class CraftRecipeMessage implements CustomPacketPayload {

public static final CustomPacketPayload.Type<CraftRecipeMessage> TYPE = new CustomPacketPayload.Type<>(ResourceLocation.fromNamespaceAndPath(CookingForBlockheads.MOD_ID,
"craft_recipe"));

private final ResourceLocation recipeId;
private final RecipeDisplayId recipeDisplayId;
private final NonNullList<ItemStack> lockedInputs;
private final boolean craftFullStack;
private final boolean addToInventory;

public CraftRecipeMessage(ResourceLocation recipeId, @Nullable NonNullList<ItemStack> lockedInputs, boolean craftFullStack, boolean addToInventory) {
this.recipeId = recipeId;
public CraftRecipeMessage(RecipeDisplayId recipeDisplayId, @Nullable NonNullList<ItemStack> lockedInputs, boolean craftFullStack, boolean addToInventory) {
this.recipeDisplayId = recipeDisplayId;
this.lockedInputs = lockedInputs;
this.craftFullStack = craftFullStack;
this.addToInventory = addToInventory;
}

public static void encode(RegistryFriendlyByteBuf buf, CraftRecipeMessage message) {
buf.writeResourceLocation(message.recipeId);
RecipeDisplayId.STREAM_CODEC.encode(buf, message.recipeDisplayId);
if (message.lockedInputs != null) {
buf.writeByte(message.lockedInputs.size());
for (ItemStack itemstack : message.lockedInputs) {
Expand All @@ -45,21 +46,21 @@ public static void encode(RegistryFriendlyByteBuf buf, CraftRecipeMessage messag
}

public static CraftRecipeMessage decode(RegistryFriendlyByteBuf buf) {
final var recipeId = buf.readResourceLocation();
final var recipeDisplayId = RecipeDisplayId.STREAM_CODEC.decode(buf);
final var lockedInputsCount = buf.readByte();
NonNullList<ItemStack> lockedInputs = NonNullList.createWithCapacity(lockedInputsCount);
for (int i = 0; i < lockedInputsCount; i++) {
lockedInputs.add( ItemStack.OPTIONAL_STREAM_CODEC.decode(buf));
}
final var craftFullStack = buf.readBoolean();
final var addToInventory = buf.readBoolean();
return new CraftRecipeMessage(recipeId, lockedInputs, craftFullStack, addToInventory);
return new CraftRecipeMessage(recipeDisplayId, lockedInputs, craftFullStack, addToInventory);
}

public static void handle(ServerPlayer player, CraftRecipeMessage message) {
AbstractContainerMenu container = player.containerMenu;
if (container instanceof KitchenMenu kitchenMenu) {
kitchenMenu.craft(message.recipeId, message.lockedInputs, message.craftFullStack, message.addToInventory);
kitchenMenu.craft(message.recipeDisplayId, message.lockedInputs, message.craftFullStack, message.addToInventory);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import com.google.common.collect.Multimap;
import net.blay09.mods.balm.api.Balm;
import net.blay09.mods.balm.api.event.BalmEvents;
import net.blay09.mods.balm.api.event.client.RecipesUpdatedEvent;
import net.blay09.mods.balm.api.event.server.ServerReloadFinishedEvent;
import net.blay09.mods.balm.api.event.server.ServerStartedEvent;
import net.blay09.mods.cookingforblockheads.CookingForBlockheadsConfig;
import net.blay09.mods.cookingforblockheads.api.ISortButton;
import net.blay09.mods.cookingforblockheads.api.KitchenRecipeGroup;
import net.blay09.mods.cookingforblockheads.api.KitchenRecipeHandler;
import net.blay09.mods.cookingforblockheads.mixin.RecipeManagerAccessor;
import net.blay09.mods.cookingforblockheads.tag.ModItemTags;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.component.DataComponents;
Expand Down Expand Up @@ -41,12 +41,14 @@ private static void reload(RecipeManager recipeManager, RegistryAccess registryA
}

private static <C extends RecipeInput, T extends Recipe<C>> void loadRecipesByType(RecipeManager recipeManager, RegistryAccess registryAccess, RecipeType<T> recipeType) {
for (final var recipe : recipeManager.getRecipesFor(recipeType)) {
final var recipeMap = ((RecipeManagerAccessor) recipeManager).getRecipes();
for (final var recipe : recipeMap.byType(recipeType)) {
if (!isEligibleRecipe(recipe)) {
continue;
}

final var resultItem = recipe.value().getResultItem(registryAccess);
final var recipeHandler = getKitchenRecipeHandler(recipe.value());
final var resultItem = recipeHandler.predictResultItem(recipe.value());
if (isEligibleResultItem(resultItem)) {
final var itemId = Balm.getRegistries().getKey(resultItem.getItem());
recipesByItemId.put(itemId, (RecipeHolder<Recipe<?>>) recipe);
Expand Down Expand Up @@ -78,7 +80,7 @@ private static boolean isEligibleResultItem(ItemStack itemStack) {
}

private static <T extends RecipeInput> boolean isEligibleRecipe(RecipeHolder<? extends Recipe<T>> recipe) {
return !CookingForBlockheadsConfig.getActive().excludedRecipes.contains(recipe.id());
return !CookingForBlockheadsConfig.getActive().excludedRecipes.contains(recipe.id().location());
}

public static <C extends RecipeInput, T extends Recipe<C>> void registerKitchenRecipeHandler(Class<T> recipeType, KitchenRecipeHandler<T> handler) {
Expand Down
5 changes: 4 additions & 1 deletion common/src/main/resources/cookingforblockheads.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"compatibilityLevel": "JAVA_17",
"refmap": "cookingforblockheads.refmap.json",
"mixins": [
"ShapelessRecipeAccessor"
"ShapelessRecipeAccessor",
"ShapedRecipeAccessor",
"SingleItemRecipeAccessor",
"RecipeManagerAccessor"
],
"client": [
],
Expand Down

0 comments on commit 35c7e08

Please sign in to comment.