JEI写样板支持shift控制启用物品替换,alt启用流体替换

This commit is contained in:
GaLi 2026-03-03 10:53:05 +08:00
parent a389b7ba5e
commit 45fdf749b1
3 changed files with 56 additions and 28 deletions

View File

@ -4,6 +4,7 @@ import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.client.ModKeybindings;
import com.extendedae_plus.init.ModNetwork;
import com.extendedae_plus.integration.jei.JeiRuntimeProxy;
import com.extendedae_plus.network.pattern.CreateAndUploadPatternC2SPacket;
import com.extendedae_plus.network.pattern.CreateCtrlQPatternC2SPacket;
import com.extendedae_plus.network.provider.RequestProvidersListC2SPacket;
import com.extendedae_plus.util.RecipeFinderUtil;
@ -22,7 +23,9 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.lwjgl.glfw.GLFW;
import java.sql.SQLOutput;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -42,8 +45,10 @@ public class CtrlQPatternKeyHandler {
Screen screen = event.getScreen();
int keyCode = event.getKeyCode();
int scanCode = event.getScanCode();
boolean isAllowSubstitutes = Screen.hasShiftDown();
boolean isFluidSubstitutes = Screen.hasAltDown();
// 使用 KeyMapping 检测按键包含修饰键
// 使用 KeyMapping
if (!ModKeybindings.CREATE_PATTERN_KEY.matches(keyCode, scanCode)) {
return;
}
@ -58,7 +63,7 @@ public class CtrlQPatternKeyHandler {
if (recipeBookmark.isPresent()) {
// 配方书签分支处理带有配方类型的书签
handleRecipeBookmark(recipeBookmark.get());
handleRecipeBookmark(recipeBookmark.get(),isAllowSubstitutes,isFluidSubstitutes);
event.setCanceled(true);
return;
}
@ -106,12 +111,17 @@ public class CtrlQPatternKeyHandler {
// 获取输出材料转换为 ItemStack流体会被包装
List<ItemStack> selectedOutputs = convertOutputsToItemStacks(selectedRecipeInfo);
System.out.println("sendPackage");
// 发送网络包到服务器
ModNetwork.CHANNEL.sendToServer(new CreateCtrlQPatternC2SPacket(
selectedRecipeInfo.getRecipe().getId(),
selectedRecipeInfo.isCraftingRecipe(),
selectedIngredients,
selectedOutputs
selectedOutputs,
false,
isAllowSubstitutes,
isFluidSubstitutes
));
// 消耗事件防止传播
@ -123,14 +133,14 @@ public class CtrlQPatternKeyHandler {
*
* @param recipeBookmark 配方书签对象RecipeBookmark<?, ?>
*/
private static void handleRecipeBookmark(Object recipeBookmark) {
private static void handleRecipeBookmark(Object recipeBookmark,boolean isAllowSubstitutes,boolean isFluidSubstitutes) {
// 判断配方类型
if (isCraftingRecipe(recipeBookmark)) {
// 合成配方分支
handleCraftingRecipeBookmark(recipeBookmark);
handleCraftingRecipeBookmark(recipeBookmark,isAllowSubstitutes,isFluidSubstitutes);
} else {
// 其他配方分支加工配方等
handleProcessingRecipeBookmark(recipeBookmark);
handleProcessingRecipeBookmark(recipeBookmark,isAllowSubstitutes,isFluidSubstitutes);
}
}
@ -163,7 +173,7 @@ public class CtrlQPatternKeyHandler {
*
* @param recipeBookmark 配方书签对象
*/
private static void handleCraftingRecipeBookmark(Object recipeBookmark) {
private static void handleCraftingRecipeBookmark(Object recipeBookmark,boolean isAllowSubstitutes,boolean isFluidSubstitutes) {
try {
// 1. 获取配方ID
net.minecraft.resources.ResourceLocation recipeId = getRecipeIdCompat(recipeBookmark);
@ -274,11 +284,13 @@ public class CtrlQPatternKeyHandler {
List<ItemStack> selectedOutputs = convertOutputsToItemStacks(matchingRecipeInfo);
// 11. 发送网络包创建样板并上传到装配矩阵
ModNetwork.CHANNEL.sendToServer(new com.extendedae_plus.network.pattern.CreateAndUploadPatternC2SPacket(
ModNetwork.CHANNEL.sendToServer(new CreateAndUploadPatternC2SPacket(
recipeId,
matchingRecipeInfo.isCraftingRecipe(),
selectedIngredients,
selectedOutputs
selectedOutputs,
isAllowSubstitutes,
isFluidSubstitutes
));
} catch (Exception e) {
@ -291,7 +303,7 @@ public class CtrlQPatternKeyHandler {
*
* @param recipeBookmark 配方书签对象
*/
private static void handleProcessingRecipeBookmark(Object recipeBookmark) {
private static void handleProcessingRecipeBookmark(Object recipeBookmark,boolean isAllowSubstitutes,boolean isFluidSubstitutes) {
try {
net.minecraft.resources.ResourceLocation recipeId = getRecipeIdCompat(recipeBookmark);
if (recipeId == null) {
@ -382,7 +394,9 @@ public class CtrlQPatternKeyHandler {
matchingRecipeInfo.isCraftingRecipe(),
selectedIngredients,
selectedOutputs,
true
true,
isAllowSubstitutes,
isFluidSubstitutes
));
ModNetwork.CHANNEL.sendToServer(new RequestProvidersListC2SPacket());
@ -396,7 +410,6 @@ public class CtrlQPatternKeyHandler {
return null;
}
// JEI 1.20 分支
try {
var getRecipeUidMethod = recipeBookmark.getClass().getMethod("getRecipeUid");
Object recipeId = getRecipeUidMethod.invoke(recipeBookmark);
@ -406,7 +419,6 @@ public class CtrlQPatternKeyHandler {
} catch (Throwable ignored) {
}
// JEI 1.21+ 分支
try {
Object recipe = recipeBookmark.getClass().getMethod("getRecipe").invoke(recipeBookmark);
Object recipeCategory = recipeBookmark.getClass().getMethod("getRecipeCategory").invoke(recipeBookmark);

View File

@ -42,12 +42,16 @@ public class CreateAndUploadPatternC2SPacket {
private final boolean isCraftingPattern;
private final List<ItemStack> selectedIngredients;
private final List<ItemStack> outputs;
private final boolean isAllowSubstitutes;
private final boolean isFluidSubstitutes;
public CreateAndUploadPatternC2SPacket(ResourceLocation recipeId, boolean isCraftingPattern, List<ItemStack> selectedIngredients, List<ItemStack> outputs) {
public CreateAndUploadPatternC2SPacket(ResourceLocation recipeId, boolean isCraftingPattern, List<ItemStack> selectedIngredients, List<ItemStack> outputs, boolean isAllowSubstitutes, boolean isFluidSubstitutes) {
this.recipeId = recipeId;
this.isCraftingPattern = isCraftingPattern;
this.selectedIngredients = selectedIngredients;
this.outputs = outputs;
this.isAllowSubstitutes = isAllowSubstitutes;
this.isFluidSubstitutes = isFluidSubstitutes;
}
public static void encode(CreateAndUploadPatternC2SPacket msg, FriendlyByteBuf buf) {
@ -61,6 +65,8 @@ public class CreateAndUploadPatternC2SPacket {
for (ItemStack stack : msg.outputs) {
buf.writeItem(stack);
}
buf.writeBoolean(msg.isAllowSubstitutes);
buf.writeBoolean(msg.isFluidSubstitutes);
}
public static CreateAndUploadPatternC2SPacket decode(FriendlyByteBuf buf) {
@ -76,7 +82,9 @@ public class CreateAndUploadPatternC2SPacket {
for (int i = 0; i < outputCount; i++) {
outputs.add(buf.readItem());
}
return new CreateAndUploadPatternC2SPacket(recipeId, isCraftingPattern, ingredients, outputs);
boolean isAllowSubstitutes = buf.readBoolean();
boolean isFluidSubstitutes = buf.readBoolean();
return new CreateAndUploadPatternC2SPacket(recipeId, isCraftingPattern, ingredients, outputs,isAllowSubstitutes,isFluidSubstitutes);
}
public static void handle(CreateAndUploadPatternC2SPacket msg, Supplier<NetworkEvent.Context> ctxSupplier) {
@ -121,7 +129,7 @@ public class CreateAndUploadPatternC2SPacket {
}
// 4. 创建样板
ItemStack pattern = createPattern(recipe, msg.isCraftingPattern, msg.selectedIngredients, msg.outputs, player);
ItemStack pattern = createPattern(recipe, msg.isCraftingPattern, msg.selectedIngredients, msg.outputs,msg.isAllowSubstitutes,msg.isFluidSubstitutes, player);
if (pattern.isEmpty()) {
// 创建失败退还空白样板到网络
@ -222,7 +230,7 @@ public class CreateAndUploadPatternC2SPacket {
/**
* 从配方创建样板
*/
private static ItemStack createPattern(Recipe<?> recipe, boolean isCrafting, List<ItemStack> selectedIngredients, List<ItemStack> selectedOutputs, ServerPlayer player) {
private static ItemStack createPattern(Recipe<?> recipe, boolean isCrafting, List<ItemStack> selectedIngredients, List<ItemStack> selectedOutputs, boolean isAllowSubstitutes, boolean isFluidSubstitutes, ServerPlayer player) {
try {
if (isCrafting && recipe instanceof CraftingRecipe craftingRecipe) {
// 合成样板
@ -241,8 +249,8 @@ public class CreateAndUploadPatternC2SPacket {
craftingRecipe,
inputs,
output,
true,
false
isAllowSubstitutes,
isFluidSubstitutes
);
encodedPattern.getOrCreateTag().putString("encodePlayer", player.getName().getString());

View File

@ -41,17 +41,21 @@ public class CreateCtrlQPatternC2SPacket {
private final List<ItemStack> selectedIngredients;
private final List<ItemStack> outputs;
private final boolean openProviderSelector;
private final boolean isAllowSubstitutes;
private final boolean isFluidSubstitutes;
public CreateCtrlQPatternC2SPacket(ResourceLocation recipeId, boolean isCraftingPattern, List<ItemStack> selectedIngredients, List<ItemStack> outputs) {
this(recipeId, isCraftingPattern, selectedIngredients, outputs, false);
public CreateCtrlQPatternC2SPacket(ResourceLocation recipeId, boolean isCraftingPattern, List<ItemStack> selectedIngredients, List<ItemStack> outputs,boolean isAllowSubstitutes,boolean isFluidSubstitutes) {
this(recipeId, isCraftingPattern, selectedIngredients, outputs, false, isAllowSubstitutes, isFluidSubstitutes);
}
public CreateCtrlQPatternC2SPacket(ResourceLocation recipeId, boolean isCraftingPattern, List<ItemStack> selectedIngredients, List<ItemStack> outputs, boolean openProviderSelector) {
public CreateCtrlQPatternC2SPacket(ResourceLocation recipeId, boolean isCraftingPattern, List<ItemStack> selectedIngredients, List<ItemStack> outputs, boolean openProviderSelector,boolean isAllowSubstitutes,boolean isFluidSubstitutes) {
this.recipeId = recipeId;
this.isCraftingPattern = isCraftingPattern;
this.selectedIngredients = selectedIngredients;
this.outputs = outputs;
this.openProviderSelector = openProviderSelector;
this.isAllowSubstitutes = isAllowSubstitutes;
this.isFluidSubstitutes = isFluidSubstitutes;
}
public static void encode(CreateCtrlQPatternC2SPacket msg, FriendlyByteBuf buf) {
@ -65,6 +69,8 @@ public class CreateCtrlQPatternC2SPacket {
for (ItemStack stack : msg.outputs) {
buf.writeItem(stack);
}
buf.writeBoolean(msg.isAllowSubstitutes);
buf.writeBoolean(msg.isFluidSubstitutes);
buf.writeBoolean(msg.openProviderSelector);
}
@ -84,8 +90,10 @@ public class CreateCtrlQPatternC2SPacket {
outputs.add(buf.readItem());
}
boolean isAllowSubstitutes = buf.readBoolean();
boolean isFluidSubstitutes = buf.readBoolean();
boolean openProviderSelector = buf.readableBytes() > 0 && buf.readBoolean();
return new CreateCtrlQPatternC2SPacket(recipeId, isCraftingPattern, ingredients, outputs, openProviderSelector);
return new CreateCtrlQPatternC2SPacket(recipeId, isCraftingPattern, ingredients, outputs, openProviderSelector,isAllowSubstitutes,isFluidSubstitutes);
}
public static void handle(CreateCtrlQPatternC2SPacket msg, Supplier<NetworkEvent.Context> ctxSupplier) {
@ -110,7 +118,7 @@ public class CreateCtrlQPatternC2SPacket {
return;
}
ItemStack pattern = createPattern(recipe, msg.isCraftingPattern, msg.selectedIngredients, msg.outputs, player);
ItemStack pattern = createPattern(recipe, msg.isCraftingPattern, msg.selectedIngredients, msg.outputs,msg.isAllowSubstitutes,msg.isFluidSubstitutes, player);
if (pattern.isEmpty()) {
player.getInventory().add(AEItems.BLANK_PATTERN.stack());
player.displayClientMessage(Component.translatable("message.extendedae_plus.pattern_creation_failed"), false);
@ -235,7 +243,7 @@ public class CreateCtrlQPatternC2SPacket {
return false;
}
private static ItemStack createPattern(Recipe<?> recipe, boolean isCrafting, List<ItemStack> selectedIngredients, List<ItemStack> selectedOutputs, ServerPlayer player) {
private static ItemStack createPattern(Recipe<?> recipe, boolean isCrafting, List<ItemStack> selectedIngredients, List<ItemStack> selectedOutputs, boolean isAllowSubstitutes,boolean isFluidSubstitutes, ServerPlayer player) {
try {
if (isCrafting && recipe instanceof CraftingRecipe craftingRecipe) {
ItemStack[] inputs = new ItemStack[9];
@ -252,8 +260,8 @@ public class CreateCtrlQPatternC2SPacket {
craftingRecipe,
inputs,
output,
true,
false
isAllowSubstitutes,
isFluidSubstitutes
);
encodedPattern.getOrCreateTag().putString("encodePlayer", player.getName().getString());
@ -302,4 +310,4 @@ public class CreateCtrlQPatternC2SPacket {
return ItemStack.EMPTY;
}
}
}
}