diff --git a/build.gradle b/build.gradle index 22f3dca..9e12294 100644 --- a/build.gradle +++ b/build.gradle @@ -71,6 +71,7 @@ dependencies { modImplementation "curse.maven:glodium-957920:${glodium_version}" //extendedAE modImplementation files('libs/ExtendedAE-1.20-1.4.2-forge.jar') + modRuntimeOnly fileTree(dir: 'libs', includes: ['*.jar']) //ae2 modImplementation "appeng:appliedenergistics2-forge:${ae2_version}" diff --git a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java index 037a65a..011f78a 100644 --- a/src/main/java/com/extendedae_plus/ExtendedAEPlus.java +++ b/src/main/java/com/extendedae_plus/ExtendedAEPlus.java @@ -4,10 +4,10 @@ import appeng.api.storage.StorageCells; import appeng.menu.locator.MenuLocators; import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellHandler; import com.extendedae_plus.client.ClientRegistrar; -import com.extendedae_plus.command.InfinityDiskGiveCommand; import com.extendedae_plus.config.ModConfig; import com.extendedae_plus.init.*; import com.extendedae_plus.menu.locator.CuriosItemLocator; +import com.extendedae_plus.util.command.InfinityDiskGiveCommand; import com.extendedae_plus.util.storage.InfinityStorageManager; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; diff --git a/src/main/java/com/extendedae_plus/ae/api/config/Settings.java b/src/main/java/com/extendedae_plus/ae/api/config/Settings.java new file mode 100644 index 0000000..6ed3fc5 --- /dev/null +++ b/src/main/java/com/extendedae_plus/ae/api/config/Settings.java @@ -0,0 +1,41 @@ +package com.extendedae_plus.ae.api.config; + +import appeng.api.config.Setting; +import appeng.api.config.YesNo; +import com.google.common.base.Preconditions; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +public final class Settings { + private static final Map> SETTINGS = new HashMap<>(); + public static final Setting ACCELERATE = register("accelerate", YesNo.NO, YesNo.YES); + + + private Settings() { + } + + private synchronized static > Setting register(String name, Class enumClass) { + Preconditions.checkState(!SETTINGS.containsKey(name)); + var setting = new Setting<>(name, enumClass); + SETTINGS.put(name, setting); + return setting; + } + + @SafeVarargs + private synchronized static > Setting register(String name, T firstOption, T... moreOptions) { + Preconditions.checkState(!SETTINGS.containsKey(name)); + var setting = new Setting(name, firstOption.getDeclaringClass(), EnumSet.of(firstOption, moreOptions)); + SETTINGS.put(name, setting); + return setting; + } + + public static Setting getOrThrow(String name) { + var setting = SETTINGS.get(name); + if (setting == null) { + throw new IllegalArgumentException("Unknown setting '" + name + "'"); + } + return setting; + } +} diff --git a/src/main/java/com/extendedae_plus/content/ScaledProcessingPattern.java b/src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPattern.java similarity index 99% rename from src/main/java/com/extendedae_plus/content/ScaledProcessingPattern.java rename to src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPattern.java index 0b672ff..ab8c924 100644 --- a/src/main/java/com/extendedae_plus/content/ScaledProcessingPattern.java +++ b/src/main/java/com/extendedae_plus/ae/api/crafting/ScaledProcessingPattern.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.content; +package com.extendedae_plus.ae.api.crafting; import appeng.api.crafting.IPatternDetails; import appeng.api.stacks.AEItemKey; diff --git a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java b/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java index efcce92..9c69845 100644 --- a/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java +++ b/src/main/java/com/extendedae_plus/ae/api/storage/InfinityBigIntegerCellInventory.java @@ -326,8 +326,11 @@ public class InfinityBigIntegerCellInventory implements StorageCell { if (amount == 0){ return 0; } - // 不允许存储无限单元自身 - if (what instanceof AEItemKey itemKey && itemKey.getItem() instanceof InfinityBigIntegerCellItem) { + // 不允许存储有物品的无限单元 + if (what instanceof AEItemKey itemKey && + itemKey.getItem() instanceof InfinityBigIntegerCellItem && + itemKey.hasTag() + ) { return 0; } diff --git a/src/main/java/com/extendedae_plus/NewIcon.java b/src/main/java/com/extendedae_plus/ae/client/gui/NewIcon.java similarity index 91% rename from src/main/java/com/extendedae_plus/NewIcon.java rename to src/main/java/com/extendedae_plus/ae/client/gui/NewIcon.java index 8535a1f..db82062 100644 --- a/src/main/java/com/extendedae_plus/NewIcon.java +++ b/src/main/java/com/extendedae_plus/ae/client/gui/NewIcon.java @@ -1,6 +1,7 @@ -package com.extendedae_plus; +package com.extendedae_plus.ae.client.gui; import appeng.client.gui.style.Blitter; +import com.extendedae_plus.ExtendedAEPlus; import net.minecraft.resources.ResourceLocation; public class NewIcon { diff --git a/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java b/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java index fcc6e5d..008a9ff 100644 --- a/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java +++ b/src/main/java/com/extendedae_plus/ae/menu/EntitySpeedTickerMenu.java @@ -9,129 +9,169 @@ import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen; import com.extendedae_plus.config.ModConfig; import com.extendedae_plus.init.ModItems; import com.extendedae_plus.init.ModMenuTypes; -import com.extendedae_plus.util.ConfigParsingUtils; -import com.extendedae_plus.util.PowerUtils; +import com.extendedae_plus.util.entitySpeed.ConfigParsingUtils; +import com.extendedae_plus.util.entitySpeed.PowerUtils; import net.minecraft.client.Minecraft; import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraftforge.registries.ForgeRegistries; import java.util.List; -// 实体加速器菜单,负责与客户端界面同步数据 +/** + * 实体加速器菜单,负责管理客户端与服务端的数据同步,处理加速卡、能量卡和目标方块的状态。 + */ public class EntitySpeedTickerMenu extends UpgradeableMenu { - @GuiSync(716) public boolean accelerateEnabled = true; - // 已安装的实体加速卡数量(用于能耗计算) - @GuiSync(717) public int entitySpeedCardCount; - // 已安装的能量卡数量 - @GuiSync(718) public int energyCardCount; - // 当前生效的配置倍率(从配置中读取并同步) - // 当前计算出的生效速度(product of multipliers),同步给客户端用于显示 - @GuiSync(719) public int effectiveSpeed = 1; - @GuiSync(720) public double multiplier = 1.0; - @GuiSync(721) public boolean targetBlacklisted = false; + @GuiSync(716) public boolean accelerateEnabled = true; // 是否启用加速 + @GuiSync(717) public int entitySpeedCardCount; // 已安装的实体加速卡数量 + @GuiSync(718) public int energyCardCount; // 已安装的能量卡数量 + @GuiSync(719) public int effectiveSpeed = 1; // 当前生效的加速倍率 + @GuiSync(720) public double multiplier = 1.0; // 目标方块的配置倍率 + @GuiSync(721) public boolean targetBlacklisted = false; // 目标方块是否在黑名单中 + @GuiSync(722) public boolean networkEnergySufficient = true; // 网络能量是否充足 + /** + * 构造函数,初始化菜单并绑定部件。 + * @param id 菜单ID + * @param ip 玩家背包 + * @param host 关联的实体加速器部件 + */ + public EntitySpeedTickerMenu(int id, Inventory ip, EntitySpeedTickerPart host) { + super(ModMenuTypes.ENTITY_TICKER_MENU.get(), id, ip, host); + if (host != null) { + host.menu = this; // 绑定菜单到部件 + this.accelerateEnabled = host.getAccelerateEnabled(); // 同步初始开关状态 + } + } + + /** + * 获取加速开关状态。 + * @return 是否启用加速 + */ public boolean getAccelerateEnabled() { return this.accelerateEnabled; } + /** + * 设置加速开关状态,并同步到部件。 + * @param enabled 是否启用加速 + */ public void setAccelerateEnabled(boolean enabled) { this.accelerateEnabled = enabled; + if (getHost() != null) { + getHost().setAccelerateEnabled(enabled); // 同步到部件 + } + broadcastChanges(); // 广播状态变化 } - - // 构造方法,初始化菜单并与部件绑定 - public EntitySpeedTickerMenu(int id, Inventory ip, EntitySpeedTickerPart host) { - super(ModMenuTypes.ENTITY_TICKER_MENU.get(), id, ip, host); - // 让部件持有当前菜单实例,便于通信 - getHost().menu = this; - // 初始同步部件上的开关状态到菜单(服务器端构造时保证一致) - try { - this.accelerateEnabled = getHost().getAccelerateEnabled(); - } catch (Exception ignored) {} + /** + * 更新网络能量充足状态并广播到客户端。 + * @param sufficient 是否能量充足 + */ + public void setNetworkEnergySufficient(boolean sufficient) { + this.networkEnergySufficient = sufficient; + broadcastChanges(); } - // 当服务器数据同步到客户端时调用 + /** + * 服务端数据同步到客户端时调用,更新卡数量、目标状态和生效速度。 + */ @Override public void onServerDataSync() { super.onServerDataSync(); - // 重新统计实体加速卡和能量卡数量 + updateCardCounts(); // 更新卡数量 + updateTargetStatus(); // 更新目标方块的黑名单和倍率 + updateEffectiveSpeed(); // 计算生效速度 + updateNetworkEnergyStatus(); // 同步能量状态 + if (isClientSide()) { + refreshClientGui(); // 客户端刷新界面 + } + } + + /** + * 当槽位内容变化时调用,客户端更新卡数量和生效速度。 + * @param slot 发生变化的槽位 + */ + @Override + public void onSlotChange(Slot slot) { + super.onSlotChange(slot); + if (isClientSide()) { + updateCardCounts(); + updateEffectiveSpeed(); + refreshClientGui(); + } + } + + /** + * 广播数据变化,清理未启用槽位的显示堆栈。 + */ + @Override + public void broadcastChanges() { + for (Object o : this.slots) { + if (o instanceof OptionalFakeSlot fs && !fs.isSlotEnabled() && !fs.getDisplayStack().isEmpty()) { + fs.clearStack(); // 清理未启用槽位的显示 + } + } + standardDetectAndSendChanges(); + } + + /** + * 更新加速卡和能量卡的数量。 + */ + private void updateCardCounts() { this.entitySpeedCardCount = this.getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get()); this.energyCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD); + } - // 计算当前面向方块的倍率(服务器端),并同步给客户端 - double mult = 1.0; - try { - BlockEntity target = getHost().getLevel().getBlockEntity(getHost().getBlockEntity().getBlockPos().relative(getHost().getSide())); - if (target != null) { - String blockId = ForgeRegistries.BLOCKS.getKey(target.getBlockState().getBlock()).toString(); - for (ConfigParsingUtils.MultiplierEntry me : ConfigParsingUtils.getCachedMultiplierEntries(List.of(ModConfig.INSTANCE.entityTickerMultipliers))) { - if (me.pattern.matcher(blockId).matches()) { - mult = Math.max(mult, me.multiplier); - } - } - } - } catch (Exception ignored) {} - this.multiplier = mult; - - // 检查目标是否在黑名单中,如果是则标记并将生效速度设为 0(服务器端计算) - boolean blacklisted = false; - try { - BlockEntity target = getHost().getLevel().getBlockEntity(getHost().getBlockEntity().getBlockPos().relative(getHost().getSide())); - if (target != null) { - String blockId = ForgeRegistries.BLOCKS.getKey(target.getBlockState().getBlock()).toString(); - for (java.util.regex.Pattern p : ConfigParsingUtils.getCachedBlacklist(List.of(ModConfig.INSTANCE.entityTickerBlackList))) { - if (p.matcher(blockId).matches()) { - blacklisted = true; - break; - } - } - } - } catch (Exception ignored) {} - this.targetBlacklisted = blacklisted; - - // 计算生效速度:如果被黑名单则为 0,否则进行正常计算(使用工具类从菜单直接计算 product with cap,最多 8 张) - if (this.targetBlacklisted) { - this.effectiveSpeed = 0; - } else { - this.effectiveSpeed = (int) PowerUtils.computeProductWithCapFromMenu(this, 8); + /** + * 更新目标方块的黑名单状态和倍率。 + */ + private void updateTargetStatus() { + BlockEntity target = getTargetBlockEntity(); + if (target == null) { + this.multiplier = 1.0; + this.targetBlacklisted = false; + return; } + String blockId = ForgeRegistries.BLOCKS.getKey(target.getBlockState().getBlock()).toString(); + this.multiplier = ConfigParsingUtils.getMultiplierForBlock(blockId, List.of(ModConfig.INSTANCE.entityTickerMultipliers)); + this.targetBlacklisted = ConfigParsingUtils.isBlockBlacklisted(blockId, List.of(ModConfig.INSTANCE.entityTickerBlackList)); + } - // 如果在客户端,刷新界面 - if (isClientSide()) { - if (Minecraft.getInstance().screen instanceof EntitySpeedTickerScreen screen) { - screen.refreshGui(); - } + /** + * 计算生效速度(考虑黑名单和卡数量)。 + */ + private void updateEffectiveSpeed() { + this.effectiveSpeed = targetBlacklisted ? 0 : (int) PowerUtils.computeProductWithCap(getUpgrades(), 8); + } + + /** + * 同步网络能量状态(仅服务端)。 + */ + private void updateNetworkEnergyStatus() { + if (!isClientSide() && getHost() != null) { + this.networkEnergySufficient = getHost().isNetworkEnergySufficient(); } } - // 当任意槽位发生变化时调用 - @Override - public void onSlotChange(net.minecraft.world.inventory.Slot slot) { - super.onSlotChange(slot); - // 客户端重新统计卡数量并刷新界面 - if (isClientSide()) { - this.entitySpeedCardCount = this.getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get()); - this.energyCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD); - // 立即在客户端计算生效速度以便界面即时反馈(使用与服务端相同的工具方法,最多 8 张卡) - this.effectiveSpeed = (int) PowerUtils.computeProductWithCapFromMenu(this, 8); - if (Minecraft.getInstance().screen instanceof EntitySpeedTickerScreen screen) { - screen.refreshGui(); - } + /** + * 客户端刷新界面。 + */ + private void refreshClientGui() { + if (Minecraft.getInstance().screen instanceof EntitySpeedTickerScreen screen) { + screen.refreshGui(); } } - @Override - public void broadcastChanges(){ - // 遍历所有槽位,清理未启用但有物品显示的 OptionalFakeSlot - for (Object o : this.slots) { - if (o instanceof OptionalFakeSlot fs) { - if (!fs.isSlotEnabled() && !fs.getDisplayStack().isEmpty()) { - fs.clearStack(); - } - } - } - // 调用标准的同步方法,通知监听者数据已更新 - this.standardDetectAndSendChanges(); + /** + * 获取目标方块实体。 + * @return 目标方块实体或 null + */ + private BlockEntity getTargetBlockEntity() { + return getHost() != null ? + getHost().getLevel().getBlockEntity( + getHost().getBlockEntity().getBlockPos().relative(getHost().getSide()) + ) : null; } } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/ae/parts/EntitySpeedTickerPart.java b/src/main/java/com/extendedae_plus/ae/parts/EntitySpeedTickerPart.java index 4b53158..53f634f 100644 --- a/src/main/java/com/extendedae_plus/ae/parts/EntitySpeedTickerPart.java +++ b/src/main/java/com/extendedae_plus/ae/parts/EntitySpeedTickerPart.java @@ -2,14 +2,18 @@ package com.extendedae_plus.ae.parts; import appeng.api.config.Actionable; import appeng.api.config.PowerMultiplier; +import appeng.api.config.YesNo; import appeng.api.networking.GridFlags; import appeng.api.networking.IGridNode; +import appeng.api.networking.energy.IEnergyService; +import appeng.api.networking.security.IActionSource; import appeng.api.networking.ticking.IGridTickable; import appeng.api.networking.ticking.TickRateModulation; import appeng.api.networking.ticking.TickingRequest; import appeng.api.parts.IPartCollisionHelper; import appeng.api.parts.IPartItem; import appeng.api.parts.IPartModel; +import appeng.api.storage.MEStorage; import appeng.api.upgrades.IUpgradeableObject; import appeng.core.definitions.AEItems; import appeng.items.parts.PartModels; @@ -22,9 +26,8 @@ import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu; import com.extendedae_plus.config.ModConfig; import com.extendedae_plus.init.ModItems; import com.extendedae_plus.init.ModMenuTypes; -import com.extendedae_plus.util.ConfigParsingUtils; -import com.extendedae_plus.util.PowerUtils; -import net.minecraft.core.BlockPos; +import com.extendedae_plus.util.entitySpeed.ConfigParsingUtils; +import com.extendedae_plus.util.entitySpeed.PowerUtils; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.InteractionHand; @@ -36,68 +39,86 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.phys.Vec3; +import net.minecraftforge.fml.ModList; import net.minecraftforge.registries.ForgeRegistries; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Method; import java.util.List; -import java.util.Objects; -import java.util.regex.Pattern; /** - * EntitySpeedTickerPart 是一个可升级的 AE2 部件

- * 该部件可以加速目标方块实体的 tick 速率,消耗 AE 网络能量,并支持加速卡升级

- * 功能受Crazy AE2 Addons启发 + * 实体加速器部件,用于加速目标方块实体的 tick 速率,消耗 AE 网络能量,支持加速卡和能量卡升级。 + * 灵感来源于 Crazy AE2 Addons。 */ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTickable, MenuProvider, IUpgradeableObject { - // 当前打开的菜单实例(如果有) - public EntitySpeedTickerMenu menu; - public static final ResourceLocation MODEL_BASE = new ResourceLocation( ExtendedAEPlus.MODID, "part/entity_speed_ticker_part"); @PartModels - public static final PartModel MODELS_OFF; + public static final PartModel MODELS_OFF = new PartModel(MODEL_BASE, new ResourceLocation(ExtendedAEPlus.MODID, "part/entity_speed_ticker_off")); @PartModels - public static final PartModel MODELS_ON; + public static final PartModel MODELS_ON = new PartModel(MODEL_BASE, new ResourceLocation(ExtendedAEPlus.MODID, "part/entity_speed_ticker_on")); @PartModels - public static final PartModel MODELS_HAS_CHANNEL; - - static { - MODELS_OFF = new PartModel(MODEL_BASE, new ResourceLocation(ExtendedAEPlus.MODID, "part/entity_speed_ticker_off")); - MODELS_ON = new PartModel(MODEL_BASE, new ResourceLocation(ExtendedAEPlus.MODID, "part/entity_speed_ticker_on")); - MODELS_HAS_CHANNEL = new PartModel(MODEL_BASE, new ResourceLocation(ExtendedAEPlus.MODID, "part/entity_speed_ticker_has_channel")); - } - + public static final PartModel MODELS_HAS_CHANNEL = new PartModel(MODEL_BASE, new ResourceLocation(ExtendedAEPlus.MODID, "part/entity_speed_ticker_has_channel")); + + public EntitySpeedTickerMenu menu; // 当前打开的菜单实例 + private boolean networkEnergySufficient = true; // 网络能量是否充足 + /** - * 构造函数,初始化部件并设置网络节点属性 + * 构造函数,初始化部件并设置网络节点属性。 * @param partItem 部件物品 */ public EntitySpeedTickerPart(IPartItem partItem) { super(partItem); - // 设置网络节点属性:需要通道、空闲功耗为1,并注册为 IGridTickable 服务 this.getMainNode() .setFlags(GridFlags.REQUIRE_CHANNEL) .setIdlePowerUsage(1) .addService(IGridTickable.class, this); + + // 注册可记忆的配置(YES/NO) + this.getConfigManager().registerSetting( + com.extendedae_plus.ae.api.config.Settings.ACCELERATE, + YesNo.YES + ); } - // 控制是否启用加速(默认启用) - private boolean accelerateEnabled = true; - - public boolean getAccelerateEnabled() { - return this.accelerateEnabled; - } - - public void setAccelerateEnabled(boolean accelerateEnabled) { - this.accelerateEnabled = accelerateEnabled; + return this.getConfigManager().getSetting(com.extendedae_plus.ae.api.config.Settings.ACCELERATE) == YesNo.YES; } /** - * 获取当前状态下的静态模型(用于渲染) + * 设置加速开关状态并通知菜单。 + * @param enabled 是否启用加速 + */ + public void setAccelerateEnabled(boolean enabled) { + this.getConfigManager().putSetting(com.extendedae_plus.ae.api.config.Settings.ACCELERATE, enabled ? YesNo.YES : YesNo.NO); + // 是否启用加速 + if (menu != null) { + menu.setAccelerateEnabled(enabled); + } + } + + public boolean isNetworkEnergySufficient() { + return this.networkEnergySufficient; + } + + /** + * 更新网络能量充足状态并通知菜单。 + * @param sufficient 是否能量充足 + */ + private void updateNetworkEnergySufficient(boolean sufficient) { + this.networkEnergySufficient = sufficient; + if (menu != null) { + menu.setNetworkEnergySufficient(sufficient); + } + } + + /** + * 获取当前状态的渲染模型。 * @return 当前状态的模型 */ + @Override public IPartModel getStaticModels() { if (this.isActive() && this.isPowered()) { return MODELS_HAS_CHANNEL; @@ -109,15 +130,14 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka } /** - * 当玩家激活部件(右键)时调用,打开自定义菜单 + * 处理玩家右键激活部件,打开菜单。 * @param player 玩家 * @param hand 手 * @param pos 点击位置 - * @return 总是返回 true,表示激活成功 + * @return 总是返回 true */ @Override public boolean onPartActivate(Player player, InteractionHand hand, Vec3 pos) { - // 仅在服务端打开菜单 if (!player.getCommandSenderWorld().isClientSide()) { MenuOpener.open(ModMenuTypes.ENTITY_TICKER_MENU.get(), player, MenuLocators.forPart(this)); } @@ -125,7 +145,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka } /** - * 定义部件的碰撞箱(用于物理碰撞和渲染) + * 定义部件的碰撞箱。 * @param bch 碰撞辅助器 */ @Override @@ -135,43 +155,37 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka } /** - * 获取定时请求,决定本部件多久 tick 一次 + * 获取定时请求,指定 tick 频率。 * @param iGridNode 网络节点 * @return TickingRequest 对象 */ @Override public TickingRequest getTickingRequest(IGridNode iGridNode) { - // 每 1 tick 执行一次 return new TickingRequest(1, 1, false, true); } /** - * 当升级卡数量发生变化时调用,通知菜单更新 + * 当升级卡变化时通知菜单更新。 */ @Override public void upgradesChanged() { - if (this.menu != null) { - // 使用 AE2 风格:当升级发生变化时让菜单广播变化(槽/数据会被同步),客户端会基于槽内容重新计算并刷新界面 - this.menu.broadcastChanges(); + if (menu != null) { + menu.broadcastChanges(); } } /** - * 网络定时回调,每次 tick 时调用 + * 网络定时回调,处理目标方块实体的加速。 * @param iGridNode 网络节点 - * @param ticksSinceLastCall 距离上次调用经过的 tick 数 - * @return TickRateModulation.IDLE 表示继续保持当前 tick 速率 + * @param ticksSinceLastCall 距离上次调用的 tick 数 + * @return TickRateModulation.IDLE */ @Override public TickRateModulation tickingRequest(IGridNode iGridNode, int ticksSinceLastCall) { - // 如果部件的加速开关被关闭,则不进行加速(提前返回) if (!this.getAccelerateEnabled()) { return TickRateModulation.IDLE; } - - // 获取目标方块实体(本部件朝向的方块) BlockEntity target = getLevel().getBlockEntity(getBlockEntity().getBlockPos().relative(getSide())); - // 仅在目标存在且部件处于激活状态时执行加速 if (target != null && isActive()) { ticker(target); } @@ -179,78 +193,149 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka } /** - * 以指定速度对目标方块实体进行 tick 操作 - * @param blockEntity 需要被 tick 的方块实体 + * 对目标方块实体执行加速 tick 操作。 + * @param blockEntity 目标方块实体 * @param 方块实体类型 */ private void ticker(@NotNull T blockEntity) { - if (this.getGridNode() == null - || this.getMainNode() == null - || this.getMainNode().getGrid() == null) { + if (!isValidForTicking()) { return; } - // 获取方块实体的位置 - BlockPos pos = blockEntity.getBlockPos(); - if (blockEntity.getLevel() == null) return; - - // 检查黑名单(支持通配符/正则) - String blockId = Objects.requireNonNull(ForgeRegistries.BLOCKS.getKey(blockEntity.getBlockState().getBlock())).toString(); - - // 使用工具类的缓存接口(工具类内部负责懒加载/线程安全) - List compiledBlacklist = ConfigParsingUtils.getCachedBlacklist(List.of(ModConfig.INSTANCE.entityTickerBlackList)); - for (Pattern p : compiledBlacklist) { - if (p.matcher(blockId).matches()) return; + String blockId = ForgeRegistries.BLOCKS.getKey(blockEntity.getBlockState().getBlock()).toString(); + if (ConfigParsingUtils.isBlockBlacklisted(blockId, List.of(ModConfig.INSTANCE.entityTickerBlackList))) { + return; } - // 获取该方块实体的 Ticker - @SuppressWarnings("unchecked") - BlockEntityTicker blockEntityTicker = this.getLevel() - .getBlockState(pos) - .getTicker(this.getLevel(), (BlockEntityType) blockEntity.getType()); - if (blockEntityTicker == null) return; + BlockEntityTicker ticker = getTicker(blockEntity); + if (ticker == null) { + return; + } - // 使用集中定义的 CardDef 列表,支持以后添加等级或改倍率而无需修改此逻辑 - int energyCardCount = getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD); + int speed = calculateSpeed(); + if (speed <= 0) { + return; + } - // 使用已注册的单一 Item 计算已安装卡数量(总计,用于能耗计算) + double requiredPower = calculateRequiredPower(speed, blockId); + if (!extractPower(requiredPower)) { + return; + } + + performTicks(blockEntity, ticker, speed); + } + + /** + * 检查网络节点是否有效。 + * @return 是否可以执行 tick + */ + private boolean isValidForTicking() { + return getGridNode() != null && getMainNode() != null && getMainNode().getGrid() != null; + } + + /** + * 获取目标方块实体的 ticker。 + * @param blockEntity 目标方块实体 + * @return ticker 或 null + */ + private BlockEntityTicker getTicker(T blockEntity) { + return getLevel().getBlockState(blockEntity.getBlockPos()) + .getTicker(getLevel(), (BlockEntityType) blockEntity.getType()); + } + + /** + * 计算加速倍率。 + * @return 生效的加速倍率 + */ + private int calculateSpeed() { int entitySpeedCardCount = getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get()); + if (entitySpeedCardCount <= 0) return 0; + return (int) PowerUtils.computeProductWithCap(getUpgrades(), 8); + } - // 使用工具方法从槽位直接计算乘积并应用 cap(最多 8 张卡) - long product = PowerUtils.computeProductWithCapFromStacks(this.getUpgrades(), 8); + /** + * 计算所需能量。 + * @param speed 加速倍率 + * @param blockId 目标方块ID + * @return 所需能量 + */ + private double calculateRequiredPower(int speed, String blockId) { + int energyCardCount = getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD); + double multiplier = ConfigParsingUtils.getMultiplierForBlock(blockId, List.of(ModConfig.INSTANCE.entityTickerMultipliers)); + return PowerUtils.computeFinalPowerForProduct(speed, energyCardCount) * multiplier; + } - // 如果没有任何实体加速卡,则不进行加速且不消耗额外能量(只保留部件的被动功耗) - if (entitySpeedCardCount <= 0) return; + /** + * 提取网络能量并更新状态,优先从 AE2 网络提取 AE 能量,不足时从磁盘提取 FE 能量。 + * @param requiredPower 所需能量(AE 单位) + * @return 是否成功提取足够能量 + */ + private boolean extractPower(double requiredPower) { + IEnergyService energyService = getMainNode().getGrid().getEnergyService(); + MEStorage storage = getMainNode().getGrid().getStorageService().getInventory(); + IActionSource source = IActionSource.ofMachine(this); + boolean appFluxLoaded = ModList.get().isLoaded("appflux"); + boolean preferDiskEnergy = appFluxLoaded && ModConfig.INSTANCE.prioritizeDiskEnergy; - // 计算本次 tick 所需能量:使用工具类根据 product 计算最终能耗 - double requiredPower = PowerUtils.computeFinalPowerForProduct(product, energyCardCount); - - int speed = (int) product; - - double multiplier = 1.0; - for (ConfigParsingUtils.MultiplierEntry me : ConfigParsingUtils.getCachedMultiplierEntries(List.of(ModConfig.INSTANCE.entityTickerMultipliers))) { - if (me.pattern.matcher(blockId).matches()) { - multiplier = Math.max(multiplier, me.multiplier); + // 如果 appflux 存在且优先磁盘能量,尝试提取 FE 能量 + if (appFluxLoaded && preferDiskEnergy) { + if (tryExtractFE(energyService, storage, requiredPower, source)) { + return true; } } - requiredPower *= multiplier; + // 尝试提取 AE 能量(当 appflux 不存在、优先 AE 能量或 FE 提取失败时) + double simulated = energyService.extractAEPower(requiredPower, Actionable.SIMULATE, PowerMultiplier.CONFIG); + if (simulated >= requiredPower) { + double extracted = energyService.extractAEPower(requiredPower, Actionable.MODULATE, PowerMultiplier.CONFIG); + boolean sufficient = extracted >= requiredPower; + updateNetworkEnergySufficient(sufficient); + return sufficient; + } + updateNetworkEnergySufficient(false); - // 先模拟提取以检查网络中是否有足够能量,再真正抽取 - double simulated = getMainNode().getGrid().getEnergyService() - .extractAEPower(requiredPower, Actionable.SIMULATE, PowerMultiplier.CONFIG); - if (simulated < requiredPower) return; + // 如果 appflux 存在且优先 AE 能量,尝试提取 FE 能量作为备用 + if (appFluxLoaded && !preferDiskEnergy) { + return tryExtractFE(energyService, storage, requiredPower, source); + } + return false; + } - double extractedPower = getMainNode().getGrid().getEnergyService() - .extractAEPower(requiredPower, Actionable.MODULATE, PowerMultiplier.CONFIG); - if (extractedPower < requiredPower) return; + private boolean tryExtractFE(IEnergyService energyService, MEStorage storage, double requiredPower, IActionSource source) { + try { + Class helperClass = Class.forName("com.extendedae_plus.util.FluxEnergyHelper"); + Method extractMethod = helperClass.getMethod( + "extractFE", + IEnergyService.class, + MEStorage.class, + long.class, + IActionSource.class + ); + long feRequired = (long) requiredPower << 1; // 1 AE = 2 FE + long feExtracted = (long) extractMethod.invoke(null, energyService, storage, feRequired, source); + if (feExtracted >= feRequired) { + updateNetworkEnergySufficient(true); + return true; + } + } catch (Exception e) { + // 如果反射失败,视为 FE 不可用 + } + updateNetworkEnergySufficient(false); + return false; + } - // 计算加速倍数:基于 2 的次方,并把 8 张映射到最大 1024x(2^10) - // 已由 product 计算得到 speed;上面已在没有卡时提前返回 - - // 执行 tick 操作 + /** + * 执行加速 tick 操作。 + * @param blockEntity 目标方块实体 + * @param ticker 方块实体 ticker + * @param speed 加速倍率 + */ + private void performTicks(T blockEntity, + BlockEntityTicker ticker, + int speed) { + // 执行 speed-1 次额外 tick(原生 tick 已包含 1 次) for (int i = 0; i < speed - 1; i++) { - blockEntityTicker.tick( + ticker.tick( blockEntity.getLevel(), blockEntity.getBlockPos(), blockEntity.getBlockState(), @@ -259,26 +344,18 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka } } - /** - * 判断部件是否有自定义名称 - * @return 是否有自定义名称 - */ @Override public boolean hasCustomName() { return super.hasCustomName(); } - /** - * 获取部件的显示名称 - * @return 显示名称 - */ @Override public @NotNull Component getDisplayName() { return super.getDisplayName(); } /** - * 创建自定义菜单(GUI) + * 创建菜单实例。 * @param containerId 容器ID * @param playerInventory 玩家背包 * @param player 玩家 @@ -292,7 +369,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka } /** - * 获取可用的升级卡槽数量 + * 获取升级卡槽数量。 * @return 升级卡槽数量 */ @Override diff --git a/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java b/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java index 3bb664a..751d318 100644 --- a/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java +++ b/src/main/java/com/extendedae_plus/ae/screen/EntitySpeedTickerScreen.java @@ -11,125 +11,115 @@ import appeng.util.Platform; import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu; import com.extendedae_plus.init.ModNetwork; import com.extendedae_plus.network.ToggleEntityTickerC2SPacket; -import com.extendedae_plus.util.PowerUtils; +import com.extendedae_plus.util.entitySpeed.PowerUtils; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; +import java.util.HashMap; import java.util.List; +import java.util.Map; +/** + * 实体加速器界面,显示加速状态、卡数量、能耗和倍率信息。 + */ public class EntitySpeedTickerScreen extends UpgradeableScreen { - private boolean eap$entitySpeedTickerEnabled = false; - private SettingToggleButton eap$entitySpeedTickerToggle; + private boolean eap$entitySpeedTickerEnabled = false; // 本地缓存的加速开关状态 + private final SettingToggleButton eap$entitySpeedTickerToggle; // 加速开关按钮 - public EntitySpeedTickerScreen( - EntitySpeedTickerMenu menu, Inventory playerInventory, Component title, ScreenStyle style) { + /** + * 构造函数,初始化界面和控件。 + * @param menu 实体加速器菜单 + * @param playerInventory 玩家背包 + * @param title 界面标题 + * @param style 界面样式 + */ + public EntitySpeedTickerScreen(EntitySpeedTickerMenu menu, Inventory playerInventory, Component title, ScreenStyle style) { super((C) menu, playerInventory, title, style); - this.addToLeftToolbar(CommonButtons.togglePowerUnit()); + this.addToLeftToolbar(CommonButtons.togglePowerUnit()); // 添加功率单位切换按钮 + this.eap$entitySpeedTickerEnabled = menu.getAccelerateEnabled(); - try{ - this.eap$entitySpeedTickerEnabled = menu.getAccelerateEnabled(); - }catch (Exception ignored){} - - // 使用 SettingToggleButton 的外观(原版图标),但自定义悬停描述为“智能阻挡” - // 不做本地切换,点击仅发送自定义C2S,显示由@GuiSync回传 + // 初始化加速开关按钮 eap$entitySpeedTickerToggle = new SettingToggleButton<>( Settings.BLOCKING_MODE, this.eap$entitySpeedTickerEnabled ? YesNo.YES : YesNo.NO, - (btn, backwards) -> { - // 不做本地切换,点击仅发送自定义C2S,显示由@GuiSync回传 - ModNetwork.CHANNEL.sendToServer(new ToggleEntityTickerC2SPacket()); - } + (btn, backwards) -> + ModNetwork.CHANNEL.sendToServer(new ToggleEntityTickerC2SPacket()) ) { @Override public List getTooltipMessage() { - // 如果目标在黑名单中,直接显示已禁用的提示 - try { - if (menu != null && menu.targetBlacklisted) { - var title = Component.literal("实体加速"); - var stateLine = Component.literal("已禁用(目标在黑名单)"); - return List.of(title, stateLine); - } - } catch (Exception ignored) {} - + if (menu.targetBlacklisted) { + return List.of( + Component.literal("实体加速"), + Component.literal("已禁用(目标在黑名单)") + ); + } boolean enabled = eap$entitySpeedTickerEnabled; - var title = Component.literal("实体加速"); - var stateLine = enabled - ? Component.literal("已启用: 将加速目标方块实体的tick") - : Component.literal("已关闭: 不会对目标方块实体进行加速"); - return List.of(title, stateLine); + return List.of( + Component.literal("实体加速"), + enabled ? Component.literal("已启用: 将加速目标方块实体的tick") : + Component.literal("已关闭: 不会对目标方块实体进行加速") + ); } @Override protected Icon getIcon() { - try { - if (menu != null && menu.targetBlacklisted) { - // 黑名单时显示禁用图标 - return Icon.INVALID; - } - } catch (Exception ignored) {} - - // 根据当前值显示不同图标(可按需替换 Icon 常量) - if (this.getCurrentValue() == YesNo.YES) { - return Icon.VALID; - } else { - return Icon.INVALID; - } + if (menu.targetBlacklisted) return Icon.INVALID; + return this.getCurrentValue() == YesNo.YES ? Icon.VALID : Icon.INVALID; } }; - // 初始化后立刻对齐当前@GuiSync状态,避免首帧显示不一致 eap$entitySpeedTickerToggle.set(this.eap$entitySpeedTickerEnabled ? YesNo.YES : YesNo.NO); - this.addToLeftToolbar(eap$entitySpeedTickerToggle); } + /** + * 在渲染前更新界面状态。 + */ @Override protected void updateBeforeRender() { super.updateBeforeRender(); - - if (this.eap$entitySpeedTickerToggle != null) { - boolean desired = this.eap$entitySpeedTickerEnabled; - if (this.menu != null) { - desired = this.menu.getAccelerateEnabled(); - } - - this.eap$entitySpeedTickerEnabled = desired; - // 如果目标在黑名单中,禁用切换并强制显示为关闭 - if (this.menu != null && this.menu.targetBlacklisted) { - this.eap$entitySpeedTickerToggle.set(YesNo.NO); - this.eap$entitySpeedTickerToggle.active = false; - } else { - this.eap$entitySpeedTickerToggle.set(desired ? YesNo.YES : YesNo.NO); - this.eap$entitySpeedTickerToggle.active = true; - } + if (eap$entitySpeedTickerToggle != null && menu != null) { + eap$entitySpeedTickerEnabled = menu.getAccelerateEnabled(); + // 如果目标在黑名单,禁用按钮并显示关闭状态 + eap$entitySpeedTickerToggle.set(menu.targetBlacklisted ? YesNo.NO : (eap$entitySpeedTickerEnabled ? YesNo.YES : YesNo.NO)); + eap$entitySpeedTickerToggle.active = !menu.targetBlacklisted; } textData(); } + /** + * 刷新界面显示。 + */ public void refreshGui() { textData(); } + /** + * 更新界面文本内容,包括加速状态、速度、能耗和倍率。 + */ private void textData() { - // 如果目标被黑名单禁止,则显示禁用状态并把数值显示为 0 + Map textContents = new HashMap<>(); if (getMenu().targetBlacklisted) { - setTextContent("enable", Component.translatable("screen.extendedae_plus.entity_speed_ticker.enable")); - setTextContent("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", 0)); - setTextContent("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(0.0, false))); - setTextContent("power_ratio", Component.translatable("screen.extendedae_plus.entity_speed_ticker.power_ratio", PowerUtils.formatPercentage(0.0))); - setTextContent("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", 0.0))); - return; + // 黑名单禁用时的默认显示 + textContents.put("enable", Component.translatable("screen.extendedae_plus.entity_speed_ticker.enable")); + textContents.put("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", 0)); + textContents.put("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(0.0, false))); + textContents.put("power_ratio", Component.translatable("screen.extendedae_plus.entity_speed_ticker.power_ratio", PowerUtils.formatPercentage(0.0))); + textContents.put("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", 0.0))); + } else { + // 正常状态下显示实际数据 + int energyCardCount = getMenu().energyCardCount; + double multiplier = getMenu().multiplier; + int effectiveSpeed = getMenu().effectiveSpeed; + double finalPower = PowerUtils.computeFinalPowerForProduct(effectiveSpeed, energyCardCount); + double remainingRatio = PowerUtils.getRemainingRatio(energyCardCount); + + textContents.put("enable", getMenu().networkEnergySufficient ? null : + Component.translatable("screen.extendedae_plus.entity_speed_ticker.warning_network_energy_insufficient")); + textContents.put("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", effectiveSpeed)); + textContents.put("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(finalPower, false))); + textContents.put("power_ratio", Component.translatable("screen.extendedae_plus.entity_speed_ticker.power_ratio", PowerUtils.formatPercentage(remainingRatio))); + textContents.put("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", multiplier))); } - - int energyCardCount = getMenu().energyCardCount; - double multiplier = getMenu().multiplier; - int effectiveSpeed = getMenu().effectiveSpeed; - - double finalPower = PowerUtils.computeFinalPowerForProduct(effectiveSpeed, energyCardCount); - double remainingRatio = PowerUtils.getRemainingRatio(energyCardCount); - - setTextContent("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", effectiveSpeed)); - setTextContent("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(finalPower, false))); - setTextContent("power_ratio", Component.translatable("screen.extendedae_plus.entity_speed_ticker.power_ratio", PowerUtils.formatPercentage(remainingRatio))); - setTextContent("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", multiplier))); + textContents.forEach(this::setTextContent); } } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/wireless/IWirelessEndpoint.java b/src/main/java/com/extendedae_plus/ae/wireless/IWirelessEndpoint.java similarity index 94% rename from src/main/java/com/extendedae_plus/wireless/IWirelessEndpoint.java rename to src/main/java/com/extendedae_plus/ae/wireless/IWirelessEndpoint.java index 15a991b..d21ebae 100644 --- a/src/main/java/com/extendedae_plus/wireless/IWirelessEndpoint.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/IWirelessEndpoint.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.wireless; +package com.extendedae_plus.ae.wireless; import appeng.api.networking.IGridNode; import net.minecraft.core.BlockPos; diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessMasterLink.java b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterLink.java similarity index 97% rename from src/main/java/com/extendedae_plus/wireless/WirelessMasterLink.java rename to src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterLink.java index 4024b49..6d40cc2 100644 --- a/src/main/java/com/extendedae_plus/wireless/WirelessMasterLink.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterLink.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.wireless; +package com.extendedae_plus.ae.wireless; import net.minecraft.server.level.ServerLevel; diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessMasterRegistry.java b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java similarity index 98% rename from src/main/java/com/extendedae_plus/wireless/WirelessMasterRegistry.java rename to src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java index a5f35b8..6d411a8 100644 --- a/src/main/java/com/extendedae_plus/wireless/WirelessMasterRegistry.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/WirelessMasterRegistry.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.wireless; +package com.extendedae_plus.ae.wireless; import com.extendedae_plus.config.ModConfig; import net.minecraft.resources.ResourceKey; diff --git a/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java b/src/main/java/com/extendedae_plus/ae/wireless/WirelessSlaveLink.java similarity index 99% rename from src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java rename to src/main/java/com/extendedae_plus/ae/wireless/WirelessSlaveLink.java index 84035fd..8196349 100644 --- a/src/main/java/com/extendedae_plus/wireless/WirelessSlaveLink.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/WirelessSlaveLink.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.wireless; +package com.extendedae_plus.ae.wireless; import appeng.api.networking.GridHelper; import appeng.api.networking.IGridNode; diff --git a/src/main/java/com/extendedae_plus/wireless/endpoint/GenericNodeEndpointImpl.java b/src/main/java/com/extendedae_plus/ae/wireless/endpoint/GenericNodeEndpointImpl.java similarity index 93% rename from src/main/java/com/extendedae_plus/wireless/endpoint/GenericNodeEndpointImpl.java rename to src/main/java/com/extendedae_plus/ae/wireless/endpoint/GenericNodeEndpointImpl.java index 84cd191..3653e12 100644 --- a/src/main/java/com/extendedae_plus/wireless/endpoint/GenericNodeEndpointImpl.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/endpoint/GenericNodeEndpointImpl.java @@ -1,7 +1,7 @@ -package com.extendedae_plus.wireless.endpoint; +package com.extendedae_plus.ae.wireless.endpoint; import appeng.api.networking.IGridNode; -import com.extendedae_plus.wireless.IWirelessEndpoint; +import com.extendedae_plus.ae.wireless.IWirelessEndpoint; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; diff --git a/src/main/java/com/extendedae_plus/wireless/endpoint/InterfaceNodeEndpointImpl.java b/src/main/java/com/extendedae_plus/ae/wireless/endpoint/InterfaceNodeEndpointImpl.java similarity index 92% rename from src/main/java/com/extendedae_plus/wireless/endpoint/InterfaceNodeEndpointImpl.java rename to src/main/java/com/extendedae_plus/ae/wireless/endpoint/InterfaceNodeEndpointImpl.java index 6736f4c..f6dbfff 100644 --- a/src/main/java/com/extendedae_plus/wireless/endpoint/InterfaceNodeEndpointImpl.java +++ b/src/main/java/com/extendedae_plus/ae/wireless/endpoint/InterfaceNodeEndpointImpl.java @@ -1,8 +1,8 @@ -package com.extendedae_plus.wireless.endpoint; +package com.extendedae_plus.ae.wireless.endpoint; import appeng.api.networking.IGridNode; import appeng.helpers.InterfaceLogicHost; -import com.extendedae_plus.wireless.IWirelessEndpoint; +import com.extendedae_plus.ae.wireless.IWirelessEndpoint; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; diff --git a/src/main/java/com/extendedae_plus/api/AdvancedBlockingHolder.java b/src/main/java/com/extendedae_plus/api/IAdvancedBlocking.java similarity index 74% rename from src/main/java/com/extendedae_plus/api/AdvancedBlockingHolder.java rename to src/main/java/com/extendedae_plus/api/IAdvancedBlocking.java index 52b8aaa..1895a7d 100644 --- a/src/main/java/com/extendedae_plus/api/AdvancedBlockingHolder.java +++ b/src/main/java/com/extendedae_plus/api/IAdvancedBlocking.java @@ -1,6 +1,6 @@ package com.extendedae_plus.api; -public interface AdvancedBlockingHolder { +public interface IAdvancedBlocking { boolean eap$getAdvancedBlocking(); void eap$setAdvancedBlocking(boolean value); diff --git a/src/main/java/com/extendedae_plus/api/ExPatternButtonsAccessor.java b/src/main/java/com/extendedae_plus/api/IExPatternButtonsAccessor.java similarity index 87% rename from src/main/java/com/extendedae_plus/api/ExPatternButtonsAccessor.java rename to src/main/java/com/extendedae_plus/api/IExPatternButtonsAccessor.java index d97f448..ac4d1ec 100644 --- a/src/main/java/com/extendedae_plus/api/ExPatternButtonsAccessor.java +++ b/src/main/java/com/extendedae_plus/api/IExPatternButtonsAccessor.java @@ -3,7 +3,7 @@ package com.extendedae_plus.api; /** * 由 {@code GuiExPatternProviderMixin} 实现,用于从通用的 Screen Mixin 中更新按钮布局。 */ -public interface ExPatternButtonsAccessor { +public interface IExPatternButtonsAccessor { /** * 在每帧调用以维护扩展样板供应器右侧按钮的可见性、重注册(窗口尺寸变化)与定位。 */ diff --git a/src/main/java/com/extendedae_plus/api/ExPatternPageAccessor.java b/src/main/java/com/extendedae_plus/api/IExPatternPageAccessor.java similarity index 82% rename from src/main/java/com/extendedae_plus/api/ExPatternPageAccessor.java rename to src/main/java/com/extendedae_plus/api/IExPatternPageAccessor.java index fca633f..c368e26 100644 --- a/src/main/java/com/extendedae_plus/api/ExPatternPageAccessor.java +++ b/src/main/java/com/extendedae_plus/api/IExPatternPageAccessor.java @@ -3,6 +3,6 @@ package com.extendedae_plus.api; /** * 由 GuiExPatternProviderMixin 实现,用于在客户端侧提供当前页号,避免反射读取 AE2 内部字段失败。 */ -public interface ExPatternPageAccessor { +public interface IExPatternPageAccessor { int eap$getCurrentPage(); } diff --git a/src/main/java/com/extendedae_plus/api/PatternProviderMenuAdvancedSync.java b/src/main/java/com/extendedae_plus/api/IPatternProviderMenuAdvancedSync.java similarity index 60% rename from src/main/java/com/extendedae_plus/api/PatternProviderMenuAdvancedSync.java rename to src/main/java/com/extendedae_plus/api/IPatternProviderMenuAdvancedSync.java index f43f52c..5d5147d 100644 --- a/src/main/java/com/extendedae_plus/api/PatternProviderMenuAdvancedSync.java +++ b/src/main/java/com/extendedae_plus/api/IPatternProviderMenuAdvancedSync.java @@ -1,5 +1,5 @@ package com.extendedae_plus.api; -public interface PatternProviderMenuAdvancedSync { +public interface IPatternProviderMenuAdvancedSync { boolean eap$getAdvancedBlockingSynced(); } diff --git a/src/main/java/com/extendedae_plus/api/PatternProviderMenuDoublingSync.java b/src/main/java/com/extendedae_plus/api/PatternProviderMenuDoublingSync.java deleted file mode 100644 index a9d1492..0000000 --- a/src/main/java/com/extendedae_plus/api/PatternProviderMenuDoublingSync.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.extendedae_plus.api; - -public interface PatternProviderMenuDoublingSync { - boolean eap$getSmartDoublingSynced(); -} diff --git a/src/main/java/com/extendedae_plus/api/SmartDoublingAwarePattern.java b/src/main/java/com/extendedae_plus/api/SmartDoublingAwarePattern.java deleted file mode 100644 index 5c18658..0000000 --- a/src/main/java/com/extendedae_plus/api/SmartDoublingAwarePattern.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.extendedae_plus.api; - -public interface SmartDoublingAwarePattern { - boolean eap$allowScaling(); - void eap$setAllowScaling(boolean allow); -} diff --git a/src/main/java/com/extendedae_plus/api/SmartDoublingHolder.java b/src/main/java/com/extendedae_plus/api/SmartDoublingHolder.java deleted file mode 100644 index b5af4ef..0000000 --- a/src/main/java/com/extendedae_plus/api/SmartDoublingHolder.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.extendedae_plus.api; - -public interface SmartDoublingHolder { - boolean eap$getSmartDoubling(); - void eap$setSmartDoubling(boolean value); -} diff --git a/src/main/java/com/extendedae_plus/bridge/InterfaceWirelessLinkBridge.java b/src/main/java/com/extendedae_plus/api/bridge/IInterfaceWirelessLinkBridge.java similarity index 92% rename from src/main/java/com/extendedae_plus/bridge/InterfaceWirelessLinkBridge.java rename to src/main/java/com/extendedae_plus/api/bridge/IInterfaceWirelessLinkBridge.java index d200f77..f83aea5 100644 --- a/src/main/java/com/extendedae_plus/bridge/InterfaceWirelessLinkBridge.java +++ b/src/main/java/com/extendedae_plus/api/bridge/IInterfaceWirelessLinkBridge.java @@ -1,9 +1,9 @@ -package com.extendedae_plus.bridge; +package com.extendedae_plus.api.bridge; /** * 非 mixin 包下的桥接接口,供 mixin 进行 instanceof 检测和回调。 */ -public interface InterfaceWirelessLinkBridge { +public interface IInterfaceWirelessLinkBridge { void eap$updateWirelessLink(); /** diff --git a/src/main/java/com/extendedae_plus/bridge/IUpgradableMenu.java b/src/main/java/com/extendedae_plus/api/bridge/IUpgradableMenu.java similarity index 89% rename from src/main/java/com/extendedae_plus/bridge/IUpgradableMenu.java rename to src/main/java/com/extendedae_plus/api/bridge/IUpgradableMenu.java index 470ccd5..4bdbbb7 100644 --- a/src/main/java/com/extendedae_plus/bridge/IUpgradableMenu.java +++ b/src/main/java/com/extendedae_plus/api/bridge/IUpgradableMenu.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.bridge; +package com.extendedae_plus.api.bridge; import appeng.api.upgrades.IUpgradeInventory; import appeng.menu.ToolboxMenu; diff --git a/src/main/java/com/extendedae_plus/api/smartDoubling/IPatternProviderMenuDoublingSync.java b/src/main/java/com/extendedae_plus/api/smartDoubling/IPatternProviderMenuDoublingSync.java new file mode 100644 index 0000000..8160d05 --- /dev/null +++ b/src/main/java/com/extendedae_plus/api/smartDoubling/IPatternProviderMenuDoublingSync.java @@ -0,0 +1,5 @@ +package com.extendedae_plus.api.smartDoubling; + +public interface IPatternProviderMenuDoublingSync { + boolean eap$getSmartDoublingSynced(); +} diff --git a/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoublingAwarePattern.java b/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoublingAwarePattern.java new file mode 100644 index 0000000..c62dc81 --- /dev/null +++ b/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoublingAwarePattern.java @@ -0,0 +1,6 @@ +package com.extendedae_plus.api.smartDoubling; + +public interface ISmartDoublingAwarePattern { + boolean eap$allowScaling(); + void eap$setAllowScaling(boolean allow); +} diff --git a/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoublingHolder.java b/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoublingHolder.java new file mode 100644 index 0000000..a1f3cb0 --- /dev/null +++ b/src/main/java/com/extendedae_plus/api/smartDoubling/ISmartDoublingHolder.java @@ -0,0 +1,6 @@ +package com.extendedae_plus.api.smartDoubling; + +public interface ISmartDoublingHolder { + boolean eap$getSmartDoubling(); + void eap$setSmartDoubling(boolean value); +} diff --git a/src/main/java/com/extendedae_plus/client/InputEvents.java b/src/main/java/com/extendedae_plus/client/InputEvents.java index e52cb36..f99765f 100644 --- a/src/main/java/com/extendedae_plus/client/InputEvents.java +++ b/src/main/java/com/extendedae_plus/client/InputEvents.java @@ -8,8 +8,8 @@ import com.extendedae_plus.init.ModNetwork; import com.extendedae_plus.integration.jei.JeiRuntimeProxy; import com.extendedae_plus.mixin.ae2.accessor.MEStorageScreenAccessor; import com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor; -import com.extendedae_plus.network.OpenCraftFromJeiC2SPacket; import com.extendedae_plus.network.PullFromJeiOrCraftC2SPacket; +import com.extendedae_plus.network.crafting.OpenCraftFromJeiC2SPacket; import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal; import mezz.jei.api.ingredients.ITypedIngredient; import net.minecraft.client.Minecraft; @@ -17,8 +17,8 @@ import net.minecraft.client.gui.screens.Screen; 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 net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.common.Mod; import org.lwjgl.glfw.GLFW; import java.util.Optional; diff --git a/src/main/java/com/extendedae_plus/client/screen/GlobalProviderModesScreen.java b/src/main/java/com/extendedae_plus/client/screen/GlobalProviderModesScreen.java index 49c36a8..87aff55 100644 --- a/src/main/java/com/extendedae_plus/client/screen/GlobalProviderModesScreen.java +++ b/src/main/java/com/extendedae_plus/client/screen/GlobalProviderModesScreen.java @@ -2,7 +2,7 @@ package com.extendedae_plus.client.screen; import com.extendedae_plus.init.ModNetwork; import com.extendedae_plus.menu.NetworkPatternControllerMenu; -import com.extendedae_plus.network.GlobalToggleProviderModesC2SPacket; +import com.extendedae_plus.network.provider.GlobalToggleProviderModesC2SPacket; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.network.chat.Component; diff --git a/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java b/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java index 9aa03ff..c78c7c7 100644 --- a/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java +++ b/src/main/java/com/extendedae_plus/compat/UpgradeSlotCompat.java @@ -2,7 +2,6 @@ package com.extendedae_plus.compat; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; -import appeng.api.upgrades.UpgradeInventories; import appeng.client.gui.style.ScreenStyle; import appeng.client.gui.widgets.ToolboxPanel; import appeng.client.gui.widgets.UpgradesPanel; @@ -41,12 +40,7 @@ public class UpgradeSlotCompat { */ public static boolean shouldEnableUpgradeSlots() { boolean appfluxExists = isAppfluxPresent(); - - if (appfluxExists) { - return false; - } else { - return true; - } + return !appfluxExists; } /** @@ -97,8 +91,6 @@ public class UpgradeSlotCompat { if (menu instanceof IUpgradeableMenuCompat compatMenu) { compatMenu.setCompatToolbox(toolbox); } - - ExtendedAELogger.LOGGER.debug("成功为PatternProviderMenu初始化升级功能"); return true; } } catch (Exception e) { @@ -144,8 +136,6 @@ public class UpgradeSlotCompat { ToolboxPanel toolboxPanel = new ToolboxPanel(style, toolbox.getName()); addMethod.invoke(widgets, "toolbox", toolboxPanel); } - - ExtendedAELogger.LOGGER.debug("成功为PatternProviderScreen添加升级面板"); return true; } catch (NoSuchMethodException e) { // 尝试其他可能的方法签名 @@ -170,8 +160,6 @@ public class UpgradeSlotCompat { ToolboxPanel toolboxPanel = new ToolboxPanel(style, toolbox.getName()); putMethod.invoke(widgets, "toolbox", toolboxPanel); } - - ExtendedAELogger.LOGGER.debug("成功为PatternProviderScreen添加升级面板(使用put方法)"); return true; } catch (Exception e2) { ExtendedAELogger.LOGGER.error("反射调用widgets方法失败", e2); diff --git a/src/main/java/com/extendedae_plus/config/ModConfig.java b/src/main/java/com/extendedae_plus/config/ModConfig.java index 413c54b..173ae83 100644 --- a/src/main/java/com/extendedae_plus/config/ModConfig.java +++ b/src/main/java/com/extendedae_plus/config/ModConfig.java @@ -125,4 +125,11 @@ public final class ModConfig { @Configurable.Range(min = 100, max = Integer.MAX_VALUE) public int craftingPauseThreshold = 100000; + @Configurable + @Configurable.Comment(value = { + "是否优先从磁盘提取FE能量(仅当Applied Flux模组存在时生效)", + "开启后,将优先尝试从磁盘提取FE能量;反之优先消耗AE网络中的能量" + }) + @Configurable.Synchronized + public boolean prioritizeDiskEnergy = true; } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java b/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java index 09b843d..6884308 100644 --- a/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java +++ b/src/main/java/com/extendedae_plus/content/wireless/WirelessTransceiverBlockEntity.java @@ -3,11 +3,11 @@ package com.extendedae_plus.content.wireless; import appeng.api.networking.*; import appeng.api.util.AECableType; import appeng.blockentity.AEBaseBlockEntity; +import com.extendedae_plus.ae.wireless.IWirelessEndpoint; +import com.extendedae_plus.ae.wireless.WirelessMasterLink; +import com.extendedae_plus.ae.wireless.WirelessSlaveLink; import com.extendedae_plus.init.ModBlockEntities; import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.wireless.IWirelessEndpoint; -import com.extendedae_plus.wireless.WirelessMasterLink; -import com.extendedae_plus.wireless.WirelessSlaveLink; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; diff --git a/src/main/java/com/extendedae_plus/init/ModNetwork.java b/src/main/java/com/extendedae_plus/init/ModNetwork.java index e281d81..666991a 100644 --- a/src/main/java/com/extendedae_plus/init/ModNetwork.java +++ b/src/main/java/com/extendedae_plus/init/ModNetwork.java @@ -2,6 +2,11 @@ package com.extendedae_plus.init; import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.network.*; +import com.extendedae_plus.network.crafting.CraftingMonitorJumpC2SPacket; +import com.extendedae_plus.network.crafting.CraftingMonitorOpenProviderC2SPacket; +import com.extendedae_plus.network.crafting.OpenCraftFromJeiC2SPacket; +import com.extendedae_plus.network.meInterface.InterfaceAdjustConfigAmountC2SPacket; +import com.extendedae_plus.network.provider.*; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.network.NetworkDirection; import net.minecraftforge.network.NetworkRegistry; diff --git a/src/main/java/com/extendedae_plus/init/UpgradeCards.java b/src/main/java/com/extendedae_plus/init/UpgradeCards.java index c7b9c33..747cecb 100644 --- a/src/main/java/com/extendedae_plus/init/UpgradeCards.java +++ b/src/main/java/com/extendedae_plus/init/UpgradeCards.java @@ -6,14 +6,8 @@ import appeng.core.definitions.AEItems; import appeng.core.definitions.AEParts; import appeng.core.localization.GuiText; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import static com.glodblock.github.extendedae.common.EPPItemAndBlock.EX_PATTERN_PROVIDER; -import static com.glodblock.github.extendedae.common.EPPItemAndBlock.EX_PATTERN_PROVIDER_PART; -import static com.glodblock.github.extendedae.common.EPPItemAndBlock.EX_INTERFACE; -import static com.glodblock.github.extendedae.common.EPPItemAndBlock.EX_INTERFACE_PART; -import static com.glodblock.github.extendedae.common.EPPItemAndBlock.OVERSIZE_INTERFACE; -import static com.glodblock.github.extendedae.common.EPPItemAndBlock.OVERSIZE_INTERFACE_PART; -import static com.glodblock.github.extendedae.common.EPPItemAndBlock.EX_IMPORT_BUS; -import static com.glodblock.github.extendedae.common.EPPItemAndBlock.EX_EXPORT_BUS; + +import static com.glodblock.github.extendedae.common.EPPItemAndBlock.*; /** * diff --git a/src/main/java/com/extendedae_plus/integration/jade/WirelessTransceiverProvider.java b/src/main/java/com/extendedae_plus/integration/jade/WirelessTransceiverProvider.java index 7786e1c..d0529fc 100644 --- a/src/main/java/com/extendedae_plus/integration/jade/WirelessTransceiverProvider.java +++ b/src/main/java/com/extendedae_plus/integration/jade/WirelessTransceiverProvider.java @@ -2,9 +2,9 @@ package com.extendedae_plus.integration.jade; import appeng.api.networking.IGrid; import appeng.api.networking.IGridNode; +import com.extendedae_plus.ae.wireless.IWirelessEndpoint; +import com.extendedae_plus.ae.wireless.WirelessMasterRegistry; import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity; -import com.extendedae_plus.wireless.IWirelessEndpoint; -import com.extendedae_plus.wireless.WirelessMasterRegistry; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; diff --git a/src/main/java/com/extendedae_plus/mixin/MixinConditions.java b/src/main/java/com/extendedae_plus/mixin/MixinConditions.java index 595bf1c..dbf7799 100644 --- a/src/main/java/com/extendedae_plus/mixin/MixinConditions.java +++ b/src/main/java/com/extendedae_plus/mixin/MixinConditions.java @@ -1,6 +1,5 @@ package com.extendedae_plus.mixin; -import net.minecraftforge.fml.ModList; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; @@ -27,7 +26,6 @@ public class MixinConditions implements IMixinConfigPlugin { public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { // 对于升级相关的Mixin,检查appflux是否存在 if (mixinClassName.contains("PatternProviderMenuUpgradesMixin") || - mixinClassName.contains("PatternProviderScreenUpgradesMixin") || mixinClassName.contains("PatternProviderLogicUpgradesMixin") || mixinClassName.contains("PatternProviderLogicHostUpgradesMixin")) { diff --git a/src/main/java/com/extendedae_plus/mixin/advancedae/AdvPatternProviderLogicContainsRedirectMixin.java b/src/main/java/com/extendedae_plus/mixin/advancedae/AdvPatternProviderLogicContainsRedirectMixin.java index 0773388..fb482b9 100644 --- a/src/main/java/com/extendedae_plus/mixin/advancedae/AdvPatternProviderLogicContainsRedirectMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/advancedae/AdvPatternProviderLogicContainsRedirectMixin.java @@ -1,7 +1,7 @@ package com.extendedae_plus.mixin.advancedae; import appeng.api.crafting.IPatternDetails; -import com.extendedae_plus.content.ScaledProcessingPattern; +import com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern; import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/com/extendedae_plus/mixin/advancedae/client/gui/AdvPatternProviderScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/advancedae/client/gui/AdvPatternProviderScreenMixin.java index 5cd6c30..813c164 100644 --- a/src/main/java/com/extendedae_plus/mixin/advancedae/client/gui/AdvPatternProviderScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/advancedae/client/gui/AdvPatternProviderScreenMixin.java @@ -5,18 +5,17 @@ import appeng.api.config.YesNo; import appeng.client.gui.AEBaseScreen; import appeng.client.gui.style.ScreenStyle; import appeng.client.gui.widgets.SettingToggleButton; -import com.extendedae_plus.api.ExPatternButtonsAccessor; -import com.extendedae_plus.api.PatternProviderMenuAdvancedSync; -import com.extendedae_plus.api.PatternProviderMenuDoublingSync; +import com.extendedae_plus.api.IExPatternButtonsAccessor; +import com.extendedae_plus.api.IPatternProviderMenuAdvancedSync; +import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync; import com.extendedae_plus.init.ModNetwork; -import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket; -import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket; +import com.extendedae_plus.network.provider.ToggleAdvancedBlockingC2SPacket; +import com.extendedae_plus.network.provider.ToggleSmartDoublingC2SPacket; import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; import net.pedroksl.advanced_ae.client.gui.AdvPatternProviderScreen; import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu; -import org.checkerframework.checker.units.qual.C; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -45,15 +44,15 @@ public abstract class AdvPatternProviderScreenMixin extends AEBaseScreen { - // 空接口:避免在 AEBaseScreen 上声明不存在方法的 Invoker 导致编译错误 -} diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicAccessor.java b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicAccessor.java index 6155a13..eaf4672 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicAccessor.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicAccessor.java @@ -1,11 +1,14 @@ package com.extendedae_plus.mixin.ae2.accessor; +import appeng.api.crafting.IPatternDetails; import appeng.api.networking.IManagedGridNode; import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogicHost; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; +import java.util.List; + @Mixin(PatternProviderLogic.class) public interface PatternProviderLogicAccessor { @Accessor(value = "host", remap = false) @@ -13,4 +16,7 @@ public interface PatternProviderLogicAccessor { @Accessor(value = "mainNode", remap = false) IManagedGridNode eap$mainNode(); + + @Accessor(value = "patterns" , remap = false) + List eap$patterns(); } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicPatternInputsAccessor.java b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicPatternInputsAccessor.java deleted file mode 100644 index 3f62fd4..0000000 --- a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicPatternInputsAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.extendedae_plus.mixin.ae2.accessor; - -import appeng.api.stacks.AEKey; -import appeng.helpers.patternprovider.PatternProviderLogic; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.Set; - -@Mixin(PatternProviderLogic.class) -public interface PatternProviderLogicPatternInputsAccessor { - @Accessor(value = "patternInputs",remap = false) - Set eap$patternInputs(); -} diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicPatternsAccessor.java b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicPatternsAccessor.java deleted file mode 100644 index c1471e3..0000000 --- a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderLogicPatternsAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.extendedae_plus.mixin.ae2.accessor; - -import appeng.api.crafting.IPatternDetails; -import appeng.helpers.patternprovider.PatternProviderLogic; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.List; - -@Mixin(value = PatternProviderLogic.class, remap = false) -public interface PatternProviderLogicPatternsAccessor { - @Accessor("patterns") - List eap$patterns(); -} diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderMenuAdvancedAccessor.java b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderMenuAccessor.java similarity index 87% rename from src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderMenuAdvancedAccessor.java rename to src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderMenuAccessor.java index 18ca7b7..a1d296f 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderMenuAdvancedAccessor.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/accessor/PatternProviderMenuAccessor.java @@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; @Mixin(PatternProviderMenu.class) -public interface PatternProviderMenuAdvancedAccessor { +public interface PatternProviderMenuAccessor { @Accessor(value = "logic", remap = false) PatternProviderLogic eap$logic(); } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingServiceGetProvidersMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingServiceGetProvidersMixin.java index ccc4812..1a508c2 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingServiceGetProvidersMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingServiceGetProvidersMixin.java @@ -2,7 +2,7 @@ package com.extendedae_plus.mixin.ae2.autopattern; import appeng.api.crafting.IPatternDetails; import appeng.me.service.CraftingService; -import com.extendedae_plus.content.ScaledProcessingPattern; +import com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyArg; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeNodeMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeNodeMixin.java index b2651d5..c37d9b0 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeNodeMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeNodeMixin.java @@ -3,14 +3,14 @@ package com.extendedae_plus.mixin.ae2.autopattern; import appeng.api.stacks.KeyCounter; import appeng.crafting.CraftingTreeNode; import appeng.crafting.inv.CraftingSimulationState; -import com.extendedae_plus.util.RequestedAmountHolder; +import com.extendedae_plus.util.smartDoubling.RequestedAmountHolder; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -@Mixin(value = CraftingTreeNode.class,remap = false) +@Mixin(value = CraftingTreeNode.class, remap = false) public class CraftingTreeNodeMixin { @Inject(method = "request(Lappeng/crafting/inv/CraftingSimulationState;JLappeng/api/stacks/KeyCounter;)V", at = @At(value = "INVOKE", @@ -18,13 +18,6 @@ public class CraftingTreeNodeMixin { locals = LocalCapture.CAPTURE_FAILHARD) private void captureRequestedAmount(CraftingSimulationState inv, long requestedAmount, KeyCounter containerItems, CallbackInfo ci) { // push the requestedAmount before addContainerItems is called - RequestedAmountHolder.push(requestedAmount); - } - - @Inject(method = "request(Lappeng/crafting/inv/CraftingSimulationState;JLappeng/api/stacks/KeyCounter;)V", - at = @At(value = "RETURN")) - private void clearRequestedAmountOnReturn(CraftingSimulationState inv, long requestedAmount, KeyCounter containerItems, CallbackInfo ci) { - // pop the pushed requested amount on return - RequestedAmountHolder.pop(); + RequestedAmountHolder.push(requestedAmount); } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeProcessMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeProcessMixin.java index 8f96a90..30a2c80 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeProcessMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/CraftingTreeProcessMixin.java @@ -9,11 +9,11 @@ import appeng.crafting.CraftingTreeNode; import appeng.crafting.CraftingTreeProcess; import appeng.crafting.pattern.AEProcessingPattern; import appeng.me.service.CraftingService; -import com.extendedae_plus.api.SmartDoublingAwarePattern; +import com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern; +import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern; import com.extendedae_plus.config.ModConfig; -import com.extendedae_plus.content.ScaledProcessingPattern; -import com.extendedae_plus.util.PatternScaler; -import com.extendedae_plus.util.RequestedAmountHolder; +import com.extendedae_plus.util.smartDoubling.PatternScaler; +import com.extendedae_plus.util.smartDoubling.RequestedAmountHolder; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; @@ -41,7 +41,7 @@ public abstract class CraftingTreeProcessMixin { // 若传入的 details 已经是缩放样板,且原始样板不允许缩放,则直接解包为原始样板 if (details instanceof ScaledProcessingPattern sp) { var proc0 = sp.getOriginal(); - if (proc0 instanceof SmartDoublingAwarePattern aware0 && !aware0.eap$allowScaling()) { + if (proc0 instanceof ISmartDoublingAwarePattern aware0 && !aware0.eap$allowScaling()) { return proc0; } } @@ -49,13 +49,14 @@ public abstract class CraftingTreeProcessMixin { if (!(details instanceof AEProcessingPattern proc)) return original; // 若样板标记为不允许缩放,则直接跳过 - if (proc instanceof SmartDoublingAwarePattern aware && !aware.eap$allowScaling()) { + if (proc instanceof ISmartDoublingAwarePattern aware && !aware.eap$allowScaling()) { return original; } CraftingTreeNodeAccessor parentAcc = (CraftingTreeNodeAccessor) craftingTreeNode; AEKey parentTarget = parentAcc.eap$getWhat(); long requested = RequestedAmountHolder.get(); + RequestedAmountHolder.pop(); // 根据配置决定是否在 provider 间轮询分配请求量(默认开启) long perProvider = 1L; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/PatternProviderLogicContainsRedirectMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/PatternProviderLogicContainsRedirectMixin.java index d6dc2a5..a1b6bf7 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/PatternProviderLogicContainsRedirectMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/autopattern/PatternProviderLogicContainsRedirectMixin.java @@ -2,7 +2,7 @@ package com.extendedae_plus.mixin.ae2.autopattern; import appeng.api.crafting.IPatternDetails; import appeng.helpers.patternprovider.PatternProviderLogic; -import com.extendedae_plus.content.ScaledProcessingPattern; +import com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java index f65d128..df7e08a 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/AEBaseScreenMixin.java @@ -13,14 +13,14 @@ import appeng.client.gui.style.ScreenStyle; import appeng.client.gui.style.Text; import appeng.client.gui.style.TextAlignment; import appeng.menu.slot.AppEngSlot; -import com.extendedae_plus.api.ExPatternPageAccessor; +import com.extendedae_plus.api.IExPatternPageAccessor; import com.extendedae_plus.content.ClientPatternHighlightStore; import com.extendedae_plus.init.ModNetwork; -import com.extendedae_plus.network.CraftingMonitorJumpC2SPacket; -import com.extendedae_plus.network.CraftingMonitorOpenProviderC2SPacket; +import com.extendedae_plus.mixin.ae2.accessor.AEBaseScreenAccessor; +import com.extendedae_plus.network.crafting.CraftingMonitorJumpC2SPacket; +import com.extendedae_plus.network.crafting.CraftingMonitorOpenProviderC2SPacket; import com.extendedae_plus.util.GuiUtil; import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider; -import com.mojang.logging.LogUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; @@ -40,17 +40,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(AEBaseScreen.class) public abstract class AEBaseScreenMixin { - @Unique - private ScreenStyle eap$getStyle(Object self) { - try { - var f = self.getClass().getDeclaredField("style"); - f.setAccessible(true); - Object v = f.get(self); - if (v instanceof ScreenStyle s) return s; - } catch (Throwable ignored) {} - return null; - } - /** * 在 AEBaseScreen 的 mouseClicked 入口拦截 CraftingCPUScreen 的 Shift+左键, * 读取鼠标下的 AEKey 并发送 CraftingMonitorJumpC2SPacket。 @@ -77,8 +66,7 @@ public abstract class AEBaseScreenMixin { } ModNetwork.CHANNEL.sendToServer(new CraftingMonitorJumpC2SPacket(key)); cir.setReturnValue(true); - } catch (Throwable ignored) { - } + } catch (Throwable ignored) {} } /** @@ -107,8 +95,7 @@ public abstract class AEBaseScreenMixin { } ModNetwork.CHANNEL.sendToServer(new CraftingMonitorOpenProviderC2SPacket(key)); cir.setReturnValue(true); - } catch (Throwable ignored) { - } + } catch (Throwable ignored) {} } @Unique @@ -266,7 +253,7 @@ public abstract class AEBaseScreenMixin { int cur = 1; int max = 1; - if (self instanceof ExPatternPageAccessor accessor) { + if (self instanceof IExPatternPageAccessor accessor) { cur = Math.max(0, accessor.eap$getCurrentPage()) + 1; } try { @@ -281,7 +268,7 @@ public abstract class AEBaseScreenMixin { String pageText = "第" + cur + "页" + "/" + max + "页"; - ScreenStyle style = eap$getStyle(self); + ScreenStyle style = ((AEBaseScreenAccessor) this).eap$getStyle(); int color = 0xFFFFFFFF; if (style != null) { try { @@ -299,11 +286,9 @@ public abstract class AEBaseScreenMixin { guiGraphics.drawString(font, pageText, lineWidth + padding, 0, color, false); guiGraphics.pose().popPose(); } - } catch (Throwable ignored) { - } + } catch (Throwable ignored) {} } - @Shadow(remap = false) protected void setTextContent(String id, Component content) {}; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java index b03fabc..e998b5c 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/InterfaceScreenMixin.java @@ -3,17 +3,15 @@ package com.extendedae_plus.mixin.ae2.client.gui; import appeng.client.gui.AEBaseScreen; import appeng.client.gui.implementations.InterfaceScreen; import appeng.menu.AEBaseMenu; -import com.extendedae_plus.NewIcon; -import com.extendedae_plus.init.ModNetwork; -import com.extendedae_plus.network.InterfaceAdjustConfigAmountC2SPacket; import appeng.menu.SlotSemantics; -import net.minecraft.world.inventory.Slot; +import appeng.menu.implementations.InterfaceMenu; +import com.extendedae_plus.ae.client.gui.NewIcon; +import com.extendedae_plus.init.ModNetwork; import com.extendedae_plus.mixin.accessor.AbstractContainerScreenAccessor; import com.extendedae_plus.mixin.accessor.ScreenAccessor; +import com.extendedae_plus.network.meInterface.InterfaceAdjustConfigAmountC2SPacket; import com.glodblock.github.extendedae.client.button.ActionEPPButton; -import net.minecraft.client.gui.components.Tooltip; -import net.minecraft.network.chat.Component; -import com.mojang.logging.LogUtils; +import net.minecraft.world.inventory.Slot; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -170,7 +168,7 @@ public abstract class InterfaceScreenMixin { // 获取菜单与配置槽列表 var screen = (AEBaseScreen) (Object) this; var menu = screen.getMenu(); - if (!(menu instanceof appeng.menu.implementations.InterfaceMenu interfaceMenu)) { + if (!(menu instanceof InterfaceMenu interfaceMenu)) { return; } var configSlots = interfaceMenu.getSlots(SlotSemantics.CONFIG); @@ -273,7 +271,7 @@ public abstract class InterfaceScreenMixin { } var screen = (AEBaseScreen) (Object) this; var menu = screen.getMenu(); - if (!(menu instanceof appeng.menu.implementations.InterfaceMenu interfaceMenu)) { + if (!(menu instanceof InterfaceMenu interfaceMenu)) { return; } var configSlots = interfaceMenu.getSlots(SlotSemantics.CONFIG); diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternEncodingTermScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternEncodingTermScreenMixin.java index 23c262f..eaa7a16 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternEncodingTermScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternEncodingTermScreenMixin.java @@ -11,6 +11,7 @@ import com.extendedae_plus.init.ModNetwork; import com.extendedae_plus.mixin.accessor.AbstractContainerScreenAccessor; import com.extendedae_plus.mixin.accessor.ScreenAccessor; import com.extendedae_plus.mixin.ae2.accessor.AEBaseScreenAccessor; +import com.extendedae_plus.network.provider.RequestProvidersListC2SPacket; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.renderer.Rect2i; @@ -41,7 +42,7 @@ public abstract class PatternEncodingTermScreenMixin { // 复用已存在的按钮实例,避免重复创建 if (eap$uploadBtn == null) { eap$uploadBtn = new IconButton(btn -> ModNetwork.CHANNEL - .sendToServer(new com.extendedae_plus.network.RequestProvidersListC2SPacket())) { + .sendToServer(new RequestProvidersListC2SPacket())) { private final float eap$scale = 0.75f; // 约 12x12 @Override diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderCloseMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderCloseMixin.java index 4613b2c..4370433 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderCloseMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderCloseMixin.java @@ -16,7 +16,6 @@ public class PatternProviderCloseMixin { if (((Object) this) instanceof PatternProviderScreen) { ClientPatternHighlightStore.clearAll(); } - } catch (Throwable ignored) { - } + } catch (Throwable ignored) {} } } \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenMixin.java index 863fab3..a47eb31 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenMixin.java @@ -7,12 +7,12 @@ import appeng.client.gui.implementations.PatternProviderScreen; import appeng.client.gui.style.ScreenStyle; import appeng.client.gui.widgets.SettingToggleButton; import appeng.menu.implementations.PatternProviderMenu; -import com.extendedae_plus.api.ExPatternButtonsAccessor; -import com.extendedae_plus.api.PatternProviderMenuAdvancedSync; -import com.extendedae_plus.api.PatternProviderMenuDoublingSync; +import com.extendedae_plus.api.IExPatternButtonsAccessor; +import com.extendedae_plus.api.IPatternProviderMenuAdvancedSync; +import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync; import com.extendedae_plus.init.ModNetwork; -import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket; -import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket; +import com.extendedae_plus.network.provider.ToggleAdvancedBlockingC2SPacket; +import com.extendedae_plus.network.provider.ToggleSmartDoublingC2SPacket; import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; @@ -52,7 +52,7 @@ public abstract class PatternProviderScreenMixin private void eap$initAdvancedBlocking(C menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) { // 使用 @GuiSync 初始化 try { - if (menu instanceof PatternProviderMenuAdvancedSync sync) { + if (menu instanceof IPatternProviderMenuAdvancedSync sync) { this.eap$AdvancedBlockingEnabled = sync.eap$getAdvancedBlockingSynced(); } } catch (Throwable t) { @@ -85,7 +85,7 @@ public abstract class PatternProviderScreenMixin // 智能翻倍按钮:与高级阻挡同款样式,点击仅发送C2S,状态由@GuiSync驱动 try { - if (menu instanceof PatternProviderMenuDoublingSync sync2) { + if (menu instanceof IPatternProviderMenuDoublingSync sync2) { this.eap$SmartDoublingEnabled = sync2.eap$getSmartDoublingSynced(); } } catch (Throwable t) { @@ -119,7 +119,7 @@ public abstract class PatternProviderScreenMixin private void eap$updateAdvancedBlocking(CallbackInfo ci) { if (this.eap$AdvancedBlockingToggle != null) { boolean desired = this.eap$AdvancedBlockingEnabled; - if (this.menu instanceof PatternProviderMenuAdvancedSync sync) { + if (this.menu instanceof IPatternProviderMenuAdvancedSync sync) { desired = sync.eap$getAdvancedBlockingSynced(); } this.eap$AdvancedBlockingEnabled = desired; @@ -128,7 +128,7 @@ public abstract class PatternProviderScreenMixin if (this.eap$SmartDoublingToggle != null) { boolean desired2 = this.eap$SmartDoublingEnabled; - if (this.menu instanceof PatternProviderMenuDoublingSync sync2) { + if (this.menu instanceof IPatternProviderMenuDoublingSync sync2) { desired2 = sync2.eap$getSmartDoublingSynced(); } this.eap$SmartDoublingEnabled = desired2; @@ -137,7 +137,7 @@ public abstract class PatternProviderScreenMixin if ((Object) this instanceof GuiExPatternProvider) { try { - ((ExPatternButtonsAccessor) this).eap$updateButtonsLayout(); + ((IExPatternButtonsAccessor) this).eap$updateButtonsLayout(); } catch (Throwable t) { LOGGER.debug("[EAP] updateButtonsLayout skipped: {}", t.toString()); } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java deleted file mode 100644 index d02b4f9..0000000 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/PatternProviderScreenUpgradesMixin.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.extendedae_plus.mixin.ae2.client.gui; - -import appeng.api.upgrades.Upgrades; -import appeng.client.gui.AEBaseScreen; -import appeng.client.gui.implementations.PatternProviderScreen; -import appeng.client.gui.style.ScreenStyle; -import appeng.client.gui.widgets.ToolboxPanel; -import appeng.client.gui.widgets.UpgradesPanel; -import appeng.core.localization.GuiText; -import appeng.menu.SlotSemantics; -import appeng.menu.implementations.PatternProviderMenu; -import com.extendedae_plus.bridge.IUpgradableMenu; -import com.extendedae_plus.compat.UpgradeSlotCompat; -import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.player.Inventory; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.ArrayList; -import java.util.List; - -@Mixin(value = PatternProviderScreen.class, priority = 2000, remap = false) -public abstract class PatternProviderScreenUpgradesMixin extends AEBaseScreen { - - @Inject(method = "", at = @At("TAIL")) - private void eap$initUpgrades(PatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) { - // 只有在应该启用升级卡槽时才添加升级面板 - if (!UpgradeSlotCompat.shouldAddUpgradePanelToScreen()) { - return; - } - - this.widgets.add("upgrades", new UpgradesPanel( - menu.getSlots(SlotSemantics.UPGRADE), - this::eap$getCompatibleUpgrades)); - if (((IUpgradableMenu) menu).getToolbox() != null && ((IUpgradableMenu) menu).getToolbox().isPresent()) { - this.widgets.add("toolbox", new ToolboxPanel(style, ((IUpgradableMenu) menu).getToolbox().getName())); - } - } - - @Unique - private List eap$getCompatibleUpgrades() { - var list = new ArrayList(); - list.add(GuiText.CompatibleUpgrades.text()); - list.addAll(Upgrades.getTooltipLinesForMachine(((IUpgradableMenu) menu).getUpgrades().getUpgradableItem())); - return list; - } - - public PatternProviderScreenUpgradesMixin(C menu, Inventory playerInventory, Component title, ScreenStyle style) { - super(menu, playerInventory, title, style); - } -} diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/SlotGridLayoutMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/SlotGridLayoutMixin.java index aa2267c..b40d099 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/SlotGridLayoutMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/client/gui/SlotGridLayoutMixin.java @@ -2,6 +2,7 @@ package com.extendedae_plus.mixin.ae2.client.gui; import appeng.client.Point; import appeng.client.gui.layout.SlotGridLayout; +import com.extendedae_plus.api.IExPatternPageAccessor; import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; @@ -32,7 +33,7 @@ public abstract class SlotGridLayoutMixin { // 读取实际当前页码:优先从 GUI accessor,其次反射容器,失败则为 0 int currentPage = 0; try { - if (screen instanceof com.extendedae_plus.api.ExPatternPageAccessor accessor) { + if (screen instanceof IExPatternPageAccessor accessor) { currentPage = accessor.eap$getCurrentPage(); } else { var menu = ((com.glodblock.github.extendedae.client.gui.GuiExPatternProvider) screen).getMenu(); diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java index 6017f35..6d3802e 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java @@ -8,11 +8,11 @@ import appeng.api.upgrades.UpgradeInventories; import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogicHost; import com.extendedae_plus.ae.items.ChannelCardItem; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; +import com.extendedae_plus.ae.wireless.WirelessSlaveLink; +import com.extendedae_plus.ae.wireless.endpoint.GenericNodeEndpointImpl; +import com.extendedae_plus.api.bridge.IInterfaceWirelessLinkBridge; import com.extendedae_plus.compat.UpgradeSlotCompat; import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.wireless.WirelessSlaveLink; -import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Final; @@ -31,7 +31,7 @@ import java.util.List; * 根据appflux是否存在来决定是否实现IUpgradeableObject接口 */ @Mixin(value = PatternProviderLogic.class, priority = 500, remap = false) -public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObject, InterfaceWirelessLinkBridge { +public abstract class PatternProviderLogicCompatMixin implements IUpgradeableObject, IInterfaceWirelessLinkBridge { @Unique private IUpgradeInventory eap$compatUpgrades = UpgradeInventories.empty(); diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java index bb4b6cf..a5ea0e3 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelCardMixin.java @@ -4,11 +4,10 @@ import appeng.api.upgrades.IUpgradeInventory; import appeng.helpers.InterfaceLogic; import appeng.helpers.InterfaceLogicHost; import com.extendedae_plus.ae.items.ChannelCardItem; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; +import com.extendedae_plus.ae.wireless.WirelessSlaveLink; +import com.extendedae_plus.ae.wireless.endpoint.InterfaceNodeEndpointImpl; +import com.extendedae_plus.api.bridge.IInterfaceWirelessLinkBridge; import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.wireless.WirelessSlaveLink; -import com.extendedae_plus.wireless.endpoint.InterfaceNodeEndpointImpl; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -18,7 +17,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(InterfaceLogic.class) -public abstract class InterfaceLogicChannelCardMixin implements InterfaceWirelessLinkBridge { +public abstract class InterfaceLogicChannelCardMixin implements IInterfaceWirelessLinkBridge { @Shadow(remap = false) public abstract IUpgradeInventory getUpgrades(); diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelLinkBridge.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelLinkBridge.java index 7dd6ad0..4822737 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelLinkBridge.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicChannelLinkBridge.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.bridge; +package com.extendedae_plus.api.bridge; /** * 旧名兼容:已迁移到非 mixin 包,避免 Mixin 处理器禁止直接引用。 diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicTickerMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicTickerMixin.java index a2063d5..88bea12 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicTickerMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/InterfaceLogicTickerMixin.java @@ -1,8 +1,7 @@ package com.extendedae_plus.mixin.ae2.helpers; import appeng.helpers.InterfaceLogic; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; -import com.extendedae_plus.util.ExtendedAELogger; +import com.extendedae_plus.api.bridge.IInterfaceWirelessLinkBridge; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -29,7 +28,7 @@ public abstract class InterfaceLogicTickerMixin { return; } - if (this$0 instanceof InterfaceWirelessLinkBridge bridge) { + if (this$0 instanceof IInterfaceWirelessLinkBridge bridge) { // 处理延迟初始化 bridge.eap$handleDelayedInit(); } @@ -38,7 +37,7 @@ public abstract class InterfaceLogicTickerMixin { @Inject(method = "tickingRequest", at = @At("TAIL"), remap = false) private void eap$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall, CallbackInfoReturnable cir) { - if (this$0 instanceof InterfaceWirelessLinkBridge bridge) { + if (this$0 instanceof IInterfaceWirelessLinkBridge bridge) { bridge.eap$updateWirelessLink(); } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicAdvancedMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicAdvancedMixin.java index 31b4654..bcaa70b 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicAdvancedMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicAdvancedMixin.java @@ -6,7 +6,7 @@ import appeng.api.stacks.AEKey; import appeng.api.stacks.GenericStack; import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderTarget; -import com.extendedae_plus.api.AdvancedBlockingHolder; +import com.extendedae_plus.api.IAdvancedBlocking; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; @@ -20,7 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Collections; @Mixin(value = PatternProviderLogic.class, remap = false) -public class PatternProviderLogicAdvancedMixin implements AdvancedBlockingHolder { +public class PatternProviderLogicAdvancedMixin implements IAdvancedBlocking { @Unique private static final String EAP_ADV_BLOCKING_KEY = "eap_advanced_blocking"; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicDoublingMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicDoublingMixin.java index 13806f2..d78a7eb 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicDoublingMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/PatternProviderLogicDoublingMixin.java @@ -3,9 +3,9 @@ package com.extendedae_plus.mixin.ae2.helpers; import appeng.api.crafting.IPatternDetails; import appeng.crafting.pattern.AEProcessingPattern; import appeng.helpers.patternprovider.PatternProviderLogic; -import com.extendedae_plus.api.SmartDoublingAwarePattern; -import com.extendedae_plus.api.SmartDoublingHolder; -import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicPatternsAccessor; +import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern; +import com.extendedae_plus.api.smartDoubling.ISmartDoublingHolder; +import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicAccessor; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; @@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(value = PatternProviderLogic.class, remap = false) -public class PatternProviderLogicDoublingMixin implements SmartDoublingHolder { +public class PatternProviderLogicDoublingMixin implements ISmartDoublingHolder { @Unique private static final String EAP_SMART_DOUBLING_KEY = "eap_smart_doubling"; @@ -33,9 +33,9 @@ public class PatternProviderLogicDoublingMixin implements SmartDoublingHolder { this.eap$smartDoubling = value; // 立即将开关状态应用到当前 Provider 的样板上,避免等待下一次 updatePatterns try { - var list = ((PatternProviderLogicPatternsAccessor) this).eap$patterns(); + var list = ((PatternProviderLogicAccessor) this).eap$patterns(); for (IPatternDetails details : list) { - if (details instanceof AEProcessingPattern proc && proc instanceof SmartDoublingAwarePattern aware) { + if (details instanceof AEProcessingPattern proc && proc instanceof ISmartDoublingAwarePattern aware) { aware.eap$setAllowScaling(value); } } @@ -60,10 +60,10 @@ public class PatternProviderLogicDoublingMixin implements SmartDoublingHolder { @Inject(method = "updatePatterns", at = @At("TAIL")) private void eap$applySmartDoublingToPatterns(CallbackInfo ci) { try { - var list = ((PatternProviderLogicPatternsAccessor) this).eap$patterns(); + var list = ((PatternProviderLogicAccessor) this).eap$patterns(); boolean allow = this.eap$smartDoubling; for (IPatternDetails details : list) { - if (details instanceof AEProcessingPattern proc && proc instanceof SmartDoublingAwarePattern aware) { + if (details instanceof AEProcessingPattern proc && proc instanceof ISmartDoublingAwarePattern aware) { aware.eap$setAllowScaling(allow); } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicTickerMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicTickerMixin.java index e799173..27ecb7f 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicTickerMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/helpers/patternprovider/PatternProviderLogicTickerMixin.java @@ -1,7 +1,7 @@ package com.extendedae_plus.mixin.ae2.helpers.patternprovider; import appeng.helpers.patternprovider.PatternProviderLogic; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; +import com.extendedae_plus.api.bridge.IInterfaceWirelessLinkBridge; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -27,7 +27,7 @@ public abstract class PatternProviderLogicTickerMixin { if (node != null && node.getLevel() != null && node.getLevel().isClientSide) { return; } - if (this$0 instanceof InterfaceWirelessLinkBridge bridge) { + if (this$0 instanceof IInterfaceWirelessLinkBridge bridge) { bridge.eap$handleDelayedInit(); } } @@ -35,7 +35,7 @@ public abstract class PatternProviderLogicTickerMixin { @Inject(method = "tickingRequest", at = @At("TAIL")) private void eap$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall, CallbackInfoReturnable cir) { - if (this$0 instanceof InterfaceWirelessLinkBridge bridge) { + if (this$0 instanceof IInterfaceWirelessLinkBridge bridge) { bridge.eap$updateWirelessLink(); } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/items/MemoryCardItemMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/items/MemoryCardItemMixin.java new file mode 100644 index 0000000..7add032 --- /dev/null +++ b/src/main/java/com/extendedae_plus/mixin/ae2/items/MemoryCardItemMixin.java @@ -0,0 +1,223 @@ +package com.extendedae_plus.mixin.ae2.items; + +import appeng.api.inventories.InternalInventory; +import appeng.api.upgrades.IUpgradeableObject; +import appeng.core.localization.PlayerMessages; +import appeng.items.tools.MemoryCardItem; +import appeng.items.tools.NetworkToolItem; +import appeng.util.inv.PlayerInternalInventory; +import com.extendedae_plus.ae.parts.EntitySpeedTickerPart; +import com.extendedae_plus.init.ModItems; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.ArrayList; + +@Mixin(value = MemoryCardItem.class, remap = false) +public class MemoryCardItemMixin { + + /** + * 写入 Memory Card 时保留实体加速卡的完整 NBT 数据 + */ + @Inject(method = "storeUpgrades", at = @At("HEAD"), cancellable = true) + private static void storeUpgradesCustom(IUpgradeableObject upgradeableObject, CompoundTag output, CallbackInfo ci) { + try { + CompoundTag desiredUpgradesTag = new CompoundTag(); + ListTag entitySpeedCards = new ListTag(); + InternalInventory upgrades = upgradeableObject.getUpgrades(); + + for (int i = 0; i < upgrades.size(); i++) { + ItemStack upgradeStack = upgrades.getStackInSlot(i); + if (upgradeStack.isEmpty()) continue; + + ResourceLocation itemId = BuiltInRegistries.ITEM.getKey(upgradeStack.getItem()); + String key = itemId.toString(); + + if (upgradeStack.getItem().equals(ModItems.ENTITY_SPEED_CARD.get())) { + CompoundTag stackTag = new CompoundTag(); + stackTag.putInt("Slot", i); + upgradeStack.save(stackTag); + entitySpeedCards.add(stackTag); + } else { + desiredUpgradesTag.putInt(key, desiredUpgradesTag.getInt(key) + upgradeStack.getCount()); + } + } + + if (!entitySpeedCards.isEmpty()) { + desiredUpgradesTag.put("entity_speed_cards", entitySpeedCards); + } + + output.put("upgrades", desiredUpgradesTag); + ci.cancel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 从 Memory Card 恢复升级时,从玩家背包或网络工具提取实体加速卡 + */ + @Inject(method = "restoreUpgrades", at = @At("HEAD"), cancellable = true) + private static void restoreUpgradesCustom(Player player, CompoundTag input, IUpgradeableObject upgradeableObject, CallbackInfoReturnable cir) { + try { + if (!input.contains("upgrades")) { + cir.setReturnValue(false); + return; + } + + CompoundTag desiredUpgradesTag = input.getCompound("upgrades"); + InternalInventory upgrades = upgradeableObject.getUpgrades(); + + // 收集背包和网络工具作为升级卡来源 + var upgradeSources = new ArrayList(); + upgradeSources.add(new PlayerInternalInventory(player.getInventory())); + var networkTool = NetworkToolItem.findNetworkToolInv(player); + if (networkTool != null) { + upgradeSources.add(networkTool.getInventory()); + } + + // 清空所有槽位中的 EntitySpeedCardItem + for (int i = 0; i < upgrades.size(); i++) { + ItemStack stack = upgrades.getStackInSlot(i); + if (!stack.isEmpty() && stack.getItem().equals(ModItems.ENTITY_SPEED_CARD.get())) { + ItemStack removed = upgrades.extractItem(i, stack.getCount(), false); + for (var source : upgradeSources) { + if (!removed.isEmpty()) { + removed = source.addItems(removed); + } + } + if (!removed.isEmpty()) { + player.drop(removed, false); + } + } + } + + // 恢复 EntitySpeedCardItem + if (desiredUpgradesTag.contains("entity_speed_cards", Tag.TAG_LIST)) { + ListTag entitySpeedCards = desiredUpgradesTag.getList("entity_speed_cards", Tag.TAG_COMPOUND); + for (int i = 0; i < entitySpeedCards.size(); i++) { + CompoundTag stackTag = entitySpeedCards.getCompound(i); + ItemStack desiredStack = ItemStack.of(stackTag); + int slot = stackTag.contains("Slot") ? stackTag.getInt("Slot") : i; + + if (player.getAbilities().instabuild) { + // 创造模式:直接生成 + if (slot >= 0 && slot < upgrades.size()) { + upgrades.setItemDirect(slot, desiredStack); + } else { + upgrades.addItems(desiredStack); + } + } else { + // 非创造模式:从背包或网络工具提取 + int missingAmount = desiredStack.getCount(); + ItemStack extracted = ItemStack.EMPTY; + + for (var source : upgradeSources) { + ItemStack potential = new ItemStack(desiredStack.getItem(), missingAmount); + if (desiredStack.hasTag()) { + potential.setTag(desiredStack.getTag().copy()); + } + ItemStack cards = source.removeItems(missingAmount, potential, null); + if (!cards.isEmpty()) { + ItemStack overflow = upgrades.addItems(cards); + if (!overflow.isEmpty()) { + player.getInventory().placeItemBackInInventory(overflow); + } + missingAmount -= cards.getCount(); + extracted = cards; + } + if (missingAmount <= 0) break; + } + + if (missingAmount > 0 && !player.level().isClientSide()) { + player.displayClientMessage( + PlayerMessages.MissingUpgrades.text(desiredStack.getItem().getDescription(), missingAmount), + true + ); + } else if (!extracted.isEmpty()) { + if (slot >= 0 && slot < upgrades.size()) { + upgrades.setItemDirect(slot, extracted); + } else { + upgrades.addItems(extracted); + } + } + } + } + } + + // 恢复其他升级卡(按 AE2 原逻辑) + for (String key : desiredUpgradesTag.getAllKeys()) { + ResourceLocation id; + try { + id = new ResourceLocation(key); + } catch (Exception ex) { + continue; + } + + var item = BuiltInRegistries.ITEM.getOptional(id).orElse(null); + if (item == null || item.equals(ModItems.ENTITY_SPEED_CARD.get())) continue; + + int desiredCount = desiredUpgradesTag.getInt(key); + if (desiredCount > 0) { + if (player.getAbilities().instabuild) { + // 创造模式:直接生成 + ItemStack stack = new ItemStack(item, desiredCount); + upgrades.addItems(stack); + } else { + // 非创造模式:从背包或网络工具提取 + int missingAmount = desiredCount; + ItemStack potential = new ItemStack(item, missingAmount); + ItemStack overflow = upgrades.addItems(potential, true); + if (!overflow.isEmpty()) { + missingAmount -= overflow.getCount(); + } + + for (var source : upgradeSources) { + ItemStack cards = source.removeItems(missingAmount, potential, null); + if (!cards.isEmpty()) { + overflow = upgrades.addItems(cards); + if (!overflow.isEmpty()) { + player.getInventory().placeItemBackInInventory(overflow); + } + missingAmount -= cards.getCount(); + } + if (missingAmount <= 0) break; + } + + if (missingAmount > 0 && !player.level().isClientSide()) { + player.displayClientMessage( + PlayerMessages.MissingUpgrades.text(item.getDescription(), missingAmount), + true + ); + } + } + } + } + + // 标记保存并通知升级变化 + if (upgradeableObject instanceof EntitySpeedTickerPart speedTickerPart) { + BlockEntity be = speedTickerPart.getBlockEntity(); + if (be != null) { + be.setChanged(); + } + speedTickerPart.upgradesChanged(); + } + + cir.setReturnValue(true); + } catch (Exception e) { + e.printStackTrace(); + cir.setReturnValue(false); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/items/QuartzCuttingKnifeItemMixin.java similarity index 99% rename from src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java rename to src/main/java/com/extendedae_plus/mixin/ae2/items/QuartzCuttingKnifeItemMixin.java index 420a3e6..6fbae65 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/QuartzCuttingKnifeItemMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/items/QuartzCuttingKnifeItemMixin.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.mixin.ae2; +package com.extendedae_plus.mixin.ae2.items; import appeng.api.parts.IPartHost; import appeng.api.parts.SelectedPart; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java index 28174ac..c9e1271 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuAdvancedMixin.java @@ -5,8 +5,8 @@ import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.menu.AEBaseMenu; import appeng.menu.guisync.GuiSync; import appeng.menu.implementations.PatternProviderMenu; -import com.extendedae_plus.api.AdvancedBlockingHolder; -import com.extendedae_plus.api.PatternProviderMenuAdvancedSync; +import com.extendedae_plus.api.IAdvancedBlocking; +import com.extendedae_plus.api.IPatternProviderMenuAdvancedSync; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; import org.spongepowered.asm.mixin.Final; @@ -20,7 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import static com.extendedae_plus.util.ExtendedAELogger.LOGGER; @Mixin(PatternProviderMenu.class) -public abstract class PatternProviderMenuAdvancedMixin implements PatternProviderMenuAdvancedSync { +public abstract class PatternProviderMenuAdvancedMixin implements IPatternProviderMenuAdvancedSync { @Final @Shadow(remap = false) protected PatternProviderLogic logic; @@ -35,7 +35,7 @@ public abstract class PatternProviderMenuAdvancedMixin implements PatternProvide // 避免@Shadow父类方法,改用公共API:AEBaseMenu#isClientSide() if (!((AEBaseMenu) (Object) this).isClientSide()) { var l = this.logic; - if (l instanceof AdvancedBlockingHolder holder) { + if (l instanceof IAdvancedBlocking holder) { this.eap$AdvancedBlocking = holder.eap$getAdvancedBlocking(); } } @@ -46,7 +46,7 @@ public abstract class PatternProviderMenuAdvancedMixin implements PatternProvide private void eap$initAdvancedSync_Public(int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) { try { var l = this.logic; - if (l instanceof AdvancedBlockingHolder holder) { + if (l instanceof IAdvancedBlocking holder) { this.eap$AdvancedBlocking = holder.eap$getAdvancedBlocking(); } } catch (Throwable ignored) {} @@ -57,7 +57,7 @@ public abstract class PatternProviderMenuAdvancedMixin implements PatternProvide private void eap$initAdvancedSync_Protected(MenuType menuType, int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) { try { var l = this.logic; - if (l instanceof AdvancedBlockingHolder holder) { + if (l instanceof IAdvancedBlocking holder) { this.eap$AdvancedBlocking = holder.eap$getAdvancedBlocking(); } } catch (Throwable t) { diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuDoublingMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuDoublingMixin.java index 3403b9d..c173633 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuDoublingMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuDoublingMixin.java @@ -5,8 +5,8 @@ import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.menu.AEBaseMenu; import appeng.menu.guisync.GuiSync; import appeng.menu.implementations.PatternProviderMenu; -import com.extendedae_plus.api.PatternProviderMenuDoublingSync; -import com.extendedae_plus.api.SmartDoublingHolder; +import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync; +import com.extendedae_plus.api.smartDoubling.ISmartDoublingHolder; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; import org.spongepowered.asm.mixin.Final; @@ -20,7 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import static com.extendedae_plus.util.ExtendedAELogger.LOGGER; @Mixin(PatternProviderMenu.class) -public abstract class PatternProviderMenuDoublingMixin implements PatternProviderMenuDoublingSync { +public abstract class PatternProviderMenuDoublingMixin implements IPatternProviderMenuDoublingSync { @Final @Shadow(remap = false) protected PatternProviderLogic logic; @@ -33,7 +33,7 @@ public abstract class PatternProviderMenuDoublingMixin implements PatternProvide private void eap$syncSmartDoubling(CallbackInfo ci) { if (!((AEBaseMenu) (Object) this).isClientSide()) { var l = this.logic; - if (l instanceof SmartDoublingHolder holder) { + if (l instanceof ISmartDoublingHolder holder) { this.eap$SmartDoubling = holder.eap$getSmartDoubling(); } } @@ -43,7 +43,7 @@ public abstract class PatternProviderMenuDoublingMixin implements PatternProvide private void eap$initSmartSync_Public(int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) { try { var l = this.logic; - if (l instanceof SmartDoublingHolder holder) { + if (l instanceof ISmartDoublingHolder holder) { this.eap$SmartDoubling = holder.eap$getSmartDoubling(); } } catch (Throwable t) { @@ -55,7 +55,7 @@ public abstract class PatternProviderMenuDoublingMixin implements PatternProvide private void eap$initSmartSync_Protected(MenuType menuType, int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) { try { var l = this.logic; - if (l instanceof SmartDoublingHolder holder) { + if (l instanceof ISmartDoublingHolder holder) { this.eap$SmartDoubling = holder.eap$getSmartDoubling(); } } catch (Throwable t) { diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuUpgradesMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuUpgradesMixin.java index c5ed6d7..01ef29c 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuUpgradesMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/menu/PatternProviderMenuUpgradesMixin.java @@ -7,7 +7,7 @@ import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.menu.AEBaseMenu; import appeng.menu.ToolboxMenu; import appeng.menu.implementations.PatternProviderMenu; -import com.extendedae_plus.bridge.IUpgradableMenu; +import com.extendedae_plus.api.bridge.IUpgradableMenu; import com.extendedae_plus.compat.UpgradeSlotCompat; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/parts/AEBasePartClientSyncMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/parts/AEBasePartClientSyncMixin.java index b180e30..10b957b 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/parts/AEBasePartClientSyncMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/parts/AEBasePartClientSyncMixin.java @@ -1,7 +1,7 @@ package com.extendedae_plus.mixin.ae2.parts; import appeng.parts.AEBasePart; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; +import com.extendedae_plus.api.bridge.IInterfaceWirelessLinkBridge; import net.minecraft.network.FriendlyByteBuf; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -18,8 +18,8 @@ public class AEBasePartClientSyncMixin { @Inject(method = "writeToStream", at = @At("TAIL")) private void eap$writeWirelessState(FriendlyByteBuf data, CallbackInfo ci) { // 检查是否实现了无线链接桥接接口 - if (this instanceof InterfaceWirelessLinkBridge) { - InterfaceWirelessLinkBridge bridge = (InterfaceWirelessLinkBridge) this; + if (this instanceof IInterfaceWirelessLinkBridge) { + IInterfaceWirelessLinkBridge bridge = (IInterfaceWirelessLinkBridge) this; // 同步无线连接状态到客户端 boolean connected = false; try { @@ -44,8 +44,8 @@ public class AEBasePartClientSyncMixin { boolean connected = data.readBoolean(); // 检查是否实现了无线链接桥接接口 - if (this instanceof InterfaceWirelessLinkBridge) { - InterfaceWirelessLinkBridge bridge = (InterfaceWirelessLinkBridge) this; + if (this instanceof IInterfaceWirelessLinkBridge) { + IInterfaceWirelessLinkBridge bridge = (IInterfaceWirelessLinkBridge) this; try { // 更新客户端状态 bridge.eap$setClientWirelessState(connected); diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java index b00c3e1..eee7501 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartChannelCardMixin.java @@ -3,16 +3,14 @@ package com.extendedae_plus.mixin.ae2.parts.automation; import appeng.api.networking.security.IActionHost; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; -import appeng.helpers.InterfaceLogicHost; import appeng.parts.automation.IOBusPart; -import net.minecraft.nbt.CompoundTag; -import com.extendedae_plus.util.ExtendedAELogger; import com.extendedae_plus.ae.items.ChannelCardItem; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; +import com.extendedae_plus.ae.wireless.WirelessSlaveLink; +import com.extendedae_plus.ae.wireless.endpoint.GenericNodeEndpointImpl; +import com.extendedae_plus.api.bridge.IInterfaceWirelessLinkBridge; import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.wireless.WirelessSlaveLink; -import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl; -import net.minecraft.network.FriendlyByteBuf; +import com.extendedae_plus.util.ExtendedAELogger; +import net.minecraft.nbt.CompoundTag; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -23,7 +21,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; * 给 AE2 的 I/O 总线注入频道卡联动:在升级变更时读取频道并更新无线链接。 */ @Mixin(value = IOBusPart.class, remap = false) -public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLinkBridge, IUpgradeableObject { +public abstract class IOBusPartChannelCardMixin implements IInterfaceWirelessLinkBridge, IUpgradeableObject { @Unique private WirelessSlaveLink eap$link; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartTickerChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartTickerChannelCardMixin.java index d9ac8ba..a964e14 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartTickerChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/parts/automation/IOBusPartTickerChannelCardMixin.java @@ -3,7 +3,7 @@ package com.extendedae_plus.mixin.ae2.parts.automation; import appeng.api.networking.IGridNode; import appeng.api.networking.ticking.TickRateModulation; import appeng.parts.automation.IOBusPart; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; +import com.extendedae_plus.api.bridge.IInterfaceWirelessLinkBridge; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -17,7 +17,7 @@ public abstract class IOBusPartTickerChannelCardMixin { @Inject(method = "tickingRequest", at = @At("TAIL")) private void eap$tickTail(IGridNode node, int ticksSinceLastCall, CallbackInfoReturnable cir) { - if (this instanceof InterfaceWirelessLinkBridge bridge) { + if (this instanceof IInterfaceWirelessLinkBridge bridge) { bridge.eap$updateWirelessLink(); } } diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java index 50e4a71..d54d757 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartChannelCardMixin.java @@ -5,14 +5,13 @@ import appeng.api.networking.security.IActionHost; import appeng.api.upgrades.IUpgradeInventory; import appeng.api.upgrades.IUpgradeableObject; import appeng.parts.storagebus.StorageBusPart; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.FriendlyByteBuf; -import com.extendedae_plus.util.ExtendedAELogger; import com.extendedae_plus.ae.items.ChannelCardItem; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; +import com.extendedae_plus.ae.wireless.WirelessSlaveLink; +import com.extendedae_plus.ae.wireless.endpoint.GenericNodeEndpointImpl; +import com.extendedae_plus.api.bridge.IInterfaceWirelessLinkBridge; import com.extendedae_plus.init.ModItems; -import com.extendedae_plus.wireless.WirelessSlaveLink; -import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl; +import com.extendedae_plus.util.ExtendedAELogger; +import net.minecraft.nbt.CompoundTag; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -23,7 +22,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; * 给 AE2 的存储总线注入频道卡联动:在升级变更时读取频道并更新无线链接。 */ @Mixin(value = StorageBusPart.class, remap = false) -public abstract class StorageBusPartChannelCardMixin implements InterfaceWirelessLinkBridge, IUpgradeableObject { +public abstract class StorageBusPartChannelCardMixin implements IInterfaceWirelessLinkBridge, IUpgradeableObject { @Unique private WirelessSlaveLink eap$link; diff --git a/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartTickerChannelCardMixin.java b/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartTickerChannelCardMixin.java index 202bc80..2227e45 100644 --- a/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartTickerChannelCardMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/ae2/parts/storagebus/StorageBusPartTickerChannelCardMixin.java @@ -3,7 +3,7 @@ package com.extendedae_plus.mixin.ae2.parts.storagebus; import appeng.api.networking.IGridNode; import appeng.api.networking.ticking.TickRateModulation; import appeng.parts.storagebus.StorageBusPart; -import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge; +import com.extendedae_plus.api.bridge.IInterfaceWirelessLinkBridge; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -17,7 +17,7 @@ public abstract class StorageBusPartTickerChannelCardMixin { @Inject(method = "tickingRequest", at = @At("TAIL")) private void eap$tickTail(IGridNode node, int ticksSinceLastCall, CallbackInfoReturnable cir) { - if (this instanceof InterfaceWirelessLinkBridge bridge) { + if (this instanceof IInterfaceWirelessLinkBridge bridge) { bridge.eap$updateWirelessLink(); } } diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java index 4009b1b..9afe3be 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternProviderMixin.java @@ -4,8 +4,9 @@ import appeng.client.gui.Icon; import appeng.client.gui.implementations.PatternProviderScreen; import appeng.client.gui.style.ScreenStyle; import appeng.menu.SlotSemantics; -import com.extendedae_plus.NewIcon; -import com.extendedae_plus.api.ExPatternButtonsAccessor; +import com.extendedae_plus.ae.client.gui.NewIcon; +import com.extendedae_plus.api.IExPatternButtonsAccessor; +import com.extendedae_plus.api.IExPatternPageAccessor; import com.extendedae_plus.config.ModConfig; import com.glodblock.github.extendedae.client.button.ActionEPPButton; import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider; @@ -26,7 +27,7 @@ import java.lang.reflect.Method; import static com.extendedae_plus.util.ExtendedAELogger.LOGGER; @Mixin(GuiExPatternProvider.class) -public abstract class GuiExPatternProviderMixin extends PatternProviderScreen implements ExPatternButtonsAccessor, com.extendedae_plus.api.ExPatternPageAccessor { +public abstract class GuiExPatternProviderMixin extends PatternProviderScreen implements IExPatternButtonsAccessor, IExPatternPageAccessor { @Unique ScreenStyle eap$screenStyle; diff --git a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternTerminalMixin.java b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternTerminalMixin.java index 143aef9..af13e76 100644 --- a/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternTerminalMixin.java +++ b/src/main/java/com/extendedae_plus/mixin/extendedae/client/gui/GuiExPatternTerminalMixin.java @@ -11,7 +11,7 @@ import appeng.menu.AEBaseMenu; import com.extendedae_plus.config.ModConfig; import com.extendedae_plus.init.ModNetwork; import com.extendedae_plus.mixin.extendedae.accessor.GuiExPatternTerminalAccessor; -import com.extendedae_plus.network.OpenProviderUiC2SPacket; +import com.extendedae_plus.network.provider.OpenProviderUiC2SPacket; import com.extendedae_plus.util.GuiUtil; import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal; import net.minecraft.client.Minecraft; diff --git a/src/main/java/com/extendedae_plus/network/CraftingMonitorJumpC2SPacket.java b/src/main/java/com/extendedae_plus/network/crafting/CraftingMonitorJumpC2SPacket.java similarity index 97% rename from src/main/java/com/extendedae_plus/network/CraftingMonitorJumpC2SPacket.java rename to src/main/java/com/extendedae_plus/network/crafting/CraftingMonitorJumpC2SPacket.java index 3a547aa..b3206d2 100644 --- a/src/main/java/com/extendedae_plus/network/CraftingMonitorJumpC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/crafting/CraftingMonitorJumpC2SPacket.java @@ -1,8 +1,7 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.crafting; import appeng.api.crafting.IPatternDetails; import appeng.api.networking.IGrid; -import appeng.api.networking.crafting.ICraftingProvider; import appeng.api.networking.security.IActionHost; import appeng.api.stacks.AEKey; import appeng.helpers.patternprovider.PatternProviderLogic; @@ -18,7 +17,6 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.MenuProvider; -import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraftforge.network.NetworkEvent; diff --git a/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java b/src/main/java/com/extendedae_plus/network/crafting/CraftingMonitorOpenProviderC2SPacket.java similarity index 97% rename from src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java rename to src/main/java/com/extendedae_plus/network/crafting/CraftingMonitorOpenProviderC2SPacket.java index 91ddfa0..c962b77 100644 --- a/src/main/java/com/extendedae_plus/network/CraftingMonitorOpenProviderC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/crafting/CraftingMonitorOpenProviderC2SPacket.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.crafting; import appeng.api.crafting.IPatternDetails; import appeng.api.networking.IGrid; @@ -13,6 +13,8 @@ import appeng.menu.me.crafting.CraftingCPUMenu; import appeng.parts.AEBasePart; import com.extendedae_plus.init.ModNetwork; import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicAccessor; +import com.extendedae_plus.network.SetPatternHighlightS2CPacket; +import com.extendedae_plus.network.provider.SetProviderPageS2CPacket; import com.extendedae_plus.util.PatternProviderDataUtil; import com.glodblock.github.extendedae.util.FCClientUtil; import com.glodblock.github.glodium.util.GlodUtil; diff --git a/src/main/java/com/extendedae_plus/network/OpenCraftFromJeiC2SPacket.java b/src/main/java/com/extendedae_plus/network/crafting/OpenCraftFromJeiC2SPacket.java similarity index 98% rename from src/main/java/com/extendedae_plus/network/OpenCraftFromJeiC2SPacket.java rename to src/main/java/com/extendedae_plus/network/crafting/OpenCraftFromJeiC2SPacket.java index 5a9a33d..ac4f48e 100644 --- a/src/main/java/com/extendedae_plus/network/OpenCraftFromJeiC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/crafting/OpenCraftFromJeiC2SPacket.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.crafting; import appeng.api.networking.IGrid; import appeng.api.stacks.AEKey; diff --git a/src/main/java/com/extendedae_plus/network/InterfaceAdjustConfigAmountC2SPacket.java b/src/main/java/com/extendedae_plus/network/meInterface/InterfaceAdjustConfigAmountC2SPacket.java similarity index 98% rename from src/main/java/com/extendedae_plus/network/InterfaceAdjustConfigAmountC2SPacket.java rename to src/main/java/com/extendedae_plus/network/meInterface/InterfaceAdjustConfigAmountC2SPacket.java index 8d899ed..f563ebb 100644 --- a/src/main/java/com/extendedae_plus/network/InterfaceAdjustConfigAmountC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/meInterface/InterfaceAdjustConfigAmountC2SPacket.java @@ -1,8 +1,7 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.meInterface; -import appeng.menu.implementations.InterfaceMenu; -import appeng.menu.SlotSemantics; import appeng.api.stacks.GenericStack; +import appeng.menu.implementations.InterfaceMenu; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.network.NetworkEvent; diff --git a/src/main/java/com/extendedae_plus/network/AdvancedBlockingSyncS2CPacket.java b/src/main/java/com/extendedae_plus/network/provider/AdvancedBlockingSyncS2CPacket.java similarity index 96% rename from src/main/java/com/extendedae_plus/network/AdvancedBlockingSyncS2CPacket.java rename to src/main/java/com/extendedae_plus/network/provider/AdvancedBlockingSyncS2CPacket.java index 357d0f3..eccbd30 100644 --- a/src/main/java/com/extendedae_plus/network/AdvancedBlockingSyncS2CPacket.java +++ b/src/main/java/com/extendedae_plus/network/provider/AdvancedBlockingSyncS2CPacket.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.provider; import com.extendedae_plus.client.ClientAdvancedBlockingState; import net.minecraft.network.FriendlyByteBuf; diff --git a/src/main/java/com/extendedae_plus/network/GlobalToggleProviderModesC2SPacket.java b/src/main/java/com/extendedae_plus/network/provider/GlobalToggleProviderModesC2SPacket.java similarity index 95% rename from src/main/java/com/extendedae_plus/network/GlobalToggleProviderModesC2SPacket.java rename to src/main/java/com/extendedae_plus/network/provider/GlobalToggleProviderModesC2SPacket.java index c37d0bc..a07dc5d 100644 --- a/src/main/java/com/extendedae_plus/network/GlobalToggleProviderModesC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/provider/GlobalToggleProviderModesC2SPacket.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.provider; import appeng.api.config.Settings; import appeng.api.config.YesNo; @@ -7,8 +7,8 @@ import appeng.blockentity.crafting.PatternProviderBlockEntity; import appeng.helpers.patternprovider.PatternProviderLogic; import appeng.helpers.patternprovider.PatternProviderLogicHost; import appeng.parts.crafting.PatternProviderPart; -import com.extendedae_plus.api.AdvancedBlockingHolder; -import com.extendedae_plus.api.SmartDoublingHolder; +import com.extendedae_plus.api.IAdvancedBlocking; +import com.extendedae_plus.api.smartDoubling.ISmartDoublingHolder; import com.extendedae_plus.content.controller.NetworkPatternControllerBlockEntity; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; @@ -16,15 +16,15 @@ import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.network.NetworkEvent; -import java.util.Set; import java.util.HashSet; +import java.util.Set; import java.util.function.Supplier; /** * C2S:全网批量切换样板供应器的三种模式: * - 阻挡模式(AE2 内置 BLOCKING_MODE 设置) - * - 高级阻挡模式(AdvancedBlockingHolder mixin) - * - 智能翻倍模式(SmartDoublingHolder mixin) + * - 高级阻挡模式(IAdvancedBlocking mixin) + * - 智能翻倍模式(ISmartDoublingHolder mixin) * * 负载为三个操作码(各1字节),分别对应:blocking、advancedBlocking、smartDoubling。 */ @@ -173,14 +173,14 @@ public class GlobalToggleProviderModesC2SPacket { } } // 2) 高级阻挡(mixin 接口) - if (msg.opAdvancedBlocking != Op.NOOP && logic instanceof AdvancedBlockingHolder adv) { + if (msg.opAdvancedBlocking != Op.NOOP && logic instanceof IAdvancedBlocking adv) { boolean current = adv.eap$getAdvancedBlocking(); boolean target = computeTarget(current, msg.opAdvancedBlocking); adv.eap$setAdvancedBlocking(target); changed = changed || (current != target); } // 3) 智能翻倍(mixin 接口) - if (msg.opSmartDoubling != Op.NOOP && logic instanceof SmartDoublingHolder sd) { + if (msg.opSmartDoubling != Op.NOOP && logic instanceof ISmartDoublingHolder sd) { boolean current = sd.eap$getSmartDoubling(); boolean target = computeTarget(current, msg.opSmartDoubling); sd.eap$setSmartDoubling(target); diff --git a/src/main/java/com/extendedae_plus/network/OpenProviderUiC2SPacket.java b/src/main/java/com/extendedae_plus/network/provider/OpenProviderUiC2SPacket.java similarity index 99% rename from src/main/java/com/extendedae_plus/network/OpenProviderUiC2SPacket.java rename to src/main/java/com/extendedae_plus/network/provider/OpenProviderUiC2SPacket.java index 8a02170..098c095 100644 --- a/src/main/java/com/extendedae_plus/network/OpenProviderUiC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/provider/OpenProviderUiC2SPacket.java @@ -1,20 +1,20 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.provider; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.core.registries.Registries; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.core.Direction; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.InteractionResult; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; import net.minecraft.world.MenuProvider; -import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.NetworkHooks; diff --git a/src/main/java/com/extendedae_plus/network/ProvidersListS2CPacket.java b/src/main/java/com/extendedae_plus/network/provider/ProvidersListS2CPacket.java similarity index 97% rename from src/main/java/com/extendedae_plus/network/ProvidersListS2CPacket.java rename to src/main/java/com/extendedae_plus/network/provider/ProvidersListS2CPacket.java index 87d3227..02689dc 100644 --- a/src/main/java/com/extendedae_plus/network/ProvidersListS2CPacket.java +++ b/src/main/java/com/extendedae_plus/network/provider/ProvidersListS2CPacket.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.provider; import com.extendedae_plus.client.ui.ProviderSelectScreen; import net.minecraft.client.Minecraft; diff --git a/src/main/java/com/extendedae_plus/network/RequestProvidersListC2SPacket.java b/src/main/java/com/extendedae_plus/network/provider/RequestProvidersListC2SPacket.java similarity index 98% rename from src/main/java/com/extendedae_plus/network/RequestProvidersListC2SPacket.java rename to src/main/java/com/extendedae_plus/network/provider/RequestProvidersListC2SPacket.java index d9a0cc3..919ba09 100644 --- a/src/main/java/com/extendedae_plus/network/RequestProvidersListC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/provider/RequestProvidersListC2SPacket.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.provider; import appeng.helpers.patternprovider.PatternContainer; import appeng.menu.implementations.PatternAccessTermMenu; diff --git a/src/main/java/com/extendedae_plus/network/SetProviderPageS2CPacket.java b/src/main/java/com/extendedae_plus/network/provider/SetProviderPageS2CPacket.java similarity index 97% rename from src/main/java/com/extendedae_plus/network/SetProviderPageS2CPacket.java rename to src/main/java/com/extendedae_plus/network/provider/SetProviderPageS2CPacket.java index 1c57644..5bfd936 100644 --- a/src/main/java/com/extendedae_plus/network/SetProviderPageS2CPacket.java +++ b/src/main/java/com/extendedae_plus/network/provider/SetProviderPageS2CPacket.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.provider; import appeng.menu.SlotSemantics; import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider; diff --git a/src/main/java/com/extendedae_plus/network/ToggleAdvancedBlockingC2SPacket.java b/src/main/java/com/extendedae_plus/network/provider/ToggleAdvancedBlockingC2SPacket.java similarity index 89% rename from src/main/java/com/extendedae_plus/network/ToggleAdvancedBlockingC2SPacket.java rename to src/main/java/com/extendedae_plus/network/provider/ToggleAdvancedBlockingC2SPacket.java index 2711206..9162194 100644 --- a/src/main/java/com/extendedae_plus/network/ToggleAdvancedBlockingC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/provider/ToggleAdvancedBlockingC2SPacket.java @@ -1,11 +1,11 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.provider; import appeng.api.config.Settings; import appeng.api.config.YesNo; import appeng.menu.implementations.PatternProviderMenu; -import com.extendedae_plus.api.AdvancedBlockingHolder; +import com.extendedae_plus.api.IAdvancedBlocking; import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor; -import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor; +import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAccessor; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.network.NetworkEvent; @@ -34,9 +34,9 @@ public class ToggleAdvancedBlockingC2SPacket { var containerMenu = player.containerMenu; if (containerMenu instanceof PatternProviderMenu menu) { - var accessor = (PatternProviderMenuAdvancedAccessor) menu; + var accessor = (PatternProviderMenuAccessor) menu; var logic = accessor.eap$logic(); - if (logic instanceof AdvancedBlockingHolder holder) { + if (logic instanceof IAdvancedBlocking holder) { boolean current = holder.eap$getAdvancedBlocking(); boolean next = !current; holder.eap$setAdvancedBlocking(next); @@ -48,7 +48,7 @@ public class ToggleAdvancedBlockingC2SPacket { }else if (containerMenu instanceof AdvPatternProviderMenu menu){ var accessor = (AdvPatternProviderMenuAdvancedAccessor) menu; var logic = accessor.eap$logic(); - if (logic instanceof AdvancedBlockingHolder holder) { + if (logic instanceof IAdvancedBlocking holder) { boolean current = holder.eap$getAdvancedBlocking(); boolean next = !current; holder.eap$setAdvancedBlocking(next); diff --git a/src/main/java/com/extendedae_plus/network/ToggleSmartDoublingC2SPacket.java b/src/main/java/com/extendedae_plus/network/provider/ToggleSmartDoublingC2SPacket.java similarity index 86% rename from src/main/java/com/extendedae_plus/network/ToggleSmartDoublingC2SPacket.java rename to src/main/java/com/extendedae_plus/network/provider/ToggleSmartDoublingC2SPacket.java index 88d832a..2006b5c 100644 --- a/src/main/java/com/extendedae_plus/network/ToggleSmartDoublingC2SPacket.java +++ b/src/main/java/com/extendedae_plus/network/provider/ToggleSmartDoublingC2SPacket.java @@ -1,9 +1,9 @@ -package com.extendedae_plus.network; +package com.extendedae_plus.network.provider; import appeng.menu.implementations.PatternProviderMenu; -import com.extendedae_plus.api.SmartDoublingHolder; +import com.extendedae_plus.api.smartDoubling.ISmartDoublingHolder; import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor; -import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor; +import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAccessor; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.network.NetworkEvent; @@ -31,9 +31,9 @@ public class ToggleSmartDoublingC2SPacket { if (player == null) return; var containerMenu = player.containerMenu; if (containerMenu instanceof PatternProviderMenu menu) { - var accessor = (PatternProviderMenuAdvancedAccessor) menu; + var accessor = (PatternProviderMenuAccessor) menu; var logic = accessor.eap$logic(); - if (logic instanceof SmartDoublingHolder holder) { + if (logic instanceof ISmartDoublingHolder holder) { boolean current = holder.eap$getSmartDoubling(); boolean next = !current; holder.eap$setSmartDoubling(next); @@ -42,7 +42,7 @@ public class ToggleSmartDoublingC2SPacket { }else if (containerMenu instanceof AdvPatternProviderMenu menu){ var accessor = (AdvPatternProviderMenuAdvancedAccessor) menu; var logic = accessor.eap$logic(); - if (logic instanceof SmartDoublingHolder holder) { + if (logic instanceof ISmartDoublingHolder holder) { boolean current = holder.eap$getSmartDoubling(); boolean next = !current; holder.eap$setSmartDoubling(next); diff --git a/src/main/java/com/extendedae_plus/util/ConfigParsingUtils.java b/src/main/java/com/extendedae_plus/util/ConfigParsingUtils.java deleted file mode 100644 index b9377a5..0000000 --- a/src/main/java/com/extendedae_plus/util/ConfigParsingUtils.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.extendedae_plus.util; - -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - -/** - * 配置解析工具类:用于解析黑名单与倍率配置的字符串 - */ -public final class ConfigParsingUtils { - private ConfigParsingUtils() {} - - public static final class MultiplierEntry { - public final Pattern pattern; - public final double multiplier; - - public MultiplierEntry(Pattern pattern, double multiplier) { - this.pattern = pattern; - this.multiplier = multiplier; - } - } - - /** - * 编译用户提供的匹配串。支持简单的 glob 语法('*' 和 '?')以及完整的正则表达式。 - * 规则: - * - 如果字符串包含 ".*" 或其他正则元字符,优先尝试按正则编译(若失败则回退到 glob 转换)。 - * - 否则若包含 '*' 或 '?',将按 glob 语法转换为正则。 - * - 否则按字面量匹配处理。 - */ - public static Pattern compilePattern(String raw) { - if (raw == null) throw new IllegalArgumentException("pattern is null"); - raw = raw.trim(); - if (raw.isEmpty()) throw new IllegalArgumentException("pattern is empty"); - - // If it looks like regex (contains '.*' or regex metachar), try regex first - if (raw.contains(".*") || raw.matches(".*[\\[\\(\\+\\{\\\\].*")) { - try { - return Pattern.compile("^" + raw + "$"); - } catch (PatternSyntaxException ignored) { - // fallback to glob below - } - } - - // If contains glob chars, convert to regex - if (raw.contains("*") || raw.contains("?")) { - StringBuilder sb = new StringBuilder(); - sb.append('^'); - for (char c : raw.toCharArray()) { - switch (c) { - case '*': sb.append(".*"); break; - case '?': sb.append('.'); break; - default: - // escape regex special chars - if (".\\+[]{}()^$|".indexOf(c) >= 0) { - sb.append('\\'); - } - sb.append(c); - } - } - sb.append('$'); - return Pattern.compile(sb.toString()); - } - - // Otherwise treat as a literal (match exact) - return Pattern.compile("^" + Pattern.quote(raw) + "$"); - } - - /** - * Parse multiplier entries like 'modid:block 2x' into MultiplierEntry objects. - * Accepts values with optional trailing 'x' (case-insensitive). - */ - public static MultiplierEntry parseMultiplierEntry(String entry) { - if (entry == null) return null; - String[] parts = entry.trim().split("\\s+"); - if (parts.length < 2) return null; - String key = parts[0]; - String val = parts[1].toLowerCase(); - if (val.endsWith("x")) val = val.substring(0, val.length() - 1); - double m; - try { - m = Double.parseDouble(val); - } catch (NumberFormatException ex) { - return null; - } - try { - Pattern p = compilePattern(key); - return new MultiplierEntry(p, m); - } catch (IllegalArgumentException e) { - return null; - } - } - - public static List compilePatterns(List raw) { - List out = new ArrayList<>(); - if (raw == null) return out; - for (String s : raw) { - if (s == null || s.isBlank()) continue; - try { out.add(compilePattern(s)); } catch (IllegalArgumentException ignored) {} - } - return out; - } - - public static List parseMultiplierList(List raw) { - List out = new ArrayList<>(); - if (raw == null) return out; - for (String s : raw) { - MultiplierEntry me = parseMultiplierEntry(s); - if (me != null) out.add(me); - } - return out; - } - - // ------------------ 全局缓存与接口 ------------------ - private static volatile List cachedBlacklist = null; - private static volatile List cachedMultiplierEntries = null; - private static final Object CACHE_LOCK = new Object(); - - /** - * 获取已解析并缓存的黑名单(线程安全、懒加载)。 - */ - public static List getCachedBlacklist(java.util.List source) { - if (cachedBlacklist == null) { - synchronized (CACHE_LOCK) { - if (cachedBlacklist == null) { - cachedBlacklist = compilePatterns(source); - } - } - } - return java.util.List.copyOf(cachedBlacklist); - } - - /** - * 获取已解析并缓存的倍率列表(线程安全、懒加载)。 - */ - public static List getCachedMultiplierEntries(java.util.List source) { - if (cachedMultiplierEntries == null) { - synchronized (CACHE_LOCK) { - if (cachedMultiplierEntries == null) { - cachedMultiplierEntries = parseMultiplierList(source); - } - } - } - return java.util.List.copyOf(cachedMultiplierEntries); - } - - /** - * 清空缓存,下一次获取时将重新从提供的源解析(或调用方可以重新调用 getter)。 - */ - public static void reload() { - synchronized (CACHE_LOCK) { - cachedBlacklist = null; - cachedMultiplierEntries = null; - } - } -} - - diff --git a/src/main/java/com/extendedae_plus/util/FluxEnergyHelper.java b/src/main/java/com/extendedae_plus/util/FluxEnergyHelper.java new file mode 100644 index 0000000..6e5a57a --- /dev/null +++ b/src/main/java/com/extendedae_plus/util/FluxEnergyHelper.java @@ -0,0 +1,41 @@ +package com.extendedae_plus.util; + +import appeng.api.config.Actionable; +import appeng.api.networking.energy.IEnergyService; +import appeng.api.networking.security.IActionSource; +import appeng.api.storage.MEStorage; +import appeng.api.storage.StorageHelper; +import com.glodblock.github.appflux.common.me.key.FluxKey; +import com.glodblock.github.appflux.common.me.key.type.EnergyType; + +public class FluxEnergyHelper { + /** + * 尝试从 ME 存储提取 FE 能量。 + * @param energyService AE2 能量服务 + * @param storage ME 存储 + * @param feRequired 所需 FE 量 + * @param source 操作来源 + * @return 提取的 FE 量 + */ + public static long extractFE( + IEnergyService energyService, + MEStorage storage, + long feRequired, + IActionSource source + ) { + FluxKey feKey = FluxKey.of(EnergyType.FE); + + // 模拟提取 FE + long feExtracted = StorageHelper.poweredExtraction( + energyService, storage, feKey, feRequired, source, Actionable.SIMULATE + ); + + // 执行实际提取 + if (feExtracted >= feRequired) { + return StorageHelper.poweredExtraction( + energyService, storage, feKey, feRequired, source, Actionable.MODULATE + ); + } + return 0; + } +} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/util/PatternProviderUIHelper.java b/src/main/java/com/extendedae_plus/util/PatternProviderUIHelper.java deleted file mode 100644 index 435a5a9..0000000 --- a/src/main/java/com/extendedae_plus/util/PatternProviderUIHelper.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.extendedae_plus.util; - -import appeng.client.gui.implementations.PatternProviderScreen; -import appeng.helpers.patternprovider.PatternProviderLogic; -import appeng.menu.implementations.PatternProviderMenu; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.Screen; - -/** - * 样板供应器UI辅助工具类 - * 用于在样板供应器界面中获取PatternProviderLogic对象 - */ -public class PatternProviderUIHelper { - - /** - * 获取当前打开的样板供应器的PatternProviderLogic - * - * @return PatternProviderLogic对象,如果当前没有打开样板供应器界面则返回null - */ - public static PatternProviderLogic getCurrentPatternProvider() { - Minecraft mc = Minecraft.getInstance(); - Screen currentScreen = mc.screen; - - if (currentScreen instanceof PatternProviderScreen patternScreen) { - PatternProviderMenu menu = (PatternProviderMenu) patternScreen.getMenu(); - - // 通过反射安全地访问protected字段 - try { - var logicField = PatternProviderMenu.class.getDeclaredField("logic"); - logicField.setAccessible(true); - return (PatternProviderLogic) logicField.get(menu); - } catch (Exception e) { - // 如果反射失败,返回null - return null; - } - } - - return null; - } - - /** - * 检查当前是否打开了样板供应器界面 - * - * @return 如果当前打开的是样板供应器界面则返回true - */ - public static boolean isPatternProviderScreenOpen() { - Minecraft mc = Minecraft.getInstance(); - return mc.screen instanceof PatternProviderScreen; - } - - /** - * 获取当前样板供应器界面的Screen对象 - * - * @return PatternProviderScreen对象,如果当前没有打开样板供应器界面则返回null - */ - public static PatternProviderScreen getCurrentPatternProviderScreen() { - Minecraft mc = Minecraft.getInstance(); - Screen currentScreen = mc.screen; - - if (currentScreen instanceof PatternProviderScreen patternScreen) { - return patternScreen; - } - - return null; - } - - /** - * 在当前样板供应器中执行样板数量倍增 - * - * @param multiplier 倍数(必须大于0) - * @return 缩放操作结果,如果当前没有打开样板供应器界面则返回null - */ - public static PatternProviderDataUtil.PatternScalingResult multiplyCurrentPatternAmounts(double multiplier) { - PatternProviderLogic patternProvider = getCurrentPatternProvider(); - if (patternProvider == null) { - return null; - } - - 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); - } - - /** - * 在当前样板供应器中执行样板数量倍除 - * - * @param divisor 除数(必须大于0) - * @return 缩放操作结果,如果当前没有打开样板供应器界面则返回null - */ - public static PatternProviderDataUtil.PatternScalingResult divideCurrentPatternAmounts(double divisor) { - PatternProviderLogic patternProvider = getCurrentPatternProvider(); - if (patternProvider == null) { - return null; - } - - return PatternProviderDataUtil.dividePatternAmounts(patternProvider, divisor); - } - - /** - * 预览当前样板供应器的缩放效果 - * - * @param scaleFactor 缩放因子 - * @return 预览结果列表,如果当前没有打开样板供应器界面则返回空列表 - */ - public static java.util.List previewCurrentPatternScaling(double scaleFactor) { - PatternProviderLogic patternProvider = getCurrentPatternProvider(); - if (patternProvider == null) { - return new java.util.ArrayList<>(); - } - - return PatternProviderDataUtil.previewPatternScaling(patternProvider, scaleFactor); - } -} diff --git a/src/main/java/com/extendedae_plus/util/PowerUtils.java b/src/main/java/com/extendedae_plus/util/PowerUtils.java deleted file mode 100644 index 93c5001..0000000 --- a/src/main/java/com/extendedae_plus/util/PowerUtils.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.extendedae_plus.util; - -import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem; -import com.extendedae_plus.config.ModConfig; - -/** - * 用于计算实体加速器的能耗与加速倍率的工具类 - */ -public final class PowerUtils { - private PowerUtils() {} - // ---- 重构后的 API ---- - /** - * 将 card multipliers(按插槽序)计算乘积并应用 cap 规则(见 capForHighestMultiplier) - * @param multipliers iterable of per-card multipliers - * @param maxCards 最多计入的卡数 - * @return 被 cap 约束后的乘积 - */ - public static long computeProductWithCap(Iterable multipliers, int maxCards) { - long product = 1L; - int considered = 0; - int highest = 1; - for (Integer m : multipliers) { - if (m == null) continue; - if (considered >= maxCards) break; - int mult = m.intValue(); - if (mult <= 0) mult = 1; - product *= mult; - highest = Math.max(highest, mult); - considered++; - } - long cap = capForHighestMultiplier(highest); - return Math.min(product, cap); - } - - /** - * 根据最高单卡 multiplier 返回 cap 值 - */ - public static long capForHighestMultiplier(int highestMultiplier) { - if (highestMultiplier >= 16) return 1024L; - if (highestMultiplier >= 8) return 256L; - if (highestMultiplier >= 4) return 64L; - if (highestMultiplier >= 2) return 8L; - return 1L; - } - - /** - * 从菜单对象读取前 maxCards 个加速卡的 multiplier 并计算 product with cap - */ - public static long computeProductWithCapFromMenu(appeng.menu.implementations.UpgradeableMenu menu, int maxCards) { - java.util.List list = new java.util.ArrayList<>(); - int considered = 0; - for (var stack : menu.getUpgrades()) { - if (considered >= maxCards) break; - if (stack != null && !stack.isEmpty() && stack.getItem() instanceof EntitySpeedCardItem) { - int multVal = EntitySpeedCardItem.readMultiplier(stack); - int count = Math.min(stack.getCount(), maxCards - considered); - for (int i = 0; i < count; i++) { - list.add(multVal); - considered++; - if (considered >= maxCards) break; - } - } - } - return computeProductWithCap(list, maxCards); - } - - /** - * 从一组 ItemStack(升级槽)直接计算 product with cap(最多 maxCards) - */ - public static long computeProductWithCapFromStacks(Iterable stacks, int maxCards) { - java.util.List list = new java.util.ArrayList<>(); - int considered = 0; - for (var stack : stacks) { - if (considered >= maxCards) break; - if (stack != null && !stack.isEmpty() && stack.getItem() instanceof EntitySpeedCardItem) { - int multVal = EntitySpeedCardItem.readMultiplier(stack); - int count = Math.min(stack.getCount(), maxCards - considered); - for (int i = 0; i < count; i++) { - list.add(multVal); - considered++; - if (considered >= maxCards) break; - } - } - } - return computeProductWithCap(list, maxCards); - } - - /** - * 计算最终消耗:把 product 转换为等效卡数(log2)并调用 getFinalPower - */ - public static double computeFinalPowerForProduct(long product, int energyCardCount) { - if (product <= 1L) return 0.0; - double base = ModConfig.INSTANCE.entityTickerCost; - - // 计算以2为底的对数(用于分档与公式) - double log2 = Math.log(product) / Math.log(2.0); - - // 分档:product==2 为一档;4..256 为中档;512..1024 为高档 - double raw; - if (product == 2L) { - // 轻量档:线性小幅增长 - raw = base * 4; - } else if (product <= 256L) { - // 中档:增长放缓(使用 1.5 * log2) - raw = base * Math.pow(2.0, 1.5 * log2) * 2; - } else { - // 高档:增长较快(使用 2.5 * log2) - raw = base * Math.pow(2.0, 2.5 * log2); - } - - double reduction = getReductionPercent(energyCardCount); - return raw * (1.0 - reduction) / 8.0; - } - - /* ----------------- legacy helpers (restored) ----------------- */ - public static double getGrowthFactor(int speedCardCount) { - if (speedCardCount <= 0) return 1.0; - if (speedCardCount == 1) return 2.0; - if (speedCardCount <= 6) return Math.pow(2.0, 2.0 * speedCardCount); - return Math.pow(2.0, 3.0 * speedCardCount); - } - - public static double getRawPower(int speedCardCount) { - double base = ModConfig.INSTANCE.entityTickerCost; - return base * getGrowthFactor(speedCardCount); - } - - public static double getReductionPercent(int energyCardCount) { - if (energyCardCount <= 0) return 0.0; - if (energyCardCount == 1) return 0.1; - if (energyCardCount >= 8) return 0.5; - return 0.5 * (1.0 - Math.pow(0.7, energyCardCount)); - } - - public static double getFinalPower(int speedCardCount, int energyCardCount) { - double raw = getRawPower(speedCardCount); - double reduction = getReductionPercent(energyCardCount); - return raw * (1.0 - reduction) / 4.0; - } - - /** - * 返回能源卡减免后剩余的功耗比率(例如 1 张能源卡 -> 0.9) - * @param energyCardCount 能源卡数量 - * @return 剩余功耗比率 - */ - public static double getRemainingRatio(int energyCardCount) { - return 1.0 - getReductionPercent(energyCardCount); - } - - /** - * 将剩余功耗比率格式化为百分比字符串(例如 0.9 -> "90%") - */ - public static String formatPercentage(double ratio) { - double pct = ratio * 100.0; - // 如果为整数则无小数 - if (Math.abs(pct - Math.round(pct)) < 1e-9) { - return String.format("%d%%", Math.round(pct)); - } - return String.format("%.2f%%", pct); - } -} diff --git a/src/main/java/com/extendedae_plus/command/InfinityDiskGiveCommand.java b/src/main/java/com/extendedae_plus/util/command/InfinityDiskGiveCommand.java similarity index 98% rename from src/main/java/com/extendedae_plus/command/InfinityDiskGiveCommand.java rename to src/main/java/com/extendedae_plus/util/command/InfinityDiskGiveCommand.java index 67305f3..399eca1 100644 --- a/src/main/java/com/extendedae_plus/command/InfinityDiskGiveCommand.java +++ b/src/main/java/com/extendedae_plus/util/command/InfinityDiskGiveCommand.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.command; +package com.extendedae_plus.util.command; import com.extendedae_plus.ExtendedAEPlus; import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem; diff --git a/src/main/java/com/extendedae_plus/util/entitySpeed/ConfigParsingUtils.java b/src/main/java/com/extendedae_plus/util/entitySpeed/ConfigParsingUtils.java new file mode 100644 index 0000000..44c9713 --- /dev/null +++ b/src/main/java/com/extendedae_plus/util/entitySpeed/ConfigParsingUtils.java @@ -0,0 +1,220 @@ +package com.extendedae_plus.util.entitySpeed; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import static com.extendedae_plus.util.ExtendedAELogger.LOGGER; + +/** + * 配置解析工具类:用于解析黑名单与倍率配置的字符串 + */ +public final class ConfigParsingUtils { + private ConfigParsingUtils() {} + + public static final class MultiplierEntry { + public final Pattern pattern; + public final double multiplier; + + public MultiplierEntry(Pattern pattern, double multiplier) { + this.pattern = pattern; + this.multiplier = multiplier; + } + } + + /** + * 编译用户提供的匹配串。支持简单的 glob 语法('*' 和 '?')以及完整的正则表达式。 + */ + public static Pattern compilePattern(String raw) { + if (raw == null || raw.trim().isEmpty()) { + LOGGER.warn("Invalid pattern: {}", raw); + throw new IllegalArgumentException("Pattern is null or empty"); + } + raw = raw.trim(); + + // Try regex first if it contains regex metacharacters + if (raw.contains(".*") || raw.matches(".*[\\[\\(\\+\\{\\\\].*")) { + try { + return Pattern.compile("^" + raw + "$"); + } catch (PatternSyntaxException e) { + LOGGER.warn("Failed to compile regex pattern '{}': {}", raw, e.getMessage()); + // Fallback to glob + } + } + + // Convert glob to regex + if (raw.contains("*") || raw.contains("?")) { + StringBuilder sb = new StringBuilder("^"); + for (char c : raw.toCharArray()) { + switch (c) { + case '*': sb.append(".*"); break; + case '?': sb.append('.'); break; + default: + if (".\\+[]{}()^$|".indexOf(c) >= 0) { + sb.append('\\'); + } + sb.append(c); + } + } + sb.append('$'); + return Pattern.compile(sb.toString()); + } + + // Literal match + return Pattern.compile("^" + Pattern.quote(raw) + "$"); + } + + /** + * 解析倍率条目,如 'modid:block 2x'。 + */ + public static MultiplierEntry parseMultiplierEntry(String entry) { + if (entry == null || entry.trim().isEmpty()) return null; + String[] parts = entry.trim().split("\\s+"); + if (parts.length < 2) { + LOGGER.warn("Invalid multiplier entry: {}", entry); + return null; + } + String key = parts[0]; + String val = parts[1].toLowerCase(); + if (val.endsWith("x")) val = val.substring(0, val.length() - 1); + double multiplier; + try { + multiplier = Double.parseDouble(val); + } catch (NumberFormatException e) { + LOGGER.warn("Invalid multiplier value in '{}': {}", entry, val); + return null; + } + try { + Pattern pattern = compilePattern(key); + return new MultiplierEntry(pattern, multiplier); + } catch (IllegalArgumentException e) { + LOGGER.warn("Failed to compile pattern in '{}': {}", entry, e.getMessage()); + return null; + } + } + + /** + * 检查方块是否在黑名单中。 + */ + public static boolean isBlockBlacklisted(String blockId, List blacklist) { + if (blockId == null) return false; + return getCachedBlacklist(blacklist).stream().anyMatch(p -> p.matcher(blockId).matches()); + } + + /** + * 获取方块的倍率。 + */ + public static double getMultiplierForBlock(String blockId, List multipliers) { + if (blockId == null) return 1.0; + double maxMultiplier = 1.0; + for (MultiplierEntry me : getCachedMultiplierEntries(multipliers)) { + if (me.pattern.matcher(blockId).matches()) { + maxMultiplier = Math.max(maxMultiplier, me.multiplier); + } + } + return maxMultiplier; + } + + public static List compilePatterns(List raw) { + List out = new ArrayList<>(); + if (raw == null) return out; + for (String s : raw) { + if (s == null || s.trim().isEmpty()) continue; + try { + out.add(compilePattern(s)); + } catch (IllegalArgumentException e) { + LOGGER.warn("Failed to compile pattern '{}': {}", s, e.getMessage()); + } + } + return out; + } + + public static List parseMultiplierList(List raw) { + List out = new ArrayList<>(); + if (raw == null) return out; + for (String s : raw) { + MultiplierEntry me = parseMultiplierEntry(s); + if (me != null) out.add(me); + } + return out; + } + + // ------------------ 全局缓存与接口 ------------------ + private static volatile List cachedBlacklist = null; + private static volatile List cachedMultiplierEntries = null; + private static volatile List cachedBlacklistSourceSnapshot = null; + private static volatile List cachedMultiplierSourceSnapshot = null; + private static final Object CACHE_LOCK = new Object(); + + /** + * 获取已解析并缓存的黑名单(线程安全、懒加载)。 + */ + public static List getCachedBlacklist(List source) { + List normalized = normalizeSource(source); + if (cachedBlacklist != null && listEquals(cachedBlacklistSourceSnapshot, normalized)) { + return Collections.unmodifiableList(cachedBlacklist); + } + synchronized (CACHE_LOCK) { + if (cachedBlacklist == null || !listEquals(cachedBlacklistSourceSnapshot, normalized)) { + cachedBlacklist = compilePatterns(normalized); + cachedBlacklistSourceSnapshot = normalized.isEmpty() ? Collections.emptyList() : new ArrayList<>(normalized); + } + return Collections.unmodifiableList(cachedBlacklist); + } + } + + /** + * 获取已解析并缓存的倍率列表(线程安全、懒加载)。 + */ + public static List getCachedMultiplierEntries(List source) { + List normalized = normalizeSource(source); + if (cachedMultiplierEntries != null && listEquals(cachedMultiplierSourceSnapshot, normalized)) { + return Collections.unmodifiableList(cachedMultiplierEntries); + } + synchronized (CACHE_LOCK) { + if (cachedMultiplierEntries == null || !listEquals(cachedMultiplierSourceSnapshot, normalized)) { + cachedMultiplierEntries = parseMultiplierList(normalized); + cachedMultiplierSourceSnapshot = normalized.isEmpty() ? Collections.emptyList() : new ArrayList<>(normalized); + } + return Collections.unmodifiableList(cachedMultiplierEntries); + } + } + + // Normalize the incoming source list: trim entries, drop blanks, keep stable ordering + private static List normalizeSource(java.util.List source) { + List out = new ArrayList<>(); + if (source == null) return out; + for (String s : source) { + if (s == null) continue; + String t = s.trim(); + if (t.isEmpty()) continue; + out.add(t); + } + return out; + } + + // Null-safe equality for two lists of strings. Uses size + element equals. + private static boolean listEquals(List a, List b) { + if (a == b) return true; + if (a == null || b == null) return false; + if (a.size() != b.size()) return false; + for (int i = 0; i < a.size(); i++) { + if (!a.get(i).equals(b.get(i))) return false; + } + return true; + } + + /** + * 清空缓存,下一次获取时将重新从提供的源解析(或调用方可以重新调用 getter)。 + */ + public static void reload() { + synchronized (CACHE_LOCK) { + cachedBlacklist = null; + cachedMultiplierEntries = null; + cachedBlacklistSourceSnapshot = null; + cachedMultiplierSourceSnapshot = null; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/util/entitySpeed/PowerUtils.java b/src/main/java/com/extendedae_plus/util/entitySpeed/PowerUtils.java new file mode 100644 index 0000000..529b40f --- /dev/null +++ b/src/main/java/com/extendedae_plus/util/entitySpeed/PowerUtils.java @@ -0,0 +1,98 @@ +package com.extendedae_plus.util.entitySpeed; + +import appeng.api.upgrades.IUpgradeInventory; +import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem; +import com.extendedae_plus.config.ModConfig; +import net.minecraft.world.item.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +/** + * 用于计算实体加速器的能耗与加速倍率的工具类 + */ +public final class PowerUtils { + private PowerUtils() {} + + /** + * 计算加速卡的乘积并应用上限。 + * @param upgrades 升级槽位 + * @param maxCards 最大计入的卡数 + * @return 被上限约束后的乘积 + */ + public static long computeProductWithCap(IUpgradeInventory upgrades, int maxCards) { + List multipliers = new ArrayList<>(); + int considered = 0; + for (ItemStack stack : upgrades) { + if (considered >= maxCards) break; + if (stack != null && !stack.isEmpty() && stack.getItem() instanceof EntitySpeedCardItem) { + int multVal = EntitySpeedCardItem.readMultiplier(stack); + int count = Math.min(stack.getCount(), maxCards - considered); + for (int i = 0; i < count; i++) { + multipliers.add(multVal); + considered++; + } + } + } + long product = 1L; + int highest = 1; + for (Integer m : multipliers) { + if (m == null || m <= 0) continue; + product *= m; + highest = Math.max(highest, m); + } + return Math.min(product, capForHighestMultiplier(highest)); + } + + /** + * 根据最高单卡倍率返回上限值。 + */ + public static long capForHighestMultiplier(int highestMultiplier) { + if (highestMultiplier >= 16) return 1024L; + if (highestMultiplier >= 8) return 256L; + if (highestMultiplier >= 4) return 64L; + if (highestMultiplier >= 2) return 8L; + return 1L; + } + + /** + * 计算最终能耗。 + * @param product 加速卡乘积 + * @param energyCardCount 能量卡数量 + * @return 最终能耗值 + */ + public static double computeFinalPowerForProduct(long product, int energyCardCount) { + if (product <= 1L) return 0.0; + double base = ModConfig.INSTANCE.entityTickerCost; + double log2 = Math.log(product) / Math.log(2.0); + double raw; + if (product == 2L) { + raw = base * 4; + } else if (product <= 256L) { + raw = base * Math.pow(2.0, 1.5 * log2) * 2; + } else { + raw = base * Math.pow(2.0, 2.5 * log2); + } + return raw * getRemainingRatio(energyCardCount) / 8.0; + } + + /** + * 计算能量卡减免后的剩余功耗比率。 + */ + public static double getRemainingRatio(int energyCardCount) { + if (energyCardCount <= 0) return 1.0; + if (energyCardCount == 1) return 0.9; + if (energyCardCount >= 8) return 0.5; + return 1.0 - 0.5 * (1.0 - Math.pow(0.7, energyCardCount)); + } + + /** + * 将剩余功耗比率格式化为百分比字符串。 + */ + public static String formatPercentage(double ratio) { + double pct = ratio * 100.0; + return Math.abs(pct - Math.round(pct)) < 1e-9 ? + String.format("%d%%", Math.round(pct)) : + String.format("%.2f%%", pct); + } +} \ No newline at end of file diff --git a/src/main/java/com/extendedae_plus/util/PatternScaler.java b/src/main/java/com/extendedae_plus/util/smartDoubling/PatternScaler.java similarity index 91% rename from src/main/java/com/extendedae_plus/util/PatternScaler.java rename to src/main/java/com/extendedae_plus/util/smartDoubling/PatternScaler.java index 11a454f..3a2eccf 100644 --- a/src/main/java/com/extendedae_plus/util/PatternScaler.java +++ b/src/main/java/com/extendedae_plus/util/smartDoubling/PatternScaler.java @@ -1,11 +1,11 @@ -package com.extendedae_plus.util; +package com.extendedae_plus.util.smartDoubling; import appeng.api.stacks.AEKey; import appeng.api.stacks.GenericStack; import appeng.crafting.pattern.AEProcessingPattern; -import com.extendedae_plus.api.SmartDoublingAwarePattern; +import com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern; +import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern; import com.extendedae_plus.config.ModConfig; -import com.extendedae_plus.content.ScaledProcessingPattern; public final class PatternScaler { private PatternScaler() { @@ -16,7 +16,7 @@ public final class PatternScaler { if (target == null) throw new IllegalArgumentException("target"); // 双保险:若样板标记为不允许缩放,直接放弃缩放(返回 null 表示调用方应保持原样板) - if (base instanceof SmartDoublingAwarePattern aware && !aware.eap$allowScaling()) { + if (base instanceof ISmartDoublingAwarePattern aware && !aware.eap$allowScaling()) { return null; } diff --git a/src/main/java/com/extendedae_plus/util/RequestedAmountHolder.java b/src/main/java/com/extendedae_plus/util/smartDoubling/RequestedAmountHolder.java similarity index 95% rename from src/main/java/com/extendedae_plus/util/RequestedAmountHolder.java rename to src/main/java/com/extendedae_plus/util/smartDoubling/RequestedAmountHolder.java index e70187a..005f919 100644 --- a/src/main/java/com/extendedae_plus/util/RequestedAmountHolder.java +++ b/src/main/java/com/extendedae_plus/util/smartDoubling/RequestedAmountHolder.java @@ -1,4 +1,4 @@ -package com.extendedae_plus.util; +package com.extendedae_plus.util.smartDoubling; import java.util.ArrayDeque; import java.util.Deque; diff --git a/src/main/resources/assets/ae2/screens/entity_speed_ticker.json b/src/main/resources/assets/ae2/screens/entity_speed_ticker.json index e30da1a..f8156f6 100644 --- a/src/main/resources/assets/ae2/screens/entity_speed_ticker.json +++ b/src/main/resources/assets/ae2/screens/entity_speed_ticker.json @@ -50,8 +50,7 @@ "left": 88 }, "align": "CENTER" - } - , + }, "multiplier": { "position": { "top": 80, diff --git a/src/main/resources/assets/extendedae_plus/lang/en_us.json b/src/main/resources/assets/extendedae_plus/lang/en_us.json index 07156e3..3e8a67d 100644 --- a/src/main/resources/assets/extendedae_plus/lang/en_us.json +++ b/src/main/resources/assets/extendedae_plus/lang/en_us.json @@ -27,6 +27,12 @@ "tooltip.extendedae_plus.infinity_biginteger_cell.summon2": "§b—§4A §dUni§cverse §eWith§ain §6A §bSin§5gle §9Point", "tooltip.extendedae_plus.entity_speed_card.multiplier": "Multiplier: %s", "tooltip.extendedae_plus.entity_speed_card.max": "Max effective: %s x", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip": "Assembler Matrix Upload Core", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload": "Upload to Assembler Matrix", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_success": "Pattern uploaded to Assembler Matrix", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_not_crafting": "Only crafting patterns supported, processing patterns ignored", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_no_matrix": "No formed Assembler Matrix found in network", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_full": "Assembler Matrix pattern storage full or cannot insert", "block.extendedae_plus.wireless_transceiver": "Wireless Transceiver", "block.extendedae_plus.4x_crafting_accelerator": "4x Crafting Accelerator", @@ -54,6 +60,7 @@ "screen.extendedae_plus.entity_speed_ticker.power_ratio": "Power ratio: %s", "screen.extendedae_plus.entity_speed_ticker.speed": "Current speed multiplier: %d", "screen.extendedae_plus.entity_speed_ticker.multiplier": "Extra consumption multiplier: %s", + "screen.extendedae_plus.entity_speed_ticker.warning_network_energy_insufficient": "§c§lInsufficient network energy", "item.extendedae_plus.entity_speed_ticker.tip.requirement": "Requires Entity Acceleration Card(s) to enable acceleration", "item.extendedae_plus.entity_speed_ticker.tip.max": "Maximum up to 1024x speed", @@ -87,11 +94,13 @@ "config.extendedae_plus.option.entityTickerBlackList": "Entity Ticker Blacklist", "config.extendedae_plus.option.entityTickerMultipliers": "Entity Ticker Extra Consumption Multipliers", "config.extendedae_plus.option.craftingPauseThreshold": "AE synthesis calculation pause check threshold", - "block.extendedae_plus.assembler_matrix_upload_core": "Assembler Matrix Upload Core", + "config.extendedae_plus.option.prioritizeDiskEnergy": "Prioritize FE energy from disk (requires Applied Flux)", "item.extendedae_plus.channel_card": "Channel Card", "item.extendedae_plus.channel_card.channel": "Frequency: %s", "item.extendedae_plus.channel_card.channel.unset": "Frequency: Unset", "item.extendedae_plus.channel_card.set": "Frequency set to: %s", + "group.pattern_provider.name": "Pattern Provider", + "group.entity_ticker.name": "Entity Accelerator", "group.storage.name": "StorageBus" } \ No newline at end of file diff --git a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json index a245edb..92d01cc 100644 --- a/src/main/resources/assets/extendedae_plus/lang/zh_cn.json +++ b/src/main/resources/assets/extendedae_plus/lang/zh_cn.json @@ -18,6 +18,7 @@ "item.extendedae_plus.1024x_crafting_accelerator": "1024x并行处理单元", "item.extendedae_plus.network_pattern_controller": "样板供应器状态控制器", "item.extendedae_plus.entity_speed_card": "实体加速卡", + "item.extendedae_plus.entity_speed_card.x1": "§k§l?#@§r§8不§k§l1§r限§k§l0§r存于§k§l%§r现实的§c实§k&0%§r体加§k§l*§r速卡§k§l...§r", "item.extendedae_plus.entity_speed_card.x2": "实体加速卡 (x2)", "item.extendedae_plus.entity_speed_card.x4": "实体加速卡 (x4)", "item.extendedae_plus.entity_speed_card.x8": "实体加速卡 (x8)", @@ -27,6 +28,12 @@ "tooltip.extendedae_plus.infinity_biginteger_cell.summon2": "§b——§4方§d寸§c之§e间§a, §6自§b有§5千§9寰", "tooltip.extendedae_plus.entity_speed_card.multiplier": "乘数: %s", "tooltip.extendedae_plus.entity_speed_card.max": "最大生效: %s 倍", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip": "装配矩阵上传核心", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload": "上传到装配矩阵", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_success": "样板已上传到装配矩阵", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_not_crafting": "仅支持上传合成样板,处理样板将被忽略", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_no_matrix": "未在当前网络中找到已成型的装配矩阵", + "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_full": "装配矩阵的样板仓已满或无法插入", "block.extendedae_plus.wireless_transceiver": "无线收发器", "block.extendedae_plus.4x_crafting_accelerator": "4x并行处理单元", @@ -54,6 +61,7 @@ "screen.extendedae_plus.entity_speed_ticker.power_ratio": "功耗比例: %s", "screen.extendedae_plus.entity_speed_ticker.speed": "当前加速倍率: %d", "screen.extendedae_plus.entity_speed_ticker.multiplier": "额外消耗倍率: %s", + "screen.extendedae_plus.entity_speed_ticker.warning_network_energy_insufficient": "§c§l网络能量不足", "item.extendedae_plus.entity_speed_ticker.tip.requirement": "需要放入实体加速卡以启用加速", "item.extendedae_plus.entity_speed_ticker.tip.max": "最高可达 1024x 加速", @@ -86,13 +94,8 @@ "config.extendedae_plus.option.entityTickerCost": "实体加速器能量消耗基础值", "config.extendedae_plus.option.entityTickerBlackList": "实体加速器黑名单", "config.extendedae_plus.option.entityTickerMultipliers": "实体加速器额外消耗倍率", + "config.extendedae_plus.option.prioritizeDiskEnergy": "优先从磁盘提取FE能量(仅当Applied Flux模组存在时生效)", "config.extendedae_plus.option.craftingPauseThreshold": "AE合成计算暂停检查阈值", - "block.extendedae_plus.assembler_matrix_upload_core.tooltip": "装配矩阵上传核心", - "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload": "上传到装配矩阵", - "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_success": "样板已上传到装配矩阵", - "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_not_crafting": "仅支持上传合成样板,处理样板将被忽略", - "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_no_matrix": "未在当前网络中找到已成型的装配矩阵", - "block.extendedae_plus.assembler_matrix_upload_core.tooltip.upload_fail_full": "装配矩阵的样板仓已满或无法插入", "item.extendedae_plus.channel_card": "频道卡", "item.extendedae_plus.channel_card.channel": "频率:%s", diff --git a/src/main/resources/extendedae_plus.mixins.json b/src/main/resources/extendedae_plus.mixins.json index 97c7ce5..2a6915a 100644 --- a/src/main/resources/extendedae_plus.mixins.json +++ b/src/main/resources/extendedae_plus.mixins.json @@ -9,9 +9,7 @@ "accessor.ScreenAccessor", "advancedae.client.gui.AdvPatternProviderScreenMixin", "advancedae.client.gui.SmallAdvPatternProviderScreenMixin", - "ae2.QuartzCuttingKnifeItemMixin", "ae2.accessor.AEBaseScreenAccessor", - "ae2.accessor.AEBaseScreenInvoker", "ae2.accessor.MEStorageScreenAccessor", "ae2.accessor.PatternAccessTermScreenAccessor", "ae2.accessor.PatternAccessTermScreenSlotsRowAccessor", @@ -20,8 +18,9 @@ "ae2.client.gui.PatternEncodingTermScreenMixin", "ae2.client.gui.PatternProviderCloseMixin", "ae2.client.gui.PatternProviderScreenMixin", - "ae2.compat.PatternProviderScreenCompatMixin", "ae2.client.gui.SlotGridLayoutMixin", + "ae2.compat.PatternProviderScreenCompatMixin", + "ae2.items.QuartzCuttingKnifeItemMixin", "ae2.menu.CraftConfirmMenuGoBackMixin", "extendedae.accessor.GuiExPatternTerminalAccessor", "extendedae.accessor.GuiExPatternTerminalSlotsRowAccessor", @@ -45,43 +44,42 @@ "ae2.CraftingCalculationMixin", "ae2.CraftingCPUClusterMixin", "ae2.EncodedPatternItemMixin", + "ae2.InterfaceLogicUpgradesMixin", "ae2.accessor.MEStorageMenuAccessor", "ae2.accessor.PatternEncodingTermMenuAccessor", "ae2.accessor.PatternProviderLogicAccessor", - "ae2.accessor.PatternProviderLogicPatternInputsAccessor", - "ae2.accessor.PatternProviderLogicPatternsAccessor", - "ae2.accessor.PatternProviderMenuAdvancedAccessor", + "ae2.accessor.PatternProviderMenuAccessor", "ae2.autopattern.CraftingServiceGetProvidersMixin", "ae2.autopattern.CraftingTreeNodeAccessor", "ae2.autopattern.CraftingTreeNodeMixin", "ae2.autopattern.CraftingTreeProcessMixin", "ae2.autopattern.PatternProviderLogicContainsRedirectMixin", + "ae2.compat.PatternProviderCompatMixin", + "ae2.compat.PatternProviderLogicCompatMixin", + "ae2.compat.PatternProviderLogicHostCompatMixin", + "ae2.helpers.InterfaceLogicChannelCardMixin", + "ae2.helpers.InterfaceLogicTickerMixin", "ae2.helpers.PatternProviderLogicAdvancedMixin", "ae2.helpers.PatternProviderLogicDoublingMixin", + "ae2.helpers.patternprovider.PatternProviderLogicTickerMixin", + "ae2.items.MemoryCardItemMixin", "ae2.menu.ContainerPatternEncodingTermMenuMixin", "ae2.menu.MEStorageMenuMixin", "ae2.menu.PatternEncodingTermMenuMixin", "ae2.menu.PatternProviderMenuAdvancedMixin", "ae2.menu.PatternProviderMenuDoublingMixin", - "ae2.compat.PatternProviderLogicCompatMixin", - "ae2.compat.PatternProviderLogicHostCompatMixin", - "ae2.compat.PatternProviderCompatMixin", - "appflux.AppfluxPatternProviderLogicMixin", - "ae2.helpers.patternprovider.PatternProviderLogicTickerMixin", "ae2.parts.AEBasePartClientSyncMixin", "ae2.parts.automation.IOBusPartChannelCardMixin", "ae2.parts.automation.IOBusPartTickerChannelCardMixin", "ae2.parts.storagebus.StorageBusPartChannelCardMixin", "ae2.parts.storagebus.StorageBusPartTickerChannelCardMixin", "ae2WTlib.ContainerUWirelessExPatternTerminalMixin", + "appflux.AppfluxPatternProviderLogicMixin", "extendedae.common.PartExPatternProviderMixin", "extendedae.common.TileExPatternProviderMixin", "extendedae.container.ContainerExPatternProviderMixin", "extendedae.container.ContainerExPatternTerminalMixin", - "extendedae.container.ContainerWirelessExPatternTerminalMixin", - "ae2.helpers.InterfaceLogicChannelCardMixin", - "ae2.helpers.InterfaceLogicTickerMixin", - "ae2.InterfaceLogicUpgradesMixin" + "extendedae.container.ContainerWirelessExPatternTerminalMixin" ], "injectors": { "defaultRequire": 1