智能系列
This commit is contained in:
parent
5ae5e7a950
commit
5fe2deb0df
11
build.gradle
11
build.gradle
|
|
@ -136,7 +136,6 @@ sourceSets.main.java {
|
||||||
exclude 'com/extendedae_plus/client/**'
|
exclude 'com/extendedae_plus/client/**'
|
||||||
// 包含配置包
|
// 包含配置包
|
||||||
include 'com/extendedae_plus/config/**'
|
include 'com/extendedae_plus/config/**'
|
||||||
exclude 'com/extendedae_plus/content/**'
|
|
||||||
exclude 'com/extendedae_plus/hooks/**'
|
exclude 'com/extendedae_plus/hooks/**'
|
||||||
exclude 'com/extendedae_plus/init/**'
|
exclude 'com/extendedae_plus/init/**'
|
||||||
exclude 'com/extendedae_plus/integration/**'
|
exclude 'com/extendedae_plus/integration/**'
|
||||||
|
|
@ -150,6 +149,8 @@ sourceSets.main.java {
|
||||||
include 'com/extendedae_plus/mixin/ae2/helpers/**'
|
include 'com/extendedae_plus/mixin/ae2/helpers/**'
|
||||||
// 启用 AEProcessingPattern 的 mixin(提供可缩放标记)
|
// 启用 AEProcessingPattern 的 mixin(提供可缩放标记)
|
||||||
include 'com/extendedae_plus/mixin/ae2/AEProcessingPatternMixin.java'
|
include 'com/extendedae_plus/mixin/ae2/AEProcessingPatternMixin.java'
|
||||||
|
// 自动样板缩放注入(CraftingTreeProcess + 其 accessor)
|
||||||
|
include 'com/extendedae_plus/mixin/ae2/autopattern/**'
|
||||||
// GUI 方案A:解禁最小 GUI 混入
|
// GUI 方案A:解禁最小 GUI 混入
|
||||||
include 'com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenMixin.java'
|
include 'com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenMixin.java'
|
||||||
include 'com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java'
|
include 'com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java'
|
||||||
|
|
@ -162,14 +163,22 @@ sourceSets.main.java {
|
||||||
// 仅解禁样板倍增核心所需的两个 util 文件
|
// 仅解禁样板倍增核心所需的两个 util 文件
|
||||||
include 'com/extendedae_plus/util/PatternProviderDataUtil.java'
|
include 'com/extendedae_plus/util/PatternProviderDataUtil.java'
|
||||||
include 'com/extendedae_plus/util/PatternProviderUIHelper.java'
|
include 'com/extendedae_plus/util/PatternProviderUIHelper.java'
|
||||||
|
// 自动样板缩放所需工具类
|
||||||
|
include 'com/extendedae_plus/util/PatternScaler.java'
|
||||||
|
include 'com/extendedae_plus/util/RequestedAmountHolder.java'
|
||||||
// GUI 与网络最小依赖
|
// GUI 与网络最小依赖
|
||||||
// 全量包含 api 包,防止个别接口遗漏
|
// 全量包含 api 包,防止个别接口遗漏
|
||||||
include 'com/extendedae_plus/api/**'
|
include 'com/extendedae_plus/api/**'
|
||||||
include 'com/extendedae_plus/util/ExtendedAELogger.java'
|
include 'com/extendedae_plus/util/ExtendedAELogger.java'
|
||||||
|
// 客户端高亮存储(单文件启用,保持 content 其余文件不参与编译)
|
||||||
|
include 'com/extendedae_plus/content/ClientPatternHighlightStore.java'
|
||||||
|
// 自动样板缩放所需内容类
|
||||||
|
include 'com/extendedae_plus/content/ScaledProcessingPattern.java'
|
||||||
include 'com/extendedae_plus/network/ModNetwork.java'
|
include 'com/extendedae_plus/network/ModNetwork.java'
|
||||||
include 'com/extendedae_plus/network/ToggleAdvancedBlockingC2SPacket.java'
|
include 'com/extendedae_plus/network/ToggleAdvancedBlockingC2SPacket.java'
|
||||||
include 'com/extendedae_plus/network/ToggleSmartDoublingC2SPacket.java'
|
include 'com/extendedae_plus/network/ToggleSmartDoublingC2SPacket.java'
|
||||||
include 'com/extendedae_plus/network/ScalePatternsC2SPacket.java'
|
include 'com/extendedae_plus/network/ScalePatternsC2SPacket.java'
|
||||||
|
include 'com/extendedae_plus/network/SetPatternHighlightS2CPacket.java'
|
||||||
// 仅 include 需要的 util 文件(不再对 util/** 做全局排除,以免误伤)
|
// 仅 include 需要的 util 文件(不再对 util/** 做全局排除,以免误伤)
|
||||||
include 'com/extendedae_plus/util/PatternProviderDataUtil.java'
|
include 'com/extendedae_plus/util/PatternProviderDataUtil.java'
|
||||||
include 'com/extendedae_plus/util/PatternProviderUIHelper.java'
|
include 'com/extendedae_plus/util/PatternProviderUIHelper.java'
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ import appeng.crafting.pattern.AEProcessingPattern;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -19,25 +22,25 @@ public final class ScaledProcessingPattern implements IPatternDetails {
|
||||||
|
|
||||||
private final AEProcessingPattern original; // 原始样板引用
|
private final AEProcessingPattern original; // 原始样板引用
|
||||||
private final AEItemKey definition; // 样板物品
|
private final AEItemKey definition; // 样板物品
|
||||||
private final GenericStack[] sparseInputs; // 缩放后的稀疏输入
|
private final List<GenericStack> sparseInputs; // 缩放后的稀疏输入(List 以适配 1.21 API)
|
||||||
private final GenericStack[] sparseOutputs; // 缩放后的稀疏输出
|
private final List<GenericStack> sparseOutputs; // 缩放后的稀疏输出(List 以适配 1.21 API)
|
||||||
private final IInput[] inputs; // 缩放后的压缩输入
|
private final IInput[] inputs; // 缩放后的压缩输入
|
||||||
private final GenericStack[] condensedOutputs; // 缩放后的压缩输出
|
private final List<GenericStack> condensedOutputs; // 缩放后的压缩输出(List 以适配 1.21 API)
|
||||||
|
|
||||||
public ScaledProcessingPattern(
|
public ScaledProcessingPattern(
|
||||||
AEProcessingPattern original,
|
AEProcessingPattern original,
|
||||||
AEItemKey definition,
|
AEItemKey definition,
|
||||||
GenericStack[] sparseInputs,
|
List<GenericStack> sparseInputs,
|
||||||
GenericStack[] sparseOutputs,
|
List<GenericStack> sparseOutputs,
|
||||||
IInput[] inputs,
|
IInput[] inputs,
|
||||||
GenericStack[] condensedOutputs
|
List<GenericStack> condensedOutputs
|
||||||
) {
|
) {
|
||||||
this.original = Objects.requireNonNull(original);
|
this.original = Objects.requireNonNull(original);
|
||||||
this.definition = Objects.requireNonNull(definition);
|
this.definition = Objects.requireNonNull(definition);
|
||||||
this.sparseInputs = Objects.requireNonNull(sparseInputs);
|
this.sparseInputs = Collections.unmodifiableList(new ArrayList<>(Objects.requireNonNull(sparseInputs)));
|
||||||
this.sparseOutputs = Objects.requireNonNull(sparseOutputs);
|
this.sparseOutputs = Collections.unmodifiableList(new ArrayList<>(Objects.requireNonNull(sparseOutputs)));
|
||||||
this.inputs = Objects.requireNonNull(inputs);
|
this.inputs = Objects.requireNonNull(inputs);
|
||||||
this.condensedOutputs = Objects.requireNonNull(condensedOutputs);
|
this.condensedOutputs = Collections.unmodifiableList(new ArrayList<>(Objects.requireNonNull(condensedOutputs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------- API 实现 -------------------- */
|
/* -------------------- API 实现 -------------------- */
|
||||||
|
|
@ -57,21 +60,21 @@ public final class ScaledProcessingPattern implements IPatternDetails {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenericStack[] getOutputs() {
|
public List<GenericStack> getOutputs() {
|
||||||
return condensedOutputs;
|
return condensedOutputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GenericStack[] getSparseInputs() {
|
public List<GenericStack> getSparseInputs() {
|
||||||
return sparseInputs;
|
return sparseInputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GenericStack[] getSparseOutputs() {
|
public List<GenericStack> getSparseOutputs() {
|
||||||
return sparseOutputs;
|
return sparseOutputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenericStack getPrimaryOutput() {
|
public GenericStack getPrimaryOutput() {
|
||||||
if (condensedOutputs.length > 0) return condensedOutputs[0];
|
if (!condensedOutputs.isEmpty()) return condensedOutputs.get(0);
|
||||||
return original.getPrimaryOutput();
|
return original.getPrimaryOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +86,7 @@ public final class ScaledProcessingPattern implements IPatternDetails {
|
||||||
@Override
|
@Override
|
||||||
public void pushInputsToExternalInventory(KeyCounter[] inputHolder, PatternInputSink inputSink) {
|
public void pushInputsToExternalInventory(KeyCounter[] inputHolder, PatternInputSink inputSink) {
|
||||||
// 保持和 AEProcessingPattern 一致,用 sparseInputs 驱动
|
// 保持和 AEProcessingPattern 一致,用 sparseInputs 驱动
|
||||||
if (sparseInputs.length == inputs.length) {
|
if (sparseInputs.size() == inputs.length) {
|
||||||
IPatternDetails.super.pushInputsToExternalInventory(inputHolder, inputSink);
|
IPatternDetails.super.pushInputsToExternalInventory(inputHolder, inputSink);
|
||||||
} else {
|
} else {
|
||||||
KeyCounter allInputs = new KeyCounter();
|
KeyCounter allInputs = new KeyCounter();
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,6 @@ public class ModNetwork {
|
||||||
registrar.playToServer(ToggleAdvancedBlockingC2SPacket.TYPE, ToggleAdvancedBlockingC2SPacket.STREAM_CODEC, ToggleAdvancedBlockingC2SPacket::handle);
|
registrar.playToServer(ToggleAdvancedBlockingC2SPacket.TYPE, ToggleAdvancedBlockingC2SPacket.STREAM_CODEC, ToggleAdvancedBlockingC2SPacket::handle);
|
||||||
registrar.playToServer(ToggleSmartDoublingC2SPacket.TYPE, ToggleSmartDoublingC2SPacket.STREAM_CODEC, ToggleSmartDoublingC2SPacket::handle);
|
registrar.playToServer(ToggleSmartDoublingC2SPacket.TYPE, ToggleSmartDoublingC2SPacket.STREAM_CODEC, ToggleSmartDoublingC2SPacket::handle);
|
||||||
registrar.playToServer(ScalePatternsC2SPacket.TYPE, ScalePatternsC2SPacket.STREAM_CODEC, ScalePatternsC2SPacket::handle);
|
registrar.playToServer(ScalePatternsC2SPacket.TYPE, ScalePatternsC2SPacket.STREAM_CODEC, ScalePatternsC2SPacket::handle);
|
||||||
|
registrar.playToClient(SetPatternHighlightS2CPacket.TYPE, SetPatternHighlightS2CPacket.STREAM_CODEC, SetPatternHighlightS2CPacket::handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,21 @@ package com.extendedae_plus.network;
|
||||||
|
|
||||||
import appeng.api.stacks.AEKey;
|
import appeng.api.stacks.AEKey;
|
||||||
import com.extendedae_plus.content.ClientPatternHighlightStore;
|
import com.extendedae_plus.content.ClientPatternHighlightStore;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||||
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import java.util.function.Supplier;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* S2C: 指示客户端对某个 AEKey 的样板进行高亮/取消高亮(仅作用于接收该包的客户端)
|
* S2C: 指示客户端对某个 AEKey 的样板进行高亮/取消高亮(仅作用于接收该包的客户端)。
|
||||||
|
* 使用 NeoForge 1.21 Payload API。
|
||||||
*/
|
*/
|
||||||
public class SetPatternHighlightS2CPacket {
|
public class SetPatternHighlightS2CPacket implements CustomPacketPayload {
|
||||||
|
public static final Type<SetPatternHighlightS2CPacket> TYPE = new Type<>(
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "set_pattern_highlight"));
|
||||||
|
|
||||||
private final AEKey key;
|
private final AEKey key;
|
||||||
private final boolean highlight;
|
private final boolean highlight;
|
||||||
|
|
||||||
|
|
@ -19,26 +25,29 @@ public class SetPatternHighlightS2CPacket {
|
||||||
this.highlight = highlight;
|
this.highlight = highlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void encode(SetPatternHighlightS2CPacket msg, FriendlyByteBuf buf) {
|
public AEKey key() { return key; }
|
||||||
AEKey.writeKey(buf, msg.key);
|
public boolean highlight() { return highlight; }
|
||||||
buf.writeBoolean(msg.highlight);
|
|
||||||
|
public static final StreamCodec<RegistryFriendlyByteBuf, SetPatternHighlightS2CPacket> STREAM_CODEC = StreamCodec.of(
|
||||||
|
(buf, pkt) -> {
|
||||||
|
AEKey.writeKey(buf, pkt.key);
|
||||||
|
buf.writeBoolean(pkt.highlight);
|
||||||
|
},
|
||||||
|
buf -> new SetPatternHighlightS2CPacket(AEKey.readKey(buf), buf.readBoolean())
|
||||||
|
);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SetPatternHighlightS2CPacket decode(FriendlyByteBuf buf) {
|
public static void handle(final SetPatternHighlightS2CPacket msg, final IPayloadContext ctx) {
|
||||||
AEKey key = AEKey.readKey(buf);
|
|
||||||
boolean h = buf.readBoolean();
|
|
||||||
return new SetPatternHighlightS2CPacket(key, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(SetPatternHighlightS2CPacket msg, Supplier<NetworkEvent.Context> ctxSupplier) {
|
|
||||||
var ctx = ctxSupplier.get();
|
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
try {
|
try {
|
||||||
ClientPatternHighlightStore.setHighlight(msg.key, msg.highlight);
|
ClientPatternHighlightStore.setHighlight(msg.key, msg.highlight);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ctx.setPacketHandled(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import com.extendedae_plus.content.ScaledProcessingPattern;
|
||||||
import com.extendedae_plus.api.SmartDoublingAwarePattern;
|
import com.extendedae_plus.api.SmartDoublingAwarePattern;
|
||||||
import com.extendedae_plus.config.ModConfigs;
|
import com.extendedae_plus.config.ModConfigs;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
|
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
|
||||||
|
|
||||||
|
|
@ -24,34 +26,34 @@ public final class PatternScaler {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericStack[] baseSparseInputs = base.getSparseInputs();
|
List<GenericStack> baseSparseInputs = base.getSparseInputs();
|
||||||
GenericStack[] baseSparseOutputs = base.getSparseOutputs();
|
List<GenericStack> baseSparseOutputs = base.getSparseOutputs();
|
||||||
IInput[] baseInputs = base.getInputs();
|
IInput[] baseInputs = base.getInputs();
|
||||||
GenericStack[] baseOutputs = base.getOutputs();
|
List<GenericStack> baseOutputs = base.getOutputs();
|
||||||
|
|
||||||
// 新逻辑:不再对样板进行单位化处理
|
// 新逻辑:不再对样板进行单位化处理
|
||||||
// 找到目标输出在 outputs 中的索引(尝试匹配 target,否则取第一个非空输出)
|
// 找到目标输出在 outputs 中的索引(尝试匹配 target,否则取第一个非空输出)
|
||||||
int targetOutIndex = -1;
|
int targetOutIndex = -1;
|
||||||
for (int i = 0; i < baseOutputs.length; i++) {
|
for (int i = 0; i < baseOutputs.size(); i++) {
|
||||||
var out = baseOutputs[i];
|
var out = baseOutputs.get(i);
|
||||||
if (out != null && target != null && out.what() != null && out.what().equals(target)) {
|
if (out != null && target != null && out.what() != null && out.what().equals(target)) {
|
||||||
targetOutIndex = i;
|
targetOutIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (targetOutIndex == -1) {
|
if (targetOutIndex == -1) {
|
||||||
for (int i = 0; i < baseOutputs.length; i++) {
|
for (int i = 0; i < baseOutputs.size(); i++) {
|
||||||
if (baseOutputs[i] != null) {
|
if (baseOutputs.get(i) != null) {
|
||||||
targetOutIndex = i;
|
targetOutIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (targetOutIndex == -1 && baseOutputs.length > 0) targetOutIndex = 0;
|
if (targetOutIndex == -1 && !baseOutputs.isEmpty()) targetOutIndex = 0;
|
||||||
|
|
||||||
long perOperationTarget = 1L;
|
long perOperationTarget = 1L;
|
||||||
if (targetOutIndex >= 0 && baseOutputs[targetOutIndex] != null) {
|
if (targetOutIndex >= 0 && baseOutputs.get(targetOutIndex) != null) {
|
||||||
long amt = baseOutputs[targetOutIndex].amount();
|
long amt = baseOutputs.get(targetOutIndex).amount();
|
||||||
if (amt > 0) perOperationTarget = amt;
|
if (amt > 0) perOperationTarget = amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,28 +85,34 @@ public final class PatternScaler {
|
||||||
scaledInputs[i] = new ScaledProcessingPattern.Input(scaledTemplates, in.getMultiplier() * multiplier);
|
scaledInputs[i] = new ScaledProcessingPattern.Input(scaledTemplates, in.getMultiplier() * multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 4. 构建压缩输出 */
|
// 构建压缩输出(List)
|
||||||
GenericStack[] scaledCondensedOutputs = new GenericStack[baseOutputs.length];
|
List<GenericStack> scaledCondensedOutputs = new ArrayList<>(baseOutputs.size());
|
||||||
for (int i = 0; i < baseOutputs.length; i++) {
|
for (int i = 0; i < baseOutputs.size(); i++) {
|
||||||
GenericStack out = baseOutputs[i];
|
GenericStack out = baseOutputs.get(i);
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
scaledCondensedOutputs[i] = new GenericStack(out.what(), out.amount() * multiplier);
|
scaledCondensedOutputs.add(new GenericStack(out.what(), out.amount() * multiplier));
|
||||||
|
} else {
|
||||||
|
scaledCondensedOutputs.add(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建并打印稀疏表示(直接按 multiplier 放大)
|
// 构建稀疏表示(List,直接按 multiplier 放大)
|
||||||
GenericStack[] scaledSparseInputs = new GenericStack[baseSparseInputs.length];
|
List<GenericStack> scaledSparseInputs = new ArrayList<>(baseSparseInputs.size());
|
||||||
for (int i = 0; i < baseSparseInputs.length; i++) {
|
for (int i = 0; i < baseSparseInputs.size(); i++) {
|
||||||
var in = baseSparseInputs[i];
|
var in = baseSparseInputs.get(i);
|
||||||
if (in != null) {
|
if (in != null) {
|
||||||
scaledSparseInputs[i] = new GenericStack(in.what(), in.amount() * multiplier);
|
scaledSparseInputs.add(new GenericStack(in.what(), in.amount() * multiplier));
|
||||||
|
} else {
|
||||||
|
scaledSparseInputs.add(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GenericStack[] scaledSparseOutputs = new GenericStack[baseSparseOutputs.length];
|
List<GenericStack> scaledSparseOutputs = new ArrayList<>(baseSparseOutputs.size());
|
||||||
for (int i = 0; i < baseSparseOutputs.length; i++) {
|
for (int i = 0; i < baseSparseOutputs.size(); i++) {
|
||||||
var out = baseSparseOutputs[i];
|
var out = baseSparseOutputs.get(i);
|
||||||
if (out != null) {
|
if (out != null) {
|
||||||
scaledSparseOutputs[i] = new GenericStack(out.what(), out.amount() * multiplier);
|
scaledSparseOutputs.add(new GenericStack(out.what(), out.amount() * multiplier));
|
||||||
|
} else {
|
||||||
|
scaledSparseOutputs.add(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@
|
||||||
"ae2.helpers.PatternProviderLogicAdvancedMixin",
|
"ae2.helpers.PatternProviderLogicAdvancedMixin",
|
||||||
"ae2.helpers.PatternProviderLogicDoublingMixin",
|
"ae2.helpers.PatternProviderLogicDoublingMixin",
|
||||||
"ae2.AEProcessingPatternMixin",
|
"ae2.AEProcessingPatternMixin",
|
||||||
"extendedae.client.gui.GuiExPatternProviderMixin"
|
"extendedae.client.gui.GuiExPatternProviderMixin",
|
||||||
|
"ae2.autopattern.CraftingTreeNodeAccessor",
|
||||||
|
"ae2.autopattern.CraftingTreeProcessMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user