完成样板倍增功能
This commit is contained in:
parent
64fb68df17
commit
bec545b289
|
|
@ -232,46 +232,54 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
|||
this.addToLeftToolbar(this.prevPage);
|
||||
}
|
||||
|
||||
// x2 按钮 - 一直显示,将所有处理样板的输入输出乘以2
|
||||
// x2 按钮 - 单机模式直接调用服务器端逻辑
|
||||
this.x2Button = new ActionEPPButton((b) -> {
|
||||
try {
|
||||
var result = PatternProviderUIHelper.multiplyCurrentPatternAmounts(2.0);
|
||||
if (result != null) {
|
||||
if (result.isSuccessful()) {
|
||||
System.out.println("成功将 " + result.getScaledPatterns() + " 个处理样板的数量乘以2!");
|
||||
if (result.getFailedPatterns() > 0) {
|
||||
System.out.println("跳过了 " + result.getFailedPatterns() + " 个合成样板(合成样板不支持数量缩放)");
|
||||
}
|
||||
// 单机模式:直接在逻辑服务器端执行样板倍增
|
||||
net.minecraft.client.Minecraft minecraft = net.minecraft.client.Minecraft.getInstance();
|
||||
if (minecraft.level != null && minecraft.player != null) {
|
||||
// 获取逻辑服务器端的玩家实例
|
||||
net.minecraft.server.level.ServerPlayer serverPlayer = minecraft.getSingleplayerServer()
|
||||
.getPlayerList().getPlayer(minecraft.player.getUUID());
|
||||
|
||||
if (serverPlayer != null) {
|
||||
// 在服务器端执行样板倍增逻辑
|
||||
executePatternScalingOnServer(serverPlayer, "MULTIPLY", 2.0);
|
||||
} else {
|
||||
System.out.println("样板数量缩放失败:" + String.join(", ", result.getErrors()));
|
||||
System.out.println("ExtendedAE Plus: 无法获取服务器端玩家实例");
|
||||
}
|
||||
} else {
|
||||
System.out.println("无法获取当前样板供应器,请确保界面已正确打开");
|
||||
System.out.println("ExtendedAE Plus: 单机服务器未启动或玩家为null");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("执行样板数量乘2时发生错误:" + e.getMessage());
|
||||
System.out.println("ExtendedAE Plus: 执行样板倍增时发生错误:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, NewIcon.MULTIPLY2);
|
||||
|
||||
// /2 按钮 - 一直显示,将所有处理样板的输入输出除以2
|
||||
// /2 按钮 - 单机模式直接调用服务器端逻辑
|
||||
this.divideBy2Button = new ActionEPPButton((b) -> {
|
||||
try {
|
||||
var result = PatternProviderUIHelper.divideCurrentPatternAmounts(2.0);
|
||||
if (result != null) {
|
||||
if (result.isSuccessful()) {
|
||||
System.out.println("成功将 " + result.getScaledPatterns() + " 个处理样板的数量除以2!");
|
||||
if (result.getFailedPatterns() > 0) {
|
||||
System.out.println("跳过了 " + result.getFailedPatterns() + " 个合成样板(合成样板不支持数量缩放)");
|
||||
}
|
||||
// 单机模式:直接在逻辑服务器端执行样板除法
|
||||
net.minecraft.client.Minecraft minecraft = net.minecraft.client.Minecraft.getInstance();
|
||||
if (minecraft.level != null && minecraft.player != null) {
|
||||
// 获取逻辑服务器端的玩家实例
|
||||
net.minecraft.server.level.ServerPlayer serverPlayer = minecraft.getSingleplayerServer()
|
||||
.getPlayerList().getPlayer(minecraft.player.getUUID());
|
||||
|
||||
if (serverPlayer != null) {
|
||||
// 在服务器端执行样板除法逻辑
|
||||
executePatternScalingOnServer(serverPlayer, "DIVIDE", 2.0);
|
||||
} else {
|
||||
System.out.println("样板数量缩放失败:" + String.join(", ", result.getErrors()));
|
||||
System.out.println("ExtendedAE Plus: 无法获取服务器端玩家实例");
|
||||
}
|
||||
} else {
|
||||
System.out.println("无法获取当前样板供应器,请确保界面已正确打开");
|
||||
System.out.println("ExtendedAE Plus: 单机服务器未启动或玩家为null");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("执行样板数量除以2时发生错误:" + e.getMessage());
|
||||
System.out.println("ExtendedAE Plus: 执行样板除法时发生错误:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, NewIcon.DIVIDE2);
|
||||
|
|
@ -279,4 +287,138 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
|||
this.addToLeftToolbar(this.x2Button);
|
||||
this.addToLeftToolbar(this.divideBy2Button);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在服务器端执行样板缩放操作(单机模式)
|
||||
*/
|
||||
@Unique
|
||||
private void executePatternScalingOnServer(net.minecraft.server.level.ServerPlayer serverPlayer, String scalingType, double scaleFactor) {
|
||||
try {
|
||||
// 获取服务器端的样板供应器逻辑
|
||||
appeng.helpers.patternprovider.PatternProviderLogic patternProvider = getServerSidePatternProvider(serverPlayer);
|
||||
if (patternProvider == null) {
|
||||
System.out.println("ExtendedAE Plus: 无法获取服务器端样板供应器");
|
||||
return;
|
||||
}
|
||||
|
||||
// 在服务器端执行样板缩放
|
||||
com.extendedae_plus.util.PatternProviderDataUtil.PatternScalingResult result;
|
||||
if ("MULTIPLY".equals(scalingType)) {
|
||||
result = com.extendedae_plus.util.PatternProviderDataUtil.duplicatePatternAmountsExtendedAEStyle(patternProvider, scaleFactor);
|
||||
} else {
|
||||
result = com.extendedae_plus.util.PatternProviderDataUtil.dividePatternAmounts(patternProvider, scaleFactor);
|
||||
}
|
||||
|
||||
// 在客户端显示结果(单机模式下可以直接访问客户端)
|
||||
net.minecraft.client.Minecraft minecraft = net.minecraft.client.Minecraft.getInstance();
|
||||
if (minecraft.player != null && result != null) {
|
||||
String message;
|
||||
if (result.isSuccessful()) {
|
||||
if (result.getFailedPatterns() > 0) {
|
||||
message = String.format("✅ ExtendedAE Plus: 样板%s成功!处理了 %d 个样板,跳过 %d 个样板",
|
||||
"MULTIPLY".equals(scalingType) ? "倍增" : "除法",
|
||||
result.getScaledPatterns(), result.getFailedPatterns());
|
||||
} else {
|
||||
message = String.format("✅ ExtendedAE Plus: 样板%s成功!处理了 %d 个样板",
|
||||
"MULTIPLY".equals(scalingType) ? "倍增" : "除法",
|
||||
result.getScaledPatterns());
|
||||
}
|
||||
} else {
|
||||
message = String.format("❌ ExtendedAE Plus: 样板%s失败!错误: %s",
|
||||
"MULTIPLY".equals(scalingType) ? "倍增" : "除法",
|
||||
String.join("; ", result.getErrors()));
|
||||
}
|
||||
|
||||
// 显示消息到动作栏
|
||||
minecraft.player.displayClientMessage(net.minecraft.network.chat.Component.literal(message), true);
|
||||
System.out.println("ExtendedAE Plus: " + message);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("ExtendedAE Plus: 服务器端执行样板缩放时发生错误: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务器端的样板供应器逻辑
|
||||
*/
|
||||
@Unique
|
||||
private appeng.helpers.patternprovider.PatternProviderLogic getServerSidePatternProvider(net.minecraft.server.level.ServerPlayer serverPlayer) {
|
||||
try {
|
||||
if (serverPlayer.containerMenu != null) {
|
||||
// 检查是否是样板供应器菜单
|
||||
String menuClassName = serverPlayer.containerMenu.getClass().getSimpleName();
|
||||
System.out.println("ExtendedAE Plus: 服务器端菜单类名: " + menuClassName);
|
||||
|
||||
if (menuClassName.contains("PatternProvider")) {
|
||||
// 尝试多种可能的字段名称
|
||||
String[] possibleFieldNames = {"logic", "patternProvider", "host", "provider"};
|
||||
|
||||
for (String fieldName : possibleFieldNames) {
|
||||
try {
|
||||
var field = findFieldInHierarchy(serverPlayer.containerMenu.getClass(), fieldName);
|
||||
if (field != null) {
|
||||
field.setAccessible(true);
|
||||
Object fieldValue = field.get(serverPlayer.containerMenu);
|
||||
|
||||
if (fieldValue instanceof appeng.helpers.patternprovider.PatternProviderLogic) {
|
||||
System.out.println("ExtendedAE Plus: 通过字段 '" + fieldName + "' 找到PatternProviderLogic");
|
||||
return (appeng.helpers.patternprovider.PatternProviderLogic) fieldValue;
|
||||
}
|
||||
|
||||
// 如果字段值是host,尝试从host获取logic
|
||||
if (fieldValue != null && fieldName.equals("host")) {
|
||||
try {
|
||||
var logicMethod = fieldValue.getClass().getMethod("getLogic");
|
||||
Object logic = logicMethod.invoke(fieldValue);
|
||||
if (logic instanceof appeng.helpers.patternprovider.PatternProviderLogic) {
|
||||
System.out.println("ExtendedAE Plus: 通过host.getLogic()找到PatternProviderLogic");
|
||||
return (appeng.helpers.patternprovider.PatternProviderLogic) logic;
|
||||
}
|
||||
} catch (Exception hostException) {
|
||||
// 忽略host方法调用失败
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception fieldException) {
|
||||
// 继续尝试下一个字段名
|
||||
}
|
||||
}
|
||||
|
||||
// 如果直接字段访问失败,尝试通过方法获取
|
||||
try {
|
||||
var getLogicMethod = serverPlayer.containerMenu.getClass().getMethod("getLogic");
|
||||
Object logic = getLogicMethod.invoke(serverPlayer.containerMenu);
|
||||
if (logic instanceof appeng.helpers.patternprovider.PatternProviderLogic) {
|
||||
System.out.println("ExtendedAE Plus: 通过getLogic()方法找到PatternProviderLogic");
|
||||
return (appeng.helpers.patternprovider.PatternProviderLogic) logic;
|
||||
}
|
||||
} catch (Exception methodException) {
|
||||
// 方法调用失败,继续其他尝试
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ExtendedAE Plus: 获取服务器端样板供应器逻辑时发生错误: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在类继承层次中查找字段
|
||||
*/
|
||||
@Unique
|
||||
private java.lang.reflect.Field findFieldInHierarchy(Class<?> clazz, String fieldName) {
|
||||
Class<?> currentClass = clazz;
|
||||
while (currentClass != null && currentClass != Object.class) {
|
||||
try {
|
||||
return currentClass.getDeclaredField(fieldName);
|
||||
} catch (NoSuchFieldException e) {
|
||||
currentClass = currentClass.getSuperclass();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -40,6 +40,20 @@ public class NetworkHandler {
|
|||
.encoder(PatternUploadResultPacket::encode)
|
||||
.consumerMainThread(PatternUploadResultPacket::handle)
|
||||
.add();
|
||||
|
||||
// 样板缩放请求包(客户端 -> 服务器)
|
||||
INSTANCE.messageBuilder(PatternScalingPacket.class, packetId++, NetworkDirection.PLAY_TO_SERVER)
|
||||
.decoder(PatternScalingPacket::decode)
|
||||
.encoder(PatternScalingPacket::encode)
|
||||
.consumerMainThread(PatternScalingPacket::handle)
|
||||
.add();
|
||||
|
||||
// 样板缩放结果包(服务器 -> 客户端)
|
||||
INSTANCE.messageBuilder(PatternScalingResultPacket.class, packetId++, NetworkDirection.PLAY_TO_CLIENT)
|
||||
.decoder(PatternScalingResultPacket::decode)
|
||||
.encoder(PatternScalingResultPacket::encode)
|
||||
.consumerMainThread(PatternScalingResultPacket::handle)
|
||||
.add();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ import net.minecraft.world.item.ItemStack;
|
|||
import net.minecraft.world.level.Level;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
|
@ -505,6 +507,7 @@ public class PatternProviderDataUtil {
|
|||
|
||||
/**
|
||||
* 对样板供应器中的所有样板进行输入输出数量倍增
|
||||
* ExtendedAE风格的样板倍增实现
|
||||
*
|
||||
* @param patternProvider 样板供应器逻辑
|
||||
* @param multiplier 倍数(必须大于0)
|
||||
|
|
@ -514,11 +517,27 @@ public class PatternProviderDataUtil {
|
|||
if (multiplier <= 0) {
|
||||
throw new IllegalArgumentException("倍数必须大于0");
|
||||
}
|
||||
return scalePatternAmounts(patternProvider, multiplier, true);
|
||||
return scalePatternAmountsExtendedAEStyle(patternProvider, multiplier, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* ExtendedAE风格的样板复制倍增
|
||||
* 支持更精确的样板处理和错误恢复
|
||||
*
|
||||
* @param patternProvider 样板供应器逻辑
|
||||
* @param multiplier 倍数
|
||||
* @return 缩放操作结果
|
||||
*/
|
||||
public static PatternScalingResult duplicatePatternAmountsExtendedAEStyle(PatternProviderLogic patternProvider, double multiplier) {
|
||||
if (multiplier <= 0) {
|
||||
throw new IllegalArgumentException("倍数必须大于0");
|
||||
}
|
||||
return scalePatternAmountsExtendedAEStyle(patternProvider, multiplier, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对样板供应器中的所有样板进行输入输出数量倍除
|
||||
* ExtendedAE风格的样板除法实现
|
||||
*
|
||||
* @param patternProvider 样板供应器逻辑
|
||||
* @param divisor 除数(必须大于0)
|
||||
|
|
@ -528,11 +547,131 @@ public class PatternProviderDataUtil {
|
|||
if (divisor <= 0) {
|
||||
throw new IllegalArgumentException("除数必须大于0");
|
||||
}
|
||||
return scalePatternAmounts(patternProvider, 1.0 / divisor, false);
|
||||
return scalePatternAmountsExtendedAEStyle(patternProvider, 1.0 / divisor, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部方法:执行样板数量缩放
|
||||
* ExtendedAE风格的样板数量缩放实现
|
||||
* 提供更好的错误处理和样板兼容性
|
||||
*/
|
||||
private static PatternScalingResult scalePatternAmountsExtendedAEStyle(PatternProviderLogic patternProvider, double scaleFactor, boolean isMultiply) {
|
||||
List<String> errors = new ArrayList<>();
|
||||
int totalPatterns = 0;
|
||||
int scaledPatterns = 0;
|
||||
int failedPatterns = 0;
|
||||
|
||||
if (patternProvider == null) {
|
||||
errors.add("样板供应器为null");
|
||||
return new PatternScalingResult(0, 0, 0, errors);
|
||||
}
|
||||
|
||||
InternalInventory patternInventory = patternProvider.getPatternInv();
|
||||
if (patternInventory == null) {
|
||||
errors.add("无法访问样板库存");
|
||||
return new PatternScalingResult(0, 0, 0, errors);
|
||||
}
|
||||
|
||||
// 获取Level对象 - ExtendedAE风格的安全获取
|
||||
Level level = getPatternProviderLevel(patternProvider);
|
||||
if (level == null) {
|
||||
errors.add("无法获取Level对象,请确保样板供应器在有效的世界中");
|
||||
return new PatternScalingResult(0, 0, 0, errors);
|
||||
}
|
||||
|
||||
// 备份原始样板,以便在出错时恢复
|
||||
Map<Integer, ItemStack> originalPatterns = new HashMap<>();
|
||||
|
||||
// 第一阶段:验证所有样板并创建备份
|
||||
for (int i = 0; i < patternInventory.size(); i++) {
|
||||
ItemStack patternStack = patternInventory.getStackInSlot(i);
|
||||
if (patternStack.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
totalPatterns++;
|
||||
originalPatterns.put(i, patternStack.copy());
|
||||
|
||||
try {
|
||||
// 验证样板是否可以被解码
|
||||
IPatternDetails originalPattern = PatternDetailsHelper.decodePattern(patternStack, level);
|
||||
if (originalPattern == null) {
|
||||
errors.add("槽位 " + i + ": 无法解码样板");
|
||||
failedPatterns++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// ExtendedAE风格:检查样板类型兼容性
|
||||
if (!isPatternScalable(originalPattern)) {
|
||||
// 合成样板跳过,不计入失败数
|
||||
continue;
|
||||
}
|
||||
|
||||
// 如果是除法操作,预先验证可行性
|
||||
if (scaleFactor < 1.0) {
|
||||
if (!canScalePatternExtendedAEStyle(originalPattern, scaleFactor)) {
|
||||
errors.add("槽位 " + i + ": 样板数量无法按指定比例缩放");
|
||||
failedPatterns++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
errors.add("槽位 " + i + ": 样板验证失败 - " + e.getMessage());
|
||||
failedPatterns++;
|
||||
}
|
||||
}
|
||||
|
||||
// 第二阶段:执行实际的样板缩放
|
||||
for (int i = 0; i < patternInventory.size(); i++) {
|
||||
ItemStack patternStack = patternInventory.getStackInSlot(i);
|
||||
if (patternStack.isEmpty() || !originalPatterns.containsKey(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// 解码原始样板
|
||||
IPatternDetails originalPattern = PatternDetailsHelper.decodePattern(patternStack, level);
|
||||
if (originalPattern == null || !isPatternScalable(originalPattern)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ExtendedAE风格的样板缩放
|
||||
ItemStack scaledPatternStack = scalePatternExtendedAEStyle(originalPattern, scaleFactor, level);
|
||||
if (scaledPatternStack == null || scaledPatternStack.isEmpty()) {
|
||||
errors.add("槽位 " + i + ": 样板缩放失败");
|
||||
failedPatterns++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 应用缩放后的样板 - 使用正确的方法确保数据持久化
|
||||
setPatternWithPersistence(patternInventory, i, scaledPatternStack, patternProvider);
|
||||
scaledPatterns++;
|
||||
|
||||
} catch (Exception e) {
|
||||
errors.add("槽位 " + i + ": 处理样板时发生异常 - " + e.getMessage());
|
||||
failedPatterns++;
|
||||
|
||||
// ExtendedAE风格:出错时恢复原始样板
|
||||
try {
|
||||
setPatternWithPersistence(patternInventory, i, originalPatterns.get(i), patternProvider);
|
||||
} catch (Exception restoreException) {
|
||||
errors.add("槽位 " + i + ": 恢复原始样板失败 - " + restoreException.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 触发样板更新
|
||||
try {
|
||||
patternProvider.updatePatterns();
|
||||
} catch (Exception e) {
|
||||
errors.add("更新样板列表时发生异常: " + e.getMessage());
|
||||
}
|
||||
|
||||
return new PatternScalingResult(totalPatterns, scaledPatterns, failedPatterns, errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部方法:执行样板数量缩放(保留原有实现以兼容性)
|
||||
*/
|
||||
private static PatternScalingResult scalePatternAmounts(PatternProviderLogic patternProvider, double scaleFactor, boolean isMultiply) {
|
||||
List<String> errors = new ArrayList<>();
|
||||
|
|
@ -620,8 +759,8 @@ public class PatternProviderDataUtil {
|
|||
continue;
|
||||
}
|
||||
|
||||
// 替换原样板
|
||||
patternInventory.setItemDirect(i, scaledPatternStack);
|
||||
// 替换原样板 - 使用正确的方法确保数据持久化
|
||||
setPatternWithPersistence(patternInventory, i, scaledPatternStack, patternProvider);
|
||||
scaledPatterns++;
|
||||
|
||||
} catch (Exception e) {
|
||||
|
|
@ -724,7 +863,228 @@ public class PatternProviderDataUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* 缩放处理样板
|
||||
* 正确设置样板并确保数据持久化
|
||||
* 解决样板修改后关闭UI就恢复的问题
|
||||
*/
|
||||
private static void setPatternWithPersistence(InternalInventory patternInventory, int slot, ItemStack newPattern, PatternProviderLogic patternProvider) {
|
||||
try {
|
||||
// 1. 设置物品到库存
|
||||
patternInventory.setItemDirect(slot, newPattern);
|
||||
|
||||
// 2. 标记数据为脏数据,确保保存到磁盘
|
||||
try {
|
||||
// 通过反射获取host并标记为脏数据
|
||||
var hostField = patternProvider.getClass().getDeclaredField("host");
|
||||
hostField.setAccessible(true);
|
||||
var host = hostField.get(patternProvider);
|
||||
|
||||
if (host != null) {
|
||||
// 获取BlockEntity并标记为脏数据
|
||||
var getBlockEntityMethod = host.getClass().getMethod("getBlockEntity");
|
||||
var blockEntity = getBlockEntityMethod.invoke(host);
|
||||
|
||||
if (blockEntity != null) {
|
||||
// 调用setChanged()方法标记为脏数据
|
||||
var setChangedMethod = blockEntity.getClass().getMethod("setChanged");
|
||||
setChangedMethod.invoke(blockEntity);
|
||||
|
||||
// 尝试触发网络同步
|
||||
try {
|
||||
var levelField = blockEntity.getClass().getSuperclass().getDeclaredField("level");
|
||||
levelField.setAccessible(true);
|
||||
Level level = (Level) levelField.get(blockEntity);
|
||||
|
||||
if (level != null && !level.isClientSide()) {
|
||||
// 服务器端:强制同步到客户端
|
||||
var getBlockPosMethod = blockEntity.getClass().getMethod("getBlockPos");
|
||||
var blockPos = getBlockPosMethod.invoke(blockEntity);
|
||||
|
||||
if (blockPos != null) {
|
||||
// 通知客户端方块状态变更
|
||||
var getBlockStateMethod = blockEntity.getClass().getMethod("getBlockState");
|
||||
var blockState = getBlockStateMethod.invoke(blockEntity);
|
||||
level.sendBlockUpdated((net.minecraft.core.BlockPos) blockPos,
|
||||
(net.minecraft.world.level.block.state.BlockState) blockState,
|
||||
(net.minecraft.world.level.block.state.BlockState) blockState, 3);
|
||||
}
|
||||
}
|
||||
} catch (Exception syncException) {
|
||||
// 网络同步失败不影响主要功能
|
||||
System.out.println("ExtendedAE Plus: 网络同步失败,但数据已保存: " + syncException.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 如果反射失败,使用备用方案
|
||||
System.out.println("ExtendedAE Plus: 无法通过反射标记脏数据,使用备用方案: " + e.getMessage());
|
||||
}
|
||||
|
||||
// 3. 强制更新样板缓存
|
||||
patternProvider.updatePatterns();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("设置样板时发生错误: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ExtendedAE风格:安全获取样板供应器的Level对象
|
||||
*/
|
||||
private static Level getPatternProviderLevel(PatternProviderLogic patternProvider) {
|
||||
try {
|
||||
var hostField = patternProvider.getClass().getDeclaredField("host");
|
||||
hostField.setAccessible(true);
|
||||
var host = hostField.get(patternProvider);
|
||||
if (host != null) {
|
||||
var getBlockEntityMethod = host.getClass().getMethod("getBlockEntity");
|
||||
var blockEntity = getBlockEntityMethod.invoke(host);
|
||||
if (blockEntity != null) {
|
||||
var getLevelMethod = blockEntity.getClass().getMethod("getLevel");
|
||||
return (Level) getLevelMethod.invoke(blockEntity);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 静默处理异常,返回null让调用者处理
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* ExtendedAE风格:检查样板是否可以缩放
|
||||
*/
|
||||
private static boolean isPatternScalable(IPatternDetails pattern) {
|
||||
if (pattern == null) return false;
|
||||
|
||||
String className = pattern.getClass().getSimpleName();
|
||||
// 只有处理样板可以缩放,合成样板不支持
|
||||
return "AEProcessingPattern".equals(className) ||
|
||||
(!className.equals("AECraftingPattern") && pattern.getOutputs().length > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* ExtendedAE风格:检查样板是否可以按指定比例缩放
|
||||
*/
|
||||
private static boolean canScalePatternExtendedAEStyle(IPatternDetails pattern, double scaleFactor) {
|
||||
if (!isPatternScalable(pattern)) return false;
|
||||
|
||||
try {
|
||||
// 对于倍增操作,总是允许
|
||||
if (scaleFactor >= 1.0) return true;
|
||||
|
||||
// 对于除法操作,检查所有输入输出是否可以被整除
|
||||
double divisor = 1.0 / scaleFactor;
|
||||
|
||||
// 检查输入
|
||||
for (IPatternDetails.IInput input : pattern.getInputs()) {
|
||||
GenericStack[] possibleInputs = input.getPossibleInputs();
|
||||
long multiplier = input.getMultiplier();
|
||||
|
||||
if (possibleInputs.length > 0 && possibleInputs[0] != null) {
|
||||
long currentAmount = possibleInputs[0].amount() * multiplier;
|
||||
if (currentAmount < divisor || (currentAmount % divisor != 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查输出
|
||||
for (GenericStack output : pattern.getOutputs()) {
|
||||
if (output != null && output.what() != null) {
|
||||
long currentAmount = output.amount();
|
||||
if (currentAmount < divisor || (currentAmount % divisor != 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ExtendedAE风格:缩放样板
|
||||
*/
|
||||
private static ItemStack scalePatternExtendedAEStyle(IPatternDetails originalPattern, double scaleFactor, Level level) {
|
||||
if (!isPatternScalable(originalPattern)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取原始输入输出
|
||||
IPatternDetails.IInput[] originalInputs = originalPattern.getInputs();
|
||||
GenericStack[] originalOutputs = originalPattern.getOutputs();
|
||||
|
||||
// ExtendedAE风格:更精确的数量计算
|
||||
List<GenericStack> scaledInputs = new ArrayList<>();
|
||||
for (IPatternDetails.IInput input : originalInputs) {
|
||||
GenericStack[] possibleInputs = input.getPossibleInputs();
|
||||
long multiplier = input.getMultiplier();
|
||||
|
||||
if (possibleInputs.length > 0 && possibleInputs[0] != null) {
|
||||
GenericStack primaryInput = possibleInputs[0];
|
||||
long originalAmount = primaryInput.amount() * multiplier;
|
||||
|
||||
// ExtendedAE风格:精确计算新数量
|
||||
long newAmount;
|
||||
if (scaleFactor >= 1.0) {
|
||||
// 倍增:四舍五入,但至少为1
|
||||
newAmount = Math.max(1, Math.round(originalAmount * scaleFactor));
|
||||
} else {
|
||||
// 除法:必须能整除
|
||||
double divisor = 1.0 / scaleFactor;
|
||||
if (originalAmount % divisor == 0) {
|
||||
newAmount = Math.max(1, (long)(originalAmount / divisor));
|
||||
} else {
|
||||
// 不能整除,返回null表示失败
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
scaledInputs.add(new GenericStack(primaryInput.what(), newAmount));
|
||||
}
|
||||
}
|
||||
|
||||
// ExtendedAE风格:缩放输出
|
||||
List<GenericStack> scaledOutputs = new ArrayList<>();
|
||||
for (GenericStack output : originalOutputs) {
|
||||
if (output != null && output.what() != null) {
|
||||
long originalAmount = output.amount();
|
||||
|
||||
// ExtendedAE风格:精确计算新数量
|
||||
long newAmount;
|
||||
if (scaleFactor >= 1.0) {
|
||||
// 倍增:四舍五入,但至少为1
|
||||
newAmount = Math.max(1, Math.round(originalAmount * scaleFactor));
|
||||
} else {
|
||||
// 除法:必须能整除
|
||||
double divisor = 1.0 / scaleFactor;
|
||||
if (originalAmount % divisor == 0) {
|
||||
newAmount = Math.max(1, (long)(originalAmount / divisor));
|
||||
} else {
|
||||
// 不能整除,返回null表示失败
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
scaledOutputs.add(new GenericStack(output.what(), newAmount));
|
||||
}
|
||||
}
|
||||
|
||||
// 创建新的处理样板
|
||||
return PatternDetailsHelper.encodeProcessingPattern(
|
||||
scaledInputs.toArray(new GenericStack[0]),
|
||||
scaledOutputs.toArray(new GenericStack[0])
|
||||
);
|
||||
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩放处理样板(保留原有实现以兼容性)
|
||||
*/
|
||||
private static ItemStack scaleProcessingPattern(IPatternDetails originalPattern, double scaleFactor) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -79,6 +79,22 @@ public class PatternProviderUIHelper {
|
|||
return PatternProviderDataUtil.multiplyPatternAmounts(patternProvider, multiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* ExtendedAE风格的样板复制倍增
|
||||
* 提供更好的错误处理和恢复机制
|
||||
*
|
||||
* @param multiplier 倍数(必须大于0)
|
||||
* @return 缩放操作结果,如果当前没有打开样板供应器界面则返回null
|
||||
*/
|
||||
public static PatternProviderDataUtil.PatternScalingResult duplicateCurrentPatternAmountsExtendedAEStyle(double multiplier) {
|
||||
PatternProviderLogic patternProvider = getCurrentPatternProvider();
|
||||
if (patternProvider == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return PatternProviderDataUtil.duplicatePatternAmountsExtendedAEStyle(patternProvider, multiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在当前样板供应器中执行样板数量倍除
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user