根据主分支包结构重新整理
This commit is contained in:
parent
5d9d76789e
commit
0049b3c3fc
|
|
@ -1,42 +0,0 @@
|
||||||
package com.extendedae_plus;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.neoforged.bus.api.SubscribeEvent;
|
|
||||||
import net.neoforged.fml.common.EventBusSubscriber;
|
|
||||||
import net.neoforged.fml.event.config.ModConfigEvent;
|
|
||||||
import net.neoforged.neoforge.common.ModConfigSpec;
|
|
||||||
|
|
||||||
// An example config class. This is not required, but it's a good idea to have one to keep your config organized.
|
|
||||||
// Demonstrates how to use Neo's config APIs
|
|
||||||
public class Config {
|
|
||||||
private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder();
|
|
||||||
|
|
||||||
public static final ModConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER
|
|
||||||
.comment("Whether to log the dirt block on common setup")
|
|
||||||
.define("logDirtBlock", true);
|
|
||||||
|
|
||||||
public static final ModConfigSpec.IntValue MAGIC_NUMBER = BUILDER
|
|
||||||
.comment("A magic number")
|
|
||||||
.defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE);
|
|
||||||
|
|
||||||
public static final ModConfigSpec.ConfigValue<String> MAGIC_NUMBER_INTRODUCTION = BUILDER
|
|
||||||
.comment("What you want the introduction message to be for the magic number")
|
|
||||||
.define("magicNumberIntroduction", "The magic number is... ");
|
|
||||||
|
|
||||||
// a list of strings that are treated as resource locations for items
|
|
||||||
public static final ModConfigSpec.ConfigValue<List<? extends String>> ITEM_STRINGS = BUILDER
|
|
||||||
.comment("A list of items to log on common setup.")
|
|
||||||
.defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), () -> "", Config::validateItemName);
|
|
||||||
|
|
||||||
static final ModConfigSpec SPEC = BUILDER.build();
|
|
||||||
|
|
||||||
private static boolean validateItemName(final Object obj) {
|
|
||||||
return obj instanceof String itemName && BuiltInRegistries.ITEM.containsKey(ResourceLocation.parse(itemName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,8 +6,8 @@ import appeng.api.storage.StorageCells;
|
||||||
import appeng.block.AEBaseEntityBlock;
|
import appeng.block.AEBaseEntityBlock;
|
||||||
import appeng.blockentity.crafting.CraftingBlockEntity;
|
import appeng.blockentity.crafting.CraftingBlockEntity;
|
||||||
import appeng.items.parts.PartModelsHelper;
|
import appeng.items.parts.PartModelsHelper;
|
||||||
import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellHandler;
|
|
||||||
import com.extendedae_plus.api.ids.EAPComponents;
|
import com.extendedae_plus.api.ids.EAPComponents;
|
||||||
|
import com.extendedae_plus.api.storage.InfinityBigIntegerCellHandler;
|
||||||
import com.extendedae_plus.config.ModConfigs;
|
import com.extendedae_plus.config.ModConfigs;
|
||||||
import com.extendedae_plus.init.*;
|
import com.extendedae_plus.init.*;
|
||||||
import com.extendedae_plus.util.storage.InfinityStorageManager;
|
import com.extendedae_plus.util.storage.InfinityStorageManager;
|
||||||
|
|
@ -37,6 +37,10 @@ public class ExtendedAEPlus {
|
||||||
// Directly reference a slf4j logger
|
// Directly reference a slf4j logger
|
||||||
public static final Logger LOGGER = LogUtils.getLogger();
|
public static final Logger LOGGER = LogUtils.getLogger();
|
||||||
// 移除 MDK 示例注册,改为使用实际模组的方块/物品/创造物品栏注册见 ModBlocks、ModItems、ModCreativeTabs
|
// 移除 MDK 示例注册,改为使用实际模组的方块/物品/创造物品栏注册见 ModBlocks、ModItems、ModCreativeTabs
|
||||||
|
@Nullable
|
||||||
|
private static InfinityStorageManager storageManager;
|
||||||
|
@Nullable
|
||||||
|
private static MinecraftServer storageManagerServer;
|
||||||
|
|
||||||
// The constructor for the mod class is the first code that is run when your mod is loaded.
|
// The constructor for the mod class is the first code that is run when your mod is loaded.
|
||||||
// FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically.
|
// FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically.
|
||||||
|
|
@ -74,6 +78,23 @@ public class ExtendedAEPlus {
|
||||||
return ResourceLocation.fromNamespaceAndPath(MODID, path);
|
return ResourceLocation.fromNamespaceAndPath(MODID, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void onServerStarted(ServerStartedEvent event) {
|
||||||
|
storageManagerServer = event.getServer();
|
||||||
|
storageManager = InfinityStorageManager.getInstance(event.getServer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void onServerStopped(ServerStoppedEvent event) {
|
||||||
|
if (storageManagerServer == event.getServer()) {
|
||||||
|
storageManagerServer = null;
|
||||||
|
storageManager = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static InfinityStorageManager currentStorageManager() {
|
||||||
|
return storageManager;
|
||||||
|
}
|
||||||
|
|
||||||
private void commonSetup(FMLCommonSetupEvent event) {
|
private void commonSetup(FMLCommonSetupEvent event) {
|
||||||
// Some common setup code
|
// Some common setup code
|
||||||
LOGGER.info("HELLO FROM COMMON SETUP");
|
LOGGER.info("HELLO FROM COMMON SETUP");
|
||||||
|
|
@ -136,29 +157,6 @@ public class ExtendedAEPlus {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static InfinityStorageManager storageManager;
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static MinecraftServer storageManagerServer;
|
|
||||||
|
|
||||||
private static void onServerStarted(ServerStartedEvent event) {
|
|
||||||
storageManagerServer = event.getServer();
|
|
||||||
storageManager = InfinityStorageManager.getInstance(event.getServer());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void onServerStopped(ServerStoppedEvent event) {
|
|
||||||
if (storageManagerServer == event.getServer()) {
|
|
||||||
storageManagerServer = null;
|
|
||||||
storageManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static InfinityStorageManager currentStorageManager() {
|
|
||||||
return storageManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
// You can use SubscribeEvent and let the Event Bus discover methods to call
|
// You can use SubscribeEvent and let the Event Bus discover methods to call
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onServerStarting(ServerStartingEvent event) {
|
public void onServerStarting(ServerStartingEvent event) {
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
|
|
||||||
private boolean tryExtractFE(IEnergyService energyService, MEStorage storage, double requiredPower, IActionSource source) {
|
private boolean tryExtractFE(IEnergyService energyService, MEStorage storage, double requiredPower, IActionSource source) {
|
||||||
try {
|
try {
|
||||||
Class<?> helperClass = Class.forName("com.extendedae_plus.util.FluxEnergyHelper");
|
Class<?> helperClass = Class.forName("com.extendedae_plus.util.entitySpeed.FluxEnergyHelper");
|
||||||
Method extractMethod = helperClass.getMethod(
|
Method extractMethod = helperClass.getMethod(
|
||||||
"extractFE",
|
"extractFE",
|
||||||
IEnergyService.class,
|
IEnergyService.class,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.wireless;
|
package com.extendedae_plus.ae.wireless;
|
||||||
|
|
||||||
import appeng.api.networking.IGridNode;
|
import appeng.api.networking.IGridNode;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.wireless;
|
package com.extendedae_plus.ae.wireless;
|
||||||
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
@ -24,13 +24,13 @@ public class WirelessMasterLink {
|
||||||
this.placerId = placerId;
|
this.placerId = placerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFrequency() { return frequency; }
|
public long getFrequency() {return this.frequency;}
|
||||||
|
|
||||||
public void setFrequency(long frequency) {
|
public void setFrequency(long frequency) {
|
||||||
// 如果频率发生变化,先撤销旧频率的注册
|
// 如果频率发生变化,先撤销旧频率的注册
|
||||||
if (this.frequency != frequency) {
|
if (this.frequency != frequency) {
|
||||||
if (registered) {
|
if (this.registered) {
|
||||||
unregister();
|
this.unregister();
|
||||||
}
|
}
|
||||||
this.frequency = frequency;
|
this.frequency = frequency;
|
||||||
}
|
}
|
||||||
|
|
@ -38,35 +38,35 @@ public class WirelessMasterLink {
|
||||||
// 频率未变的情况下也要校正注册状态:
|
// 频率未变的情况下也要校正注册状态:
|
||||||
// - 当从"从端"切回"主端"时,registered 可能为 false,需要重新注册;
|
// - 当从"从端"切回"主端"时,registered 可能为 false,需要重新注册;
|
||||||
// - 当频率为 0 或端点被移除时,确保处于未注册。
|
// - 当频率为 0 或端点被移除时,确保处于未注册。
|
||||||
if (frequency != 0L && !host.isEndpointRemoved()) {
|
if (frequency != 0L && !this.host.isEndpointRemoved()) {
|
||||||
if (!registered) {
|
if (!this.registered) {
|
||||||
register();
|
this.register();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (registered) {
|
if (this.registered) {
|
||||||
unregister();
|
this.unregister();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean register() {
|
public boolean register() {
|
||||||
ServerLevel level = host.getServerLevel();
|
ServerLevel level = this.host.getServerLevel();
|
||||||
if (level == null || frequency == 0L) return false;
|
if (level == null || this.frequency == 0L) return false;
|
||||||
// placerId可以为null(公共收发器模式)
|
// placerId可以为null(公共收发器模式)
|
||||||
boolean ok = WirelessMasterRegistry.register(level, frequency, placerId, host);
|
boolean ok = WirelessMasterRegistry.register(level, this.frequency, this.placerId, this.host);
|
||||||
this.registered = ok;
|
this.registered = ok;
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregister() {
|
private void unregister() {
|
||||||
ServerLevel level = host.getServerLevel();
|
ServerLevel level = this.host.getServerLevel();
|
||||||
if (!registered || level == null || frequency == 0L) return;
|
if (!this.registered || level == null || this.frequency == 0L) return;
|
||||||
// placerId可以为null(公共收发器模式)
|
// placerId可以为null(公共收发器模式)
|
||||||
WirelessMasterRegistry.unregister(level, frequency, placerId, host);
|
WirelessMasterRegistry.unregister(level, this.frequency, this.placerId, this.host);
|
||||||
registered = false;
|
this.registered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUnloadOrRemove() {
|
public void onUnloadOrRemove() {
|
||||||
unregister();
|
this.unregister();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.extendedae_plus.wireless;
|
package com.extendedae_plus.ae.wireless;
|
||||||
|
|
||||||
import com.extendedae_plus.config.ModConfigs;
|
import com.extendedae_plus.config.ModConfigs;
|
||||||
import com.extendedae_plus.util.WirelessTeamUtil;
|
import com.extendedae_plus.util.wireless.WirelessTeamUtil;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
|
@ -20,15 +20,14 @@ import java.util.UUID;
|
||||||
* 公共模式:placerId为null时使用公共UUID,所有人都能访问(向下兼容旧版本)。
|
* 公共模式:placerId为null时使用公共UUID,所有人都能访问(向下兼容旧版本)。
|
||||||
*/
|
*/
|
||||||
public final class WirelessMasterRegistry {
|
public final class WirelessMasterRegistry {
|
||||||
private WirelessMasterRegistry() {}
|
|
||||||
|
|
||||||
private static final Map<Key, WeakReference<IWirelessEndpoint>> MASTERS = new HashMap<>();
|
private static final Map<Key, WeakReference<IWirelessEndpoint>> MASTERS = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 公共收发器UUID(用于没有设置所有者的收发器)
|
* 公共收发器UUID(用于没有设置所有者的收发器)
|
||||||
* 所有placerId为null的收发器都使用这个UUID,实现公共访问
|
* 所有placerId为null的收发器都使用这个UUID,实现公共访问
|
||||||
*/
|
*/
|
||||||
public static final UUID PUBLIC_NETWORK_UUID = new UUID(0, 0);
|
private static final UUID PUBLIC_NETWORK_UUID = new UUID(0, 0);
|
||||||
|
|
||||||
|
private WirelessMasterRegistry() {}
|
||||||
|
|
||||||
public static synchronized boolean register(ServerLevel level, long frequency, @Nullable UUID placerId, IWirelessEndpoint endpoint) {
|
public static synchronized boolean register(ServerLevel level, long frequency, @Nullable UUID placerId, IWirelessEndpoint endpoint) {
|
||||||
Objects.requireNonNull(level, "level");
|
Objects.requireNonNull(level, "level");
|
||||||
|
|
@ -54,7 +53,7 @@ public final class WirelessMasterRegistry {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void unregister(ServerLevel level, long frequency, @Nullable UUID placerId, IWirelessEndpoint endpoint) {
|
static synchronized void unregister(ServerLevel level, long frequency, @Nullable UUID placerId, IWirelessEndpoint endpoint) {
|
||||||
if (frequency == 0L || level == null) return;
|
if (frequency == 0L || level == null) return;
|
||||||
|
|
||||||
UUID ownerUUID = placerId != null
|
UUID ownerUUID = placerId != null
|
||||||
|
|
@ -100,9 +99,9 @@ public final class WirelessMasterRegistry {
|
||||||
private record Key(@Nullable ResourceKey<Level> dim, long freq, UUID owner) {
|
private record Key(@Nullable ResourceKey<Level> dim, long freq, UUID owner) {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return (dim == null ? "*" : dim.location().toString())
|
return (this.dim == null ? "*" : this.dim.location().toString())
|
||||||
+ "#" + freq
|
+ "#" + this.freq
|
||||||
+ "@" + owner;
|
+ "@" + this.owner;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.wireless;
|
package com.extendedae_plus.ae.wireless;
|
||||||
|
|
||||||
import appeng.api.networking.GridHelper;
|
import appeng.api.networking.GridHelper;
|
||||||
import appeng.api.networking.IGridConnection;
|
import appeng.api.networking.IGridConnection;
|
||||||
|
|
@ -35,59 +35,59 @@ public class WirelessSlaveLink {
|
||||||
this.placerId = placerId;
|
this.placerId = placerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getFrequency() {
|
||||||
|
return this.frequency;
|
||||||
|
}
|
||||||
|
|
||||||
public void setFrequency(long frequency) {
|
public void setFrequency(long frequency) {
|
||||||
if (this.frequency != frequency) {
|
if (this.frequency != frequency) {
|
||||||
this.frequency = frequency;
|
this.frequency = frequency;
|
||||||
// 频率变更,立即尝试重连/断开
|
// 频率变更,立即尝试重连/断开
|
||||||
updateStatus();
|
this.updateStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFrequency() {
|
|
||||||
return frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
return !shutdown && connection.getConnection() != null;
|
return !this.shutdown && this.connection.getConnection() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getDistance() {
|
public double getDistance() {
|
||||||
return distance;
|
return this.distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 建议在 BE 的 serverTick 或者频率/加载状态变化时调用。
|
* 建议在 BE 的 serverTick 或者频率/加载状态变化时调用。
|
||||||
*/
|
*/
|
||||||
public void updateStatus() {
|
public void updateStatus() {
|
||||||
if (host.isEndpointRemoved()) {
|
if (this.host.isEndpointRemoved()) {
|
||||||
destroyConnection();
|
this.destroyConnection();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final ServerLevel level = host.getServerLevel();
|
final ServerLevel level = this.host.getServerLevel();
|
||||||
if (level == null || frequency == 0L) {
|
if (level == null || this.frequency == 0L) {
|
||||||
destroyConnection();
|
this.destroyConnection();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// placerId可以为null(公共收发器模式)
|
// placerId可以为null(公共收发器模式)
|
||||||
IWirelessEndpoint master = WirelessMasterRegistry.get(level, frequency, placerId);
|
IWirelessEndpoint master = WirelessMasterRegistry.get(level, this.frequency, this.placerId);
|
||||||
shutdown = false;
|
this.shutdown = false;
|
||||||
distance = 0.0D;
|
this.distance = 0.0D;
|
||||||
|
|
||||||
boolean crossDim = ModConfigs.WIRELESS_CROSS_DIM_ENABLE.get();
|
boolean crossDim = ModConfigs.WIRELESS_CROSS_DIM_ENABLE.get();
|
||||||
if (master != null && !master.isEndpointRemoved() && (crossDim || master.getServerLevel() == level)) {
|
if (master != null && !master.isEndpointRemoved() && (crossDim || master.getServerLevel() == level)) {
|
||||||
if (!crossDim) {
|
if (!crossDim) {
|
||||||
distance = Math.sqrt(master.getBlockPos().distSqr(host.getBlockPos()));
|
this.distance = Math.sqrt(master.getBlockPos().distSqr(this.host.getBlockPos()));
|
||||||
}
|
}
|
||||||
double maxRange = ModConfigs.WIRELESS_MAX_RANGE.get();
|
double maxRange = ModConfigs.WIRELESS_MAX_RANGE.get();
|
||||||
if (crossDim || distance <= maxRange) {
|
if (crossDim || this.distance <= maxRange) {
|
||||||
// 保持/建立连接
|
// 保持/建立连接
|
||||||
try {
|
try {
|
||||||
var current = connection.getConnection();
|
var current = this.connection.getConnection();
|
||||||
IGridNode a = host.getGridNode(); // 从端
|
IGridNode a = this.host.getGridNode(); // 从端
|
||||||
IGridNode b = master.getGridNode(); // 主端
|
IGridNode b = master.getGridNode(); // 主端
|
||||||
if (a == null || b == null) {
|
if (a == null || b == null) {
|
||||||
shutdown = true;
|
this.shutdown = true;
|
||||||
} else {
|
} else {
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
// 如果已连且目标相同则维持
|
// 如果已连且目标相同则维持
|
||||||
|
|
@ -98,37 +98,37 @@ public class WirelessSlaveLink {
|
||||||
}
|
}
|
||||||
// 否则先断开,再重建
|
// 否则先断开,再重建
|
||||||
current.destroy();
|
current.destroy();
|
||||||
connection = new ConnectionWrapper(null);
|
this.connection = new ConnectionWrapper(null);
|
||||||
}
|
}
|
||||||
// AE2 侧是否已经存在连接(例如此前创建但 wrapper 丢失)
|
// AE2 侧是否已经存在连接(例如此前创建但 wrapper 丢失)
|
||||||
IGridConnection existing = findExistingConnection(a, b);
|
IGridConnection existing = this.findExistingConnection(a, b);
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
connection = new ConnectionWrapper(existing);
|
this.connection = new ConnectionWrapper(existing);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
connection = new ConnectionWrapper(GridHelper.createConnection(a, b));
|
this.connection = new ConnectionWrapper(GridHelper.createConnection(a, b));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (IllegalStateException ex) {
|
} catch (IllegalStateException ex) {
|
||||||
// 连接非法(如重复连接等)——落入重建/关闭逻辑
|
// 连接非法(如重复连接等)——落入重建/关闭逻辑
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
shutdown = true; // 超出范围
|
this.shutdown = true; // 超出范围
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
shutdown = true; // 无主或主端不可用
|
this.shutdown = true; // 无主或主端不可用
|
||||||
}
|
}
|
||||||
|
|
||||||
// 需要关闭连接
|
// 需要关闭连接
|
||||||
destroyConnection();
|
this.destroyConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUnloadOrRemove() {
|
public void onUnloadOrRemove() {
|
||||||
destroyConnection();
|
this.destroyConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void destroyConnection() {
|
private void destroyConnection() {
|
||||||
var current = connection.getConnection();
|
var current = this.connection.getConnection();
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
var a = current.a();
|
var a = current.a();
|
||||||
var b = current.b();
|
var b = current.b();
|
||||||
|
|
@ -144,11 +144,11 @@ public class WirelessSlaveLink {
|
||||||
b.getGrid().getTickManager().wakeDevice(b);
|
b.getGrid().getTickManager().wakeDevice(b);
|
||||||
}
|
}
|
||||||
} catch (Throwable ignored) {}
|
} catch (Throwable ignored) {}
|
||||||
connection.setConnection(null);
|
this.connection.setConnection(null);
|
||||||
} else {
|
} else {
|
||||||
// 兜底:如果 wrapper 已丢失,但 AE2 内仍有直连,则尝试查找并销毁
|
// 兜底:如果 wrapper 已丢失,但 AE2 内仍有直连,则尝试查找并销毁
|
||||||
try {
|
try {
|
||||||
IGridNode a = host.getGridNode();
|
IGridNode a = this.host.getGridNode();
|
||||||
if (a != null) {
|
if (a != null) {
|
||||||
for (IGridConnection gc : a.getConnections()) {
|
for (IGridConnection gc : a.getConnections()) {
|
||||||
// 我们创建的是非 in-world 直连
|
// 我们创建的是非 in-world 直连
|
||||||
|
|
@ -165,7 +165,7 @@ public class WirelessSlaveLink {
|
||||||
}
|
}
|
||||||
} catch (Throwable ignored) {}
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
connection = new ConnectionWrapper(null);
|
this.connection = new ConnectionWrapper(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.extendedae_plus.wireless.endpoint;
|
package com.extendedae_plus.ae.wireless.endpoint;
|
||||||
|
|
||||||
import appeng.api.networking.IGridNode;
|
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.core.BlockPos;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
|
@ -24,7 +24,7 @@ public class GenericNodeEndpointImpl implements IWirelessEndpoint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerLevel getServerLevel() {
|
public ServerLevel getServerLevel() {
|
||||||
var be = blockEntitySupplier.get();
|
var be = this.blockEntitySupplier.get();
|
||||||
if (be == null) return null;
|
if (be == null) return null;
|
||||||
Level lvl = be.getLevel();
|
Level lvl = be.getLevel();
|
||||||
return (lvl instanceof ServerLevel) ? (ServerLevel) lvl : null;
|
return (lvl instanceof ServerLevel) ? (ServerLevel) lvl : null;
|
||||||
|
|
@ -32,18 +32,18 @@ public class GenericNodeEndpointImpl implements IWirelessEndpoint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockPos getBlockPos() {
|
public BlockPos getBlockPos() {
|
||||||
var be = blockEntitySupplier.get();
|
var be = this.blockEntitySupplier.get();
|
||||||
return be != null ? be.getBlockPos() : BlockPos.ZERO;
|
return be != null ? be.getBlockPos() : BlockPos.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IGridNode getGridNode() {
|
public IGridNode getGridNode() {
|
||||||
return nodeSupplier.get();
|
return this.nodeSupplier.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEndpointRemoved() {
|
public boolean isEndpointRemoved() {
|
||||||
var be = blockEntitySupplier.get();
|
var be = this.blockEntitySupplier.get();
|
||||||
return be == null || be.isRemoved();
|
return be == null || be.isRemoved();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package com.extendedae_plus.wireless.endpoint;
|
package com.extendedae_plus.ae.wireless.endpoint;
|
||||||
|
|
||||||
import appeng.api.networking.IGridNode;
|
import appeng.api.networking.IGridNode;
|
||||||
import appeng.helpers.InterfaceLogicHost;
|
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.core.BlockPos;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
|
@ -24,7 +24,7 @@ public class InterfaceNodeEndpointImpl implements IWirelessEndpoint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerLevel getServerLevel() {
|
public ServerLevel getServerLevel() {
|
||||||
var be = host.getBlockEntity();
|
var be = this.host.getBlockEntity();
|
||||||
if (be == null) return null;
|
if (be == null) return null;
|
||||||
Level lvl = be.getLevel();
|
Level lvl = be.getLevel();
|
||||||
return (lvl instanceof ServerLevel) ? (ServerLevel) lvl : null;
|
return (lvl instanceof ServerLevel) ? (ServerLevel) lvl : null;
|
||||||
|
|
@ -32,18 +32,18 @@ public class InterfaceNodeEndpointImpl implements IWirelessEndpoint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockPos getBlockPos() {
|
public BlockPos getBlockPos() {
|
||||||
var be = host.getBlockEntity();
|
var be = this.host.getBlockEntity();
|
||||||
return be != null ? be.getBlockPos() : BlockPos.ZERO;
|
return be != null ? be.getBlockPos() : BlockPos.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IGridNode getGridNode() {
|
public IGridNode getGridNode() {
|
||||||
return nodeSupplier.get();
|
return this.nodeSupplier.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEndpointRemoved() {
|
public boolean isEndpointRemoved() {
|
||||||
var be = host.getBlockEntity();
|
var be = this.host.getBlockEntity();
|
||||||
return be == null || be.isRemoved();
|
return be == null || be.isRemoved();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ package com.extendedae_plus.api;
|
||||||
/**
|
/**
|
||||||
* 由 {@code GuiExPatternProviderMixin} 实现,用于从通用的 Screen Mixin 中更新按钮布局。
|
* 由 {@code GuiExPatternProviderMixin} 实现,用于从通用的 Screen Mixin 中更新按钮布局。
|
||||||
*/
|
*/
|
||||||
public interface ExPatternButtonsAccessor {
|
public interface IExPatternButton {
|
||||||
/**
|
/**
|
||||||
* 在每帧调用以维护扩展样板供应器右侧按钮的可见性、重注册(窗口尺寸变化)与定位。
|
* 在每帧调用以维护扩展样板供应器右侧按钮的可见性、重注册(窗口尺寸变化)与定位。
|
||||||
*/
|
*/
|
||||||
|
|
@ -3,6 +3,6 @@ package com.extendedae_plus.api;
|
||||||
/**
|
/**
|
||||||
* 由 GuiExPatternProviderMixin 实现,用于在客户端侧提供当前页号,避免反射读取 AE2 内部字段失败。
|
* 由 GuiExPatternProviderMixin 实现,用于在客户端侧提供当前页号,避免反射读取 AE2 内部字段失败。
|
||||||
*/
|
*/
|
||||||
public interface ExPatternPageAccessor {
|
public interface IExPatternPage {
|
||||||
int eap$getCurrentPage();
|
int eap$getCurrentPage();
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.util;
|
package com.extendedae_plus.api;
|
||||||
|
|
||||||
import appeng.client.gui.style.Blitter;
|
import appeng.client.gui.style.Blitter;
|
||||||
import appeng.client.gui.style.WidgetStyle;
|
import appeng.client.gui.style.WidgetStyle;
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package com.extendedae_plus.api;
|
|
||||||
|
|
||||||
public interface PatternProviderMenuAdvancedSync {
|
|
||||||
boolean eap$getAdvancedBlockingSynced();
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package com.extendedae_plus.api;
|
|
||||||
|
|
||||||
public interface PatternProviderMenuDoublingSync {
|
|
||||||
boolean eap$getSmartDoublingSynced();
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package com.extendedae_plus.api;
|
|
||||||
|
|
||||||
public interface SmartDoublingAwarePattern {
|
|
||||||
boolean eap$allowScaling();
|
|
||||||
void eap$setAllowScaling(boolean allow);
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.extendedae_plus.api;
|
package com.extendedae_plus.api.advancedBlocking;
|
||||||
|
|
||||||
public interface AdvancedBlockingHolder {
|
public interface IAdvancedBlocking {
|
||||||
boolean eap$getAdvancedBlocking();
|
boolean eap$getAdvancedBlocking();
|
||||||
void eap$setAdvancedBlocking(boolean value);
|
void eap$setAdvancedBlocking(boolean value);
|
||||||
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.extendedae_plus.api.advancedBlocking;
|
||||||
|
|
||||||
|
public interface IPatternProviderMenuAdvancedSync {
|
||||||
|
boolean eap$getAdvancedBlockingSynced();
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.bridge;
|
package com.extendedae_plus.api.bridge;
|
||||||
|
|
||||||
import appeng.api.upgrades.IUpgradeInventory;
|
import appeng.api.upgrades.IUpgradeInventory;
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.bridge;
|
package com.extendedae_plus.api.bridge;
|
||||||
|
|
||||||
import appeng.menu.ToolboxMenu;
|
import appeng.menu.ToolboxMenu;
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.bridge;
|
package com.extendedae_plus.api.bridge;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 非 mixin 包下的桥接接口,供 mixin 进行 instanceof 检测和回调。
|
* 非 mixin 包下的桥接接口,供 mixin 进行 instanceof 检测和回调。
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.content;
|
package com.extendedae_plus.api.crafting;
|
||||||
|
|
||||||
import appeng.api.crafting.IPatternDetails;
|
import appeng.api.crafting.IPatternDetails;
|
||||||
import appeng.api.stacks.AEItemKey;
|
import appeng.api.stacks.AEItemKey;
|
||||||
|
|
@ -46,54 +46,46 @@ public final class ScaledProcessingPattern implements IPatternDetails {
|
||||||
/* -------------------- API 实现 -------------------- */
|
/* -------------------- API 实现 -------------------- */
|
||||||
|
|
||||||
public AEProcessingPattern getOriginal() {
|
public AEProcessingPattern getOriginal() {
|
||||||
return original;
|
return this.original;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AEItemKey getDefinition() {
|
public AEItemKey getDefinition() {
|
||||||
return definition;
|
return this.definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IInput[] getInputs() {
|
public IInput[] getInputs() {
|
||||||
return inputs;
|
return this.inputs;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<GenericStack> getOutputs() {
|
|
||||||
return condensedOutputs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GenericStack> getSparseInputs() {
|
|
||||||
return sparseInputs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GenericStack> getSparseOutputs() {
|
|
||||||
return sparseOutputs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GenericStack getPrimaryOutput() {
|
public GenericStack getPrimaryOutput() {
|
||||||
if (!condensedOutputs.isEmpty()) return condensedOutputs.get(0);
|
if (!this.condensedOutputs.isEmpty()) return this.condensedOutputs.get(0);
|
||||||
return original.getPrimaryOutput();
|
return this.original.getPrimaryOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GenericStack> getOutputs() {
|
||||||
|
return this.condensedOutputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsPushInputsToExternalInventory() {
|
public boolean supportsPushInputsToExternalInventory() {
|
||||||
return original.supportsPushInputsToExternalInventory();
|
return this.original.supportsPushInputsToExternalInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pushInputsToExternalInventory(KeyCounter[] inputHolder, PatternInputSink inputSink) {
|
public void pushInputsToExternalInventory(KeyCounter[] inputHolder, PatternInputSink inputSink) {
|
||||||
// 保持和 AEProcessingPattern 一致,用 sparseInputs 驱动
|
// 保持和 AEProcessingPattern 一致,用 sparseInputs 驱动
|
||||||
if (sparseInputs.size() == inputs.length) {
|
if (this.sparseInputs.size() == this.inputs.length) {
|
||||||
IPatternDetails.super.pushInputsToExternalInventory(inputHolder, inputSink);
|
IPatternDetails.super.pushInputsToExternalInventory(inputHolder, inputSink);
|
||||||
} else {
|
} else {
|
||||||
KeyCounter allInputs = new KeyCounter();
|
KeyCounter allInputs = new KeyCounter();
|
||||||
for (KeyCounter counter : inputHolder) {
|
for (KeyCounter counter : inputHolder) {
|
||||||
allInputs.addAll(counter);
|
allInputs.addAll(counter);
|
||||||
}
|
}
|
||||||
for (GenericStack sparseInput : sparseInputs) {
|
for (GenericStack sparseInput : this.sparseInputs) {
|
||||||
if (sparseInput != null) {
|
if (sparseInput != null) {
|
||||||
AEKey key = sparseInput.what();
|
AEKey key = sparseInput.what();
|
||||||
long amount = sparseInput.amount();
|
long amount = sparseInput.amount();
|
||||||
|
|
@ -109,6 +101,14 @@ public final class ScaledProcessingPattern implements IPatternDetails {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GenericStack> getSparseInputs() {
|
||||||
|
return this.sparseInputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GenericStack> getSparseOutputs() {
|
||||||
|
return this.sparseOutputs;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------- 缩放输入代理 -------------------- */
|
/* -------------------- 缩放输入代理 -------------------- */
|
||||||
|
|
||||||
public static final class Input implements IPatternDetails.IInput {
|
public static final class Input implements IPatternDetails.IInput {
|
||||||
|
|
@ -120,18 +120,22 @@ public final class ScaledProcessingPattern implements IPatternDetails {
|
||||||
this.multiplier = multiplier;
|
this.multiplier = multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public GenericStack[] getPossibleInputs() {
|
public GenericStack[] getPossibleInputs() {
|
||||||
return this.template;
|
return this.template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getMultiplier() {
|
public long getMultiplier() {
|
||||||
return this.multiplier;
|
return this.multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isValid(AEKey input, Level level) {
|
public boolean isValid(AEKey input, Level level) {
|
||||||
return input.matches(this.template[0]);
|
return input.matches(this.template[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public @Nullable AEKey getRemainingKey(AEKey template) {
|
public @Nullable AEKey getRemainingKey(AEKey template) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.extendedae_plus.api.smartDoubling;
|
||||||
|
|
||||||
|
import appeng.api.networking.IGrid;
|
||||||
|
|
||||||
|
public interface ICraftingCalculationExt {
|
||||||
|
IGrid getGrid();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.extendedae_plus.api.smartDoubling;
|
||||||
|
|
||||||
|
public interface IPatternProviderMenuDoublingSync {
|
||||||
|
boolean eap$getSmartDoublingSynced();
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.extendedae_plus.api;
|
package com.extendedae_plus.api.smartDoubling;
|
||||||
|
|
||||||
public interface SmartDoublingHolder {
|
public interface ISmartDoubling {
|
||||||
boolean eap$getSmartDoubling();
|
boolean eap$getSmartDoubling();
|
||||||
void eap$setSmartDoubling(boolean value);
|
void eap$setSmartDoubling(boolean value);
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.extendedae_plus.api.smartDoubling;
|
||||||
|
|
||||||
|
public interface ISmartDoublingAwarePattern {
|
||||||
|
boolean eap$allowScaling();
|
||||||
|
void eap$setAllowScaling(boolean allow);
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
package com.extendedae_plus.ae.api.storage;
|
package com.extendedae_plus.api.storage;
|
||||||
|
|
||||||
import appeng.api.storage.cells.ICellHandler;
|
import appeng.api.storage.cells.ICellHandler;
|
||||||
import appeng.api.storage.cells.ISaveProvider;
|
import appeng.api.storage.cells.ISaveProvider;
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem;
|
import com.extendedae_plus.items.InfinityBigIntegerCellItem;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
public class InfinityBigIntegerCellHandler implements ICellHandler {
|
public class InfinityBigIntegerCellHandler implements ICellHandler {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.ae.api.storage;
|
package com.extendedae_plus.api.storage;
|
||||||
|
|
||||||
import appeng.api.config.Actionable;
|
import appeng.api.config.Actionable;
|
||||||
import appeng.api.networking.security.IActionSource;
|
import appeng.api.networking.security.IActionSource;
|
||||||
|
|
@ -9,7 +9,7 @@ import appeng.api.storage.cells.CellState;
|
||||||
import appeng.api.storage.cells.ISaveProvider;
|
import appeng.api.storage.cells.ISaveProvider;
|
||||||
import appeng.api.storage.cells.StorageCell;
|
import appeng.api.storage.cells.StorageCell;
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem;
|
import com.extendedae_plus.items.InfinityBigIntegerCellItem;
|
||||||
import com.extendedae_plus.util.storage.InfinityConstants;
|
import com.extendedae_plus.util.storage.InfinityConstants;
|
||||||
import com.extendedae_plus.util.storage.InfinityDataStorage;
|
import com.extendedae_plus.util.storage.InfinityDataStorage;
|
||||||
import com.extendedae_plus.util.storage.InfinityStorageManager;
|
import com.extendedae_plus.util.storage.InfinityStorageManager;
|
||||||
|
|
@ -51,10 +51,10 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
private boolean isPersisted = true;
|
private boolean isPersisted = true;
|
||||||
|
|
||||||
|
|
||||||
public InfinityBigIntegerCellInventory(InfinityBigIntegerCellItem cell,
|
private InfinityBigIntegerCellInventory(InfinityBigIntegerCellItem cell,
|
||||||
ItemStack stack,
|
ItemStack stack,
|
||||||
ISaveProvider saveProvider,
|
ISaveProvider saveProvider,
|
||||||
@Nullable InfinityStorageManager storageManager) {
|
@Nullable InfinityStorageManager storageManager) {
|
||||||
// 保存存储单元类型(InfinityBigIntegerCellItem 实例),用于访问磁盘属性
|
// 保存存储单元类型(InfinityBigIntegerCellItem 实例),用于访问磁盘属性
|
||||||
this.cell = cell;
|
this.cell = cell;
|
||||||
// 保存物品堆栈,表示磁盘本身,包含运行时的 NBT 数据
|
// 保存物品堆栈,表示磁盘本身,包含运行时的 NBT 数据
|
||||||
|
|
@ -65,7 +65,7 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
this.AEKey2AmountsMap = null;
|
this.AEKey2AmountsMap = null;
|
||||||
this.storageManager = storageManager;
|
this.storageManager = storageManager;
|
||||||
// 初始化磁盘数据
|
// 初始化磁盘数据
|
||||||
initData();
|
this.initData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将 BigInteger 格式化为带单位的字符串,保留两位小数
|
// 将 BigInteger 格式化为带单位的字符串,保留两位小数
|
||||||
|
|
@ -87,9 +87,9 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 静态方法,创建存储单元库存
|
// 静态方法,创建存储单元库存
|
||||||
public static InfinityBigIntegerCellInventory createInventory(ItemStack stack,
|
static InfinityBigIntegerCellInventory createInventory(ItemStack stack,
|
||||||
ISaveProvider saveProvider,
|
ISaveProvider saveProvider,
|
||||||
@Nullable InfinityStorageManager storageManager) {
|
@Nullable InfinityStorageManager storageManager) {
|
||||||
// 检查物品堆栈是否为空
|
// 检查物品堆栈是否为空
|
||||||
Objects.requireNonNull(stack, "Cannot create cell inventory for null itemstack");
|
Objects.requireNonNull(stack, "Cannot create cell inventory for null itemstack");
|
||||||
// 检查物品是否为 IDISKCellItem 类型
|
// 检查物品是否为 IDISKCellItem 类型
|
||||||
|
|
@ -103,8 +103,8 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
// 获取磁盘的 InfinityDataStorage 数据
|
// 获取磁盘的 InfinityDataStorage 数据
|
||||||
private InfinityDataStorage getCellStorage() {
|
private InfinityDataStorage getCellStorage() {
|
||||||
// 如果磁盘有 UUID,返回对应的 InfinityDataStorage
|
// 如果磁盘有 UUID,返回对应的 InfinityDataStorage
|
||||||
if (getUUID() != null && this.storageManager != null) {
|
if (this.getUUID() != null && this.storageManager != null) {
|
||||||
return storageManager.getOrCreateCell(getUUID());
|
return this.storageManager.getOrCreateCell(this.getUUID());
|
||||||
} else {
|
} else {
|
||||||
// 否则返回空的 InfinityDataStorage
|
// 否则返回空的 InfinityDataStorage
|
||||||
return InfinityDataStorage.EMPTY;
|
return InfinityDataStorage.EMPTY;
|
||||||
|
|
@ -114,18 +114,18 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
// 初始化磁盘数据
|
// 初始化磁盘数据
|
||||||
private void initData() {
|
private void initData() {
|
||||||
// 如果磁盘有 UUID,加载存储的物品数据
|
// 如果磁盘有 UUID,加载存储的物品数据
|
||||||
if (hasUUID()) {
|
if (this.hasUUID()) {
|
||||||
this.totalAEKeyType = getCellStorage().amounts.size();
|
this.totalAEKeyType = this.getCellStorage().amounts.size();
|
||||||
this.totalAEKey2Amounts = getCellStorage().itemCount.equals(BigInteger.ZERO) ?
|
this.totalAEKey2Amounts = this.getCellStorage().itemCount.equals(BigInteger.ZERO) ?
|
||||||
BigInteger.ZERO :
|
BigInteger.ZERO :
|
||||||
getCellStorage().itemCount;
|
this.getCellStorage().itemCount;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 否则初始化为空
|
// 否则初始化为空
|
||||||
this.totalAEKeyType = 0;
|
this.totalAEKeyType = 0;
|
||||||
this.totalAEKey2Amounts = BigInteger.ZERO;
|
this.totalAEKey2Amounts = BigInteger.ZERO;
|
||||||
// 加载物品数据
|
// 加载物品数据
|
||||||
getCellStoredMap();
|
this.getCellStoredMap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,10 +153,10 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.totalAEKey2Amounts.equals(BigInteger.ZERO)) {
|
if (this.totalAEKey2Amounts.equals(BigInteger.ZERO)) {
|
||||||
if (hasUUID()) {
|
if (this.hasUUID()) {
|
||||||
this.storageManager.removeCell(getUUID());
|
this.storageManager.removeCell(this.getUUID());
|
||||||
// 从 DataComponents.CUSTOM_DATA 里移除对应字段
|
// 从 DataComponents.CUSTOM_DATA 里移除对应字段
|
||||||
CustomData data = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
||||||
CompoundTag tag = data.copyTag();
|
CompoundTag tag = data.copyTag();
|
||||||
tag.remove(InfinityConstants.INFINITY_CELL_UUID);
|
tag.remove(InfinityConstants.INFINITY_CELL_UUID);
|
||||||
tag.remove(InfinityConstants.INFINITY_ITEM_TOTAL);
|
tag.remove(InfinityConstants.INFINITY_ITEM_TOTAL);
|
||||||
|
|
@ -164,9 +164,9 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
// backward compat
|
// backward compat
|
||||||
tag.remove(InfinityConstants.INFINITY_CELL_ITEM_COUNT);
|
tag.remove(InfinityConstants.INFINITY_CELL_ITEM_COUNT);
|
||||||
|
|
||||||
self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
||||||
|
|
||||||
initData();
|
this.initData();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -192,9 +192,9 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keys.isEmpty()) {
|
if (keys.isEmpty()) {
|
||||||
this.storageManager.updateCell(getUUID(), new InfinityDataStorage());
|
this.storageManager.updateCell(this.getUUID(), new InfinityDataStorage());
|
||||||
} else {
|
} else {
|
||||||
this.storageManager.modifyDisk(getUUID(), keys, amounts, itemCount);
|
this.storageManager.modifyDisk(this.getUUID(), keys, amounts, itemCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新存储的物品种类数量
|
// 更新存储的物品种类数量
|
||||||
|
|
@ -204,23 +204,17 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
// 将物品总数与种类数量存入物品堆栈的 NBT(用于快捷查看/tooltip),同时保留旧字段以兼容历史版本
|
// 将物品总数与种类数量存入物品堆栈的 NBT(用于快捷查看/tooltip),同时保留旧字段以兼容历史版本
|
||||||
|
|
||||||
// 写回 DataComponents.CUSTOM_DATA(替代 getOrCreateTag)
|
// 写回 DataComponents.CUSTOM_DATA(替代 getOrCreateTag)
|
||||||
CompoundTag tag = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
CompoundTag tag = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
||||||
tag.putByteArray(InfinityConstants.INFINITY_ITEM_TOTAL, itemCount.toByteArray());
|
tag.putByteArray(InfinityConstants.INFINITY_ITEM_TOTAL, itemCount.toByteArray());
|
||||||
tag.putInt(InfinityConstants.INFINITY_ITEM_TYPES, this.totalAEKeyType);
|
tag.putInt(InfinityConstants.INFINITY_ITEM_TYPES, this.totalAEKeyType);
|
||||||
tag.putByteArray(InfinityConstants.INFINITY_CELL_ITEM_COUNT, itemCount.toByteArray());
|
tag.putByteArray(InfinityConstants.INFINITY_CELL_ITEM_COUNT, itemCount.toByteArray());
|
||||||
self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
||||||
// 标记数据已持久化
|
// 标记数据已持久化
|
||||||
this.isPersisted = true;
|
this.isPersisted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取存储单元的描述(此处返回null,可自定义)
|
|
||||||
@Override
|
|
||||||
public Component getDescription() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取存储的物品总数
|
// 获取存储的物品总数
|
||||||
public BigInteger getTotalAEKey2Amounts() {
|
private BigInteger getTotalAEKey2Amounts() {
|
||||||
return this.totalAEKey2Amounts;
|
return this.totalAEKey2Amounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,14 +224,14 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断物品堆栈是否有UUID
|
// 判断物品堆栈是否有UUID
|
||||||
public boolean hasUUID() {
|
private boolean hasUUID() {
|
||||||
CustomData data = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
||||||
return !data.isEmpty() && data.copyTag().contains(InfinityConstants.INFINITY_CELL_UUID);
|
return !data.isEmpty() && data.copyTag().contains(InfinityConstants.INFINITY_CELL_UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取物品堆栈的UUID
|
// 获取物品堆栈的UUID
|
||||||
public UUID getUUID() {
|
public UUID getUUID() {
|
||||||
CustomData data = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
||||||
if (!data.isEmpty() && data.copyTag().contains(InfinityConstants.INFINITY_CELL_UUID)) {
|
if (!data.isEmpty() && data.copyTag().contains(InfinityConstants.INFINITY_CELL_UUID)) {
|
||||||
return data.copyTag().getUUID(InfinityConstants.INFINITY_CELL_UUID);
|
return data.copyTag().getUUID(InfinityConstants.INFINITY_CELL_UUID);
|
||||||
}
|
}
|
||||||
|
|
@ -246,40 +240,13 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
|
|
||||||
// 获取或初始化存储映射
|
// 获取或初始化存储映射
|
||||||
private Object2ObjectMap<AEKey, BigInteger> getCellStoredMap() {
|
private Object2ObjectMap<AEKey, BigInteger> getCellStoredMap() {
|
||||||
if (AEKey2AmountsMap == null) {
|
if (this.AEKey2AmountsMap == null) {
|
||||||
AEKey2AmountsMap = new Object2ObjectOpenHashMap<>();
|
this.AEKey2AmountsMap = new Object2ObjectOpenHashMap<>();
|
||||||
this.loadCellStoredMap();
|
this.loadCellStoredMap();
|
||||||
}
|
}
|
||||||
return AEKey2AmountsMap;
|
return this.AEKey2AmountsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有可用的物品堆栈及其数量
|
|
||||||
@Override
|
|
||||||
public void getAvailableStacks(KeyCounter out) {
|
|
||||||
BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE);
|
|
||||||
if (this.getCellStoredMap() == null) return;
|
|
||||||
for (var entry : this.getCellStoredMap().object2ObjectEntrySet()) {
|
|
||||||
AEKey key = entry.getKey();
|
|
||||||
BigInteger value = entry.getValue();
|
|
||||||
|
|
||||||
// 获取 KeyCounter 中已有的值
|
|
||||||
long existing = out.get(key);
|
|
||||||
|
|
||||||
// 计算总和并限制到 Long.MAX_VALUE
|
|
||||||
BigInteger sum = BigInteger.valueOf(existing).add(value);
|
|
||||||
long toSet = sum.compareTo(maxLong) > 0 ? Long.MAX_VALUE : sum.longValue();
|
|
||||||
// 更新 KeyCounter
|
|
||||||
if (existing == Long.MAX_VALUE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
long delta = toSet - existing;
|
|
||||||
if (delta != 0) {
|
|
||||||
out.add(key, delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 从存储中加载物品映射
|
// 从存储中加载物品映射
|
||||||
private void loadCellStoredMap() {
|
private void loadCellStoredMap() {
|
||||||
if (this.storageManager == null) {
|
if (this.storageManager == null) {
|
||||||
|
|
@ -287,10 +254,10 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean dataCorruption = false;
|
boolean dataCorruption = false;
|
||||||
if (self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).isEmpty()) return;
|
if (this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).isEmpty()) return;
|
||||||
|
|
||||||
var keys = getCellStorage().keys;
|
var keys = this.getCellStorage().keys;
|
||||||
var amounts = getCellStorage().amounts;
|
var amounts = this.getCellStorage().amounts;
|
||||||
// 数据损坏
|
// 数据损坏
|
||||||
if (keys.size() != amounts.size()) {
|
if (keys.size() != amounts.size()) {
|
||||||
AELog.warn("Loading storage cell with mismatched amounts/tags: %d != %d", amounts.size(), keys.size());
|
AELog.warn("Loading storage cell with mismatched amounts/tags: %d != %d", amounts.size(), keys.size());
|
||||||
|
|
@ -306,7 +273,7 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
if (amount.compareTo(BigInteger.ZERO) <= 0 || key == null) {
|
if (amount.compareTo(BigInteger.ZERO) <= 0 || key == null) {
|
||||||
dataCorruption = true;
|
dataCorruption = true;
|
||||||
} else {
|
} else {
|
||||||
AEKey2AmountsMap.put(key, amount);
|
this.AEKey2AmountsMap.put(key, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dataCorruption) {
|
if (dataCorruption) {
|
||||||
|
|
@ -351,9 +318,9 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果没有 UUID,且服务器端存储管理器已就绪,则生成 UUID 并初始化存储
|
// 如果没有 UUID,且服务器端存储管理器已就绪,则生成 UUID 并初始化存储
|
||||||
if (storageManager != null && !this.hasUUID()) {
|
if (this.storageManager != null && !this.hasUUID()) {
|
||||||
// 取出自定义 NBT(如果没有就返回空)
|
// 取出自定义 NBT(如果没有就返回空)
|
||||||
CustomData data = self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
CustomData data = this.self.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
|
||||||
CompoundTag tag = data.copyTag();
|
CompoundTag tag = data.copyTag();
|
||||||
|
|
||||||
// 生成新的 UUID 并写入
|
// 生成新的 UUID 并写入
|
||||||
|
|
@ -361,13 +328,13 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
tag.putUUID(InfinityConstants.INFINITY_CELL_UUID, newUUID);
|
tag.putUUID(InfinityConstants.INFINITY_CELL_UUID, newUUID);
|
||||||
|
|
||||||
// 回写到 ItemStack
|
// 回写到 ItemStack
|
||||||
self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
this.self.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
||||||
|
|
||||||
// 初始化存储
|
// 初始化存储
|
||||||
this.storageManager.getOrCreateCell(newUUID);
|
this.storageManager.getOrCreateCell(newUUID);
|
||||||
|
|
||||||
// 加载已存储的映射
|
// 加载已存储的映射
|
||||||
loadCellStoredMap();
|
this.loadCellStoredMap();
|
||||||
}
|
}
|
||||||
// 获取当前物品数量
|
// 获取当前物品数量
|
||||||
BigInteger currentAmount = this.getCellStoredMap().getOrDefault(what, BigInteger.ZERO);
|
BigInteger currentAmount = this.getCellStoredMap().getOrDefault(what, BigInteger.ZERO);
|
||||||
|
|
@ -375,7 +342,7 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
if (mode == Actionable.MODULATE) {
|
if (mode == Actionable.MODULATE) {
|
||||||
// 实际插入,更新数量并保存
|
// 实际插入,更新数量并保存
|
||||||
BigInteger newAmount = currentAmount.add(BigInteger.valueOf(amount));
|
BigInteger newAmount = currentAmount.add(BigInteger.valueOf(amount));
|
||||||
getCellStoredMap().put(what, newAmount);
|
this.getCellStoredMap().put(what, newAmount);
|
||||||
this.saveChanges();
|
this.saveChanges();
|
||||||
}
|
}
|
||||||
return amount;
|
return amount;
|
||||||
|
|
@ -393,14 +360,14 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
// 如果提取数量大于等于当前数量
|
// 如果提取数量大于等于当前数量
|
||||||
if (requested.compareTo(currentAmount) >= 0) {
|
if (requested.compareTo(currentAmount) >= 0) {
|
||||||
if (mode == Actionable.MODULATE) {
|
if (mode == Actionable.MODULATE) {
|
||||||
getCellStoredMap().remove(what);
|
this.getCellStoredMap().remove(what);
|
||||||
this.saveChanges();
|
this.saveChanges();
|
||||||
}
|
}
|
||||||
return currentAmount.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0 ? Long.MAX_VALUE : currentAmount.longValue();
|
return currentAmount.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0 ? Long.MAX_VALUE : currentAmount.longValue();
|
||||||
} else {
|
} else {
|
||||||
// 提取部分数量
|
// 提取部分数量
|
||||||
if (mode == Actionable.MODULATE) {
|
if (mode == Actionable.MODULATE) {
|
||||||
getCellStoredMap().put(what, currentAmount.subtract(requested));
|
this.getCellStoredMap().put(what, currentAmount.subtract(requested));
|
||||||
this.saveChanges();
|
this.saveChanges();
|
||||||
}
|
}
|
||||||
return requested.longValue();
|
return requested.longValue();
|
||||||
|
|
@ -409,9 +376,41 @@ public class InfinityBigIntegerCellInventory implements StorageCell {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取所有可用的物品堆栈及其数量
|
||||||
|
@Override
|
||||||
|
public void getAvailableStacks(KeyCounter out) {
|
||||||
|
BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE);
|
||||||
|
if (this.getCellStoredMap() == null) return;
|
||||||
|
for (var entry : this.getCellStoredMap().object2ObjectEntrySet()) {
|
||||||
|
AEKey key = entry.getKey();
|
||||||
|
BigInteger value = entry.getValue();
|
||||||
|
|
||||||
|
// 获取 KeyCounter 中已有的值
|
||||||
|
long existing = out.get(key);
|
||||||
|
|
||||||
|
// 计算总和并限制到 Long.MAX_VALUE
|
||||||
|
BigInteger sum = BigInteger.valueOf(existing).add(value);
|
||||||
|
long toSet = sum.compareTo(maxLong) > 0 ? Long.MAX_VALUE : sum.longValue();
|
||||||
|
// 更新 KeyCounter
|
||||||
|
if (existing == Long.MAX_VALUE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
long delta = toSet - existing;
|
||||||
|
if (delta != 0) {
|
||||||
|
out.add(key, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取存储单元的描述(此处返回null,可自定义)
|
||||||
|
@Override
|
||||||
|
public Component getDescription() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取存储单元内所有物品的总数量(格式化字符串)
|
// 获取存储单元内所有物品的总数量(格式化字符串)
|
||||||
public String getTotalStorage() {
|
public String getTotalStorage() {
|
||||||
// 使用缓存的 totalStored,避免每次全表扫描
|
// 使用缓存的 totalStored,避免每次全表扫描
|
||||||
return formatBigInteger(totalAEKey2Amounts);
|
return formatBigInteger(this.totalAEKey2Amounts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,13 +3,13 @@ package com.extendedae_plus.client;
|
||||||
import appeng.client.render.crafting.CraftingCubeModel;
|
import appeng.client.render.crafting.CraftingCubeModel;
|
||||||
import appeng.init.client.InitScreens;
|
import appeng.init.client.InitScreens;
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem;
|
|
||||||
import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen;
|
import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen;
|
||||||
import com.extendedae_plus.client.render.crafting.EPlusCraftingCubeModelProvider;
|
import com.extendedae_plus.client.render.crafting.EPlusCraftingCubeModelProvider;
|
||||||
import com.extendedae_plus.content.crafting.EPlusCraftingUnitType;
|
import com.extendedae_plus.content.crafting.EPlusCraftingUnitType;
|
||||||
import com.extendedae_plus.hooks.BuiltInModelHooks;
|
import com.extendedae_plus.hooks.BuiltInModelHooks;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
import com.extendedae_plus.init.ModMenuTypes;
|
import com.extendedae_plus.init.ModMenuTypes;
|
||||||
|
import com.extendedae_plus.items.materials.EntitySpeedCardItem;
|
||||||
import net.minecraft.client.renderer.item.ItemProperties;
|
import net.minecraft.client.renderer.item.ItemProperties;
|
||||||
import net.neoforged.api.distmarker.Dist;
|
import net.neoforged.api.distmarker.Dist;
|
||||||
import net.neoforged.bus.api.SubscribeEvent;
|
import net.neoforged.bus.api.SubscribeEvent;
|
||||||
|
|
@ -21,10 +21,10 @@ import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent;
|
||||||
*/
|
*/
|
||||||
@EventBusSubscriber(modid = ExtendedAEPlus.MODID, value = Dist.CLIENT)
|
@EventBusSubscriber(modid = ExtendedAEPlus.MODID, value = Dist.CLIENT)
|
||||||
public final class ClientProxy {
|
public final class ClientProxy {
|
||||||
private ClientProxy() {}
|
|
||||||
|
|
||||||
private static boolean REGISTERED = false;
|
private static boolean REGISTERED = false;
|
||||||
|
|
||||||
|
private ClientProxy() {}
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
if (REGISTERED) return;
|
if (REGISTERED) return;
|
||||||
REGISTERED = true;
|
REGISTERED = true;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.client;
|
package com.extendedae_plus.client.event;
|
||||||
|
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
|
|
@ -1,22 +1,19 @@
|
||||||
package com.extendedae_plus;
|
package com.extendedae_plus.client.gui;
|
||||||
|
|
||||||
import appeng.client.gui.style.Blitter;
|
import appeng.client.gui.style.Blitter;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class NewIcon {
|
public class NewIcon {
|
||||||
@SuppressWarnings("all")
|
|
||||||
// 贴图当前存放于 assets/extendedae_plus/textures/gui/nicons.png
|
|
||||||
// 与 MODID (extendedaeplus) 不同,因此这里直接指定贴图所在命名空间
|
|
||||||
private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath("extendedae_plus", "textures/gui/nicons.png");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static final Blitter MULTIPLY2;
|
public static final Blitter MULTIPLY2;
|
||||||
public static final Blitter DIVIDE2;
|
public static final Blitter DIVIDE2;
|
||||||
public static final Blitter MULTIPLY5;
|
public static final Blitter MULTIPLY5;
|
||||||
public static final Blitter DIVIDE5;
|
public static final Blitter DIVIDE5;
|
||||||
public static final Blitter MULTIPLY10;
|
public static final Blitter MULTIPLY10;
|
||||||
public static final Blitter DIVIDE10;
|
public static final Blitter DIVIDE10;
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
// 贴图当前存放于 assets/extendedae_plus/textures/gui/nicons.png
|
||||||
|
// 与 MODID (extendedaeplus) 不同,因此这里直接指定贴图所在命名空间
|
||||||
|
private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath("extendedae_plus", "textures/gui/nicons.png");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
MULTIPLY2 = Blitter.texture(TEXTURE, 64, 64).src(32, 0, 16, 16);
|
MULTIPLY2 = Blitter.texture(TEXTURE, 64, 64).src(32, 0, 16, 16);
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
package com.extendedae_plus.client.gui;
|
|
||||||
|
|
||||||
public final class PageLayoutContext {
|
|
||||||
private static final ThreadLocal<Boolean> ACTIVE = ThreadLocal.withInitial(() -> false);
|
|
||||||
private static final ThreadLocal<Integer> CURRENT_PAGE = ThreadLocal.withInitial(() -> 0);
|
|
||||||
|
|
||||||
private PageLayoutContext() {}
|
|
||||||
|
|
||||||
public static void enable(int page) {
|
|
||||||
ACTIVE.set(true);
|
|
||||||
CURRENT_PAGE.set(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void disable() {
|
|
||||||
ACTIVE.set(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isActive() {
|
|
||||||
Boolean b = ACTIVE.get();
|
|
||||||
return b != null && b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getCurrentPage() {
|
|
||||||
Integer i = CURRENT_PAGE.get();
|
|
||||||
return i != null ? i : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void withPage(int page, Runnable action) {
|
|
||||||
enable(page);
|
|
||||||
try {
|
|
||||||
action.run();
|
|
||||||
} finally {
|
|
||||||
disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.client.ui;
|
package com.extendedae_plus.client.screen;
|
||||||
|
|
||||||
import com.extendedae_plus.network.SetWirelessFrequencyC2SPacket;
|
import com.extendedae_plus.network.SetWirelessFrequencyC2SPacket;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
@ -35,60 +35,17 @@ public class FrequencyInputScreen extends Screen {
|
||||||
* @param pos 无线收发器的位置
|
* @param pos 无线收发器的位置
|
||||||
* @param currentFrequency 当前频率
|
* @param currentFrequency 当前频率
|
||||||
*/
|
*/
|
||||||
public FrequencyInputScreen(BlockPos pos, long currentFrequency) {
|
private FrequencyInputScreen(BlockPos pos, long currentFrequency) {
|
||||||
super(Component.translatable("gui.extendedae_plus.frequency_input.title"));
|
super(Component.translatable("gui.extendedae_plus.frequency_input.title"));
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
this.currentFrequency = currentFrequency;
|
this.currentFrequency = currentFrequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
protected void init() {
|
* 静态工厂方法:打开频率输入界面
|
||||||
super.init();
|
*/
|
||||||
|
public static void open(BlockPos pos, long currentFrequency) {
|
||||||
// 计算居中位置
|
Minecraft.getInstance().setScreen(new FrequencyInputScreen(pos, currentFrequency));
|
||||||
int x = (this.width - WINDOW_WIDTH) / 2;
|
|
||||||
int y = (this.height - WINDOW_HEIGHT) / 2;
|
|
||||||
|
|
||||||
// 创建输入框
|
|
||||||
// API说明:EditBox构造函数参数:font, x, y, width, height, component
|
|
||||||
this.frequencyInput = new EditBox(
|
|
||||||
this.font,
|
|
||||||
x + 10,
|
|
||||||
y + 30,
|
|
||||||
WINDOW_WIDTH - 20,
|
|
||||||
20,
|
|
||||||
Component.translatable("gui.extendedae_plus.frequency_input.field")
|
|
||||||
);
|
|
||||||
|
|
||||||
// 设置输入框属性
|
|
||||||
this.frequencyInput.setMaxLength(19); // long类型最大19位数字
|
|
||||||
this.frequencyInput.setValue(String.valueOf(currentFrequency));
|
|
||||||
this.frequencyInput.setFilter(this::isValidInput); // 只允许数字和负号
|
|
||||||
this.frequencyInput.setFocused(true);
|
|
||||||
|
|
||||||
// 添加输入框到组件列表
|
|
||||||
this.addRenderableWidget(this.frequencyInput);
|
|
||||||
|
|
||||||
// 创建确认按钮
|
|
||||||
// API说明:Button.builder方法在1.21.1中使用
|
|
||||||
this.confirmButton = Button.builder(
|
|
||||||
Component.translatable("gui.extendedae_plus.frequency_input.confirm"),
|
|
||||||
button -> this.onConfirm()
|
|
||||||
)
|
|
||||||
.bounds(x + 10, y + 55, 80, 20)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
this.addRenderableWidget(this.confirmButton);
|
|
||||||
|
|
||||||
// 创建取消按钮
|
|
||||||
Button cancelButton = Button.builder(
|
|
||||||
Component.translatable("gui.extendedae_plus.frequency_input.cancel"),
|
|
||||||
button -> this.onClose()
|
|
||||||
)
|
|
||||||
.bounds(x + 110, y + 55, 80, 20)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
this.addRenderableWidget(cancelButton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -110,26 +67,6 @@ public class FrequencyInputScreen extends Screen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 按键处理:回车键确认,ESC键取消
|
|
||||||
*
|
|
||||||
* API说明:keyPressed方法在1.21.1中保持一致
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
||||||
// 回车键确认
|
|
||||||
if (keyCode == 257 || keyCode == 335) { // ENTER or NUMPAD_ENTER
|
|
||||||
this.onConfirm();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// ESC键取消
|
|
||||||
if (keyCode == 256) { // ESC
|
|
||||||
this.onClose();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染背景
|
* 渲染背景
|
||||||
*
|
*
|
||||||
|
|
@ -167,6 +104,85 @@ public class FrequencyInputScreen extends Screen {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按键处理:回车键确认,ESC键取消
|
||||||
|
*
|
||||||
|
* API说明:keyPressed方法在1.21.1中保持一致
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
|
// 回车键确认
|
||||||
|
if (keyCode == 257 || keyCode == 335) { // ENTER or NUMPAD_ENTER
|
||||||
|
this.onConfirm();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// ESC键取消
|
||||||
|
if (keyCode == 256) { // ESC
|
||||||
|
this.onClose();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
// 计算居中位置
|
||||||
|
int x = (this.width - WINDOW_WIDTH) / 2;
|
||||||
|
int y = (this.height - WINDOW_HEIGHT) / 2;
|
||||||
|
|
||||||
|
// 创建输入框
|
||||||
|
// API说明:EditBox构造函数参数:font, x, y, width, height, component
|
||||||
|
this.frequencyInput = new EditBox(
|
||||||
|
this.font,
|
||||||
|
x + 10,
|
||||||
|
y + 30,
|
||||||
|
WINDOW_WIDTH - 20,
|
||||||
|
20,
|
||||||
|
Component.translatable("gui.extendedae_plus.frequency_input.field")
|
||||||
|
);
|
||||||
|
|
||||||
|
// 设置输入框属性
|
||||||
|
this.frequencyInput.setMaxLength(19); // long类型最大19位数字
|
||||||
|
this.frequencyInput.setValue(String.valueOf(this.currentFrequency));
|
||||||
|
this.frequencyInput.setFilter(this::isValidInput); // 只允许数字和负号
|
||||||
|
this.frequencyInput.setFocused(true);
|
||||||
|
|
||||||
|
// 添加输入框到组件列表
|
||||||
|
this.addRenderableWidget(this.frequencyInput);
|
||||||
|
|
||||||
|
// 创建确认按钮
|
||||||
|
// API说明:Button.builder方法在1.21.1中使用
|
||||||
|
this.confirmButton = Button.builder(
|
||||||
|
Component.translatable("gui.extendedae_plus.frequency_input.confirm"),
|
||||||
|
button -> this.onConfirm()
|
||||||
|
)
|
||||||
|
.bounds(x + 10, y + 55, 80, 20)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.addRenderableWidget(this.confirmButton);
|
||||||
|
|
||||||
|
// 创建取消按钮
|
||||||
|
Button cancelButton = Button.builder(
|
||||||
|
Component.translatable("gui.extendedae_plus.frequency_input.cancel"),
|
||||||
|
button -> this.onClose()
|
||||||
|
)
|
||||||
|
.bounds(x + 110, y + 55, 80, 20)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.addRenderableWidget(cancelButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暂停游戏状态
|
||||||
|
* 返回false表示不暂停游戏(允许多人游戏中正常使用)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isPauseScreen() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确认按钮处理
|
* 确认按钮处理
|
||||||
*/
|
*/
|
||||||
|
|
@ -182,28 +198,12 @@ public class FrequencyInputScreen extends Screen {
|
||||||
|
|
||||||
// 发送数据包到服务端
|
// 发送数据包到服务端
|
||||||
// API说明:NeoForge使用PacketDistributor.sendToServer
|
// API说明:NeoForge使用PacketDistributor.sendToServer
|
||||||
PacketDistributor.sendToServer(new SetWirelessFrequencyC2SPacket(pos, frequency));
|
PacketDistributor.sendToServer(new SetWirelessFrequencyC2SPacket(this.pos, frequency));
|
||||||
|
|
||||||
this.onClose();
|
this.onClose();
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
// 输入无效,不做处理
|
// 输入无效,不做处理
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 暂停游戏状态
|
|
||||||
* 返回false表示不暂停游戏(允许多人游戏中正常使用)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isPauseScreen() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 静态工厂方法:打开频率输入界面
|
|
||||||
*/
|
|
||||||
public static void open(BlockPos pos, long currentFrequency) {
|
|
||||||
Minecraft.getInstance().setScreen(new FrequencyInputScreen(pos, currentFrequency));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.extendedae_plus.client.ui;
|
package com.extendedae_plus.client.screen;
|
||||||
|
|
||||||
import com.extendedae_plus.network.UploadEncodedPatternToProviderC2SPacket;
|
import com.extendedae_plus.network.UploadEncodedPatternToProviderC2SPacket;
|
||||||
|
import com.extendedae_plus.util.uploadPattern.ExtendedAEPatternUploadUtil;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.components.Button;
|
import net.minecraft.client.gui.components.Button;
|
||||||
import net.minecraft.client.gui.components.EditBox;
|
import net.minecraft.client.gui.components.EditBox;
|
||||||
|
|
@ -14,35 +15,33 @@ import java.util.*;
|
||||||
* 展示若干个可点击的供应器条目,点击后发送带 providerId 的上传请求。
|
* 展示若干个可点击的供应器条目,点击后发送带 providerId 的上传请求。
|
||||||
*/
|
*/
|
||||||
public class ProviderSelectScreen extends Screen {
|
public class ProviderSelectScreen extends Screen {
|
||||||
|
private static final int PAGE_SIZE = 6;
|
||||||
|
// 优先使用 JEC 的拼音匹配,否则回退到大小写不敏感子串匹配
|
||||||
|
private static Boolean JEC_AVAILABLE = null;
|
||||||
|
private static java.lang.reflect.Method JEC_CONTAINS = null;
|
||||||
private final Screen parent;
|
private final Screen parent;
|
||||||
// 原始数据
|
// 原始数据
|
||||||
private final List<Long> ids;
|
private final List<Long> ids;
|
||||||
private final List<String> names;
|
private final List<String> names;
|
||||||
private final List<Integer> emptySlots;
|
private final List<Integer> emptySlots;
|
||||||
|
|
||||||
// 分组后的数据(同名合并)
|
// 分组后的数据(同名合并)
|
||||||
private final List<Long> gIds = new ArrayList<>(); // 代表条目使用的 providerId:选择空位数最多的那个
|
private final List<Long> gIds = new ArrayList<>(); // 代表条目使用的 providerId:选择空位数最多的那个
|
||||||
private final List<String> gNames = new ArrayList<>(); // 分组名(供应器名称)
|
private final List<String> gNames = new ArrayList<>(); // 分组名(供应器名称)
|
||||||
private final List<Integer> gTotalSlots = new ArrayList<>(); // 该名称下供应器空位总和
|
private final List<Integer> gTotalSlots = new ArrayList<>(); // 该名称下供应器空位总和
|
||||||
private final List<Integer> gCount = new ArrayList<>(); // 该名称下供应器数量
|
private final List<Integer> gCount = new ArrayList<>(); // 该名称下供应器数量
|
||||||
|
|
||||||
// 过滤后的数据(由查询生成)
|
// 过滤后的数据(由查询生成)
|
||||||
private final List<Long> fIds = new ArrayList<>();
|
private final List<Long> fIds = new ArrayList<>();
|
||||||
private final List<String> fNames = new ArrayList<>();
|
private final List<String> fNames = new ArrayList<>();
|
||||||
private final List<Integer> fTotalSlots = new ArrayList<>();
|
private final List<Integer> fTotalSlots = new ArrayList<>();
|
||||||
private final List<Integer> fCount = new ArrayList<>();
|
private final List<Integer> fCount = new ArrayList<>();
|
||||||
|
private final List<Button> entryButtons = new ArrayList<>();
|
||||||
// 搜索框
|
// 搜索框
|
||||||
private EditBox searchBox;
|
private EditBox searchBox;
|
||||||
// 中文名输入框(用于添加映射)
|
// 中文名输入框(用于添加映射)
|
||||||
private EditBox cnInput;
|
private EditBox cnInput;
|
||||||
private String query = "";
|
private String query = "";
|
||||||
private boolean needsRefresh = false;
|
private boolean needsRefresh = false;
|
||||||
|
|
||||||
private int page = 0;
|
private int page = 0;
|
||||||
private static final int PAGE_SIZE = 6;
|
|
||||||
|
|
||||||
private final List<Button> entryButtons = new ArrayList<>();
|
|
||||||
|
|
||||||
public ProviderSelectScreen(Screen parent, List<Long> ids, List<String> names, List<Integer> emptySlots) {
|
public ProviderSelectScreen(Screen parent, List<Long> ids, List<String> names, List<Integer> emptySlots) {
|
||||||
super(Component.translatable("extendedae_plus.screen.choose_provider.title"));
|
super(Component.translatable("extendedae_plus.screen.choose_provider.title"));
|
||||||
|
|
@ -52,218 +51,17 @@ public class ProviderSelectScreen extends Screen {
|
||||||
this.emptySlots = emptySlots;
|
this.emptySlots = emptySlots;
|
||||||
// 如果有来自 JEI 的最近处理名称,则作为初始查询
|
// 如果有来自 JEI 的最近处理名称,则作为初始查询
|
||||||
try {
|
try {
|
||||||
String recent = com.extendedae_plus.util.ExtendedAEPatternUploadUtil.lastProcessingName;
|
String recent = ExtendedAEPatternUploadUtil.lastProcessingName;
|
||||||
if (recent != null && !recent.isBlank()) {
|
if (recent != null && !recent.isBlank()) {
|
||||||
this.query = recent;
|
this.query = recent;
|
||||||
// 用后即清空,避免污染下次
|
// 用后即清空,避免污染下次
|
||||||
com.extendedae_plus.util.ExtendedAEPatternUploadUtil.lastProcessingName = null;
|
ExtendedAEPatternUploadUtil.lastProcessingName = null;
|
||||||
}
|
}
|
||||||
} catch (Throwable ignored) {}
|
} catch (Throwable ignored) {}
|
||||||
buildGroups();
|
this.buildGroups();
|
||||||
applyFilter();
|
this.applyFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
this.clearWidgets();
|
|
||||||
entryButtons.clear();
|
|
||||||
|
|
||||||
int centerX = this.width / 2;
|
|
||||||
int startY = this.height / 2 - 70;
|
|
||||||
|
|
||||||
// 搜索框(置于条目上方)
|
|
||||||
if (searchBox == null) {
|
|
||||||
searchBox = new EditBox(this.font, centerX - 120, startY - 25, 240, 18, Component.translatable("extendedae_plus.screen.search"));
|
|
||||||
} else {
|
|
||||||
// 重新定位,保持输入值
|
|
||||||
searchBox.setX(centerX - 120);
|
|
||||||
searchBox.setY(startY - 25);
|
|
||||||
searchBox.setWidth(240);
|
|
||||||
}
|
|
||||||
searchBox.setValue(query);
|
|
||||||
searchBox.setResponder(text -> {
|
|
||||||
// 只有当输入真正发生变化时,才重置页码与过滤
|
|
||||||
if (Objects.equals(text, query)) return;
|
|
||||||
query = text;
|
|
||||||
page = 0;
|
|
||||||
applyFilter();
|
|
||||||
// 避免在回调中直接重建 UI,延迟到下一次 tick
|
|
||||||
needsRefresh = true;
|
|
||||||
});
|
|
||||||
this.addRenderableWidget(searchBox);
|
|
||||||
|
|
||||||
int start = page * PAGE_SIZE;
|
|
||||||
int end = Math.min(start + PAGE_SIZE, fIds.size());
|
|
||||||
|
|
||||||
int buttonWidth = 240;
|
|
||||||
int buttonHeight = 20;
|
|
||||||
int gap = 5;
|
|
||||||
|
|
||||||
for (int i = start; i < end; i++) {
|
|
||||||
int idx = i;
|
|
||||||
String label = buildLabel(idx);
|
|
||||||
Button btn = Button.builder(Component.literal(label), b -> onChoose(idx))
|
|
||||||
.bounds(centerX - buttonWidth / 2, startY + (i - start) * (buttonHeight + gap), buttonWidth, buttonHeight)
|
|
||||||
.build();
|
|
||||||
entryButtons.add(btn);
|
|
||||||
this.addRenderableWidget(btn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分页按钮
|
|
||||||
int navY = startY + PAGE_SIZE * (buttonHeight + gap) + 10;
|
|
||||||
Button prev = Button.builder(Component.literal("<"), b -> changePage(-1))
|
|
||||||
.bounds(centerX - 60, navY, 20, 20)
|
|
||||||
.build();
|
|
||||||
Button next = Button.builder(Component.literal(">"), b -> changePage(1))
|
|
||||||
.bounds(centerX + 40, navY, 20, 20)
|
|
||||||
.build();
|
|
||||||
prev.active = page > 0;
|
|
||||||
next.active = (page + 1) * PAGE_SIZE < fIds.size();
|
|
||||||
this.addRenderableWidget(prev);
|
|
||||||
this.addRenderableWidget(next);
|
|
||||||
|
|
||||||
// 重载映射按钮(热重载 recipe_type_names.json)——移至下一行,与关闭按钮并排
|
|
||||||
Button reload = Button.builder(Component.translatable("extendedae_plus.screen.reload_mapping"), b -> reloadMapping())
|
|
||||||
.bounds(centerX - 130, navY + 30, 80, 20)
|
|
||||||
.build();
|
|
||||||
this.addRenderableWidget(reload);
|
|
||||||
|
|
||||||
// 中文名输入框(用于新增映射的值)
|
|
||||||
if (cnInput == null) {
|
|
||||||
cnInput = new EditBox(this.font, centerX + 50, navY + 30, 120, 20, Component.translatable("extendedae_plus.screen.cn_name"));
|
|
||||||
} else {
|
|
||||||
cnInput.setX(centerX + 50);
|
|
||||||
cnInput.setY(navY + 30);
|
|
||||||
cnInput.setWidth(120);
|
|
||||||
}
|
|
||||||
this.addRenderableWidget(cnInput);
|
|
||||||
|
|
||||||
// 增加映射按钮(使用当前搜索关键字 -> 中文)
|
|
||||||
Button addMap = Button.builder(Component.translatable("extendedae_plus.screen.add_mapping"), b -> addMappingFromUI())
|
|
||||||
.bounds(centerX + 175, navY + 30, 60, 20)
|
|
||||||
.build();
|
|
||||||
this.addRenderableWidget(addMap);
|
|
||||||
|
|
||||||
// 删除映射(按中文值精确匹配删除)按钮
|
|
||||||
Button delByCn = Button.builder(Component.literal("删除映射"), b -> deleteMappingByCnFromUI())
|
|
||||||
.bounds(centerX + 240, navY + 30, 60, 20)
|
|
||||||
.build();
|
|
||||||
this.addRenderableWidget(delByCn);
|
|
||||||
|
|
||||||
// 关闭按钮
|
|
||||||
Button close = Button.builder(Component.translatable("gui.cancel"), b -> onClose())
|
|
||||||
.bounds(centerX - 40, navY + 30, 80, 20)
|
|
||||||
.build();
|
|
||||||
this.addRenderableWidget(close);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void changePage(int delta) {
|
|
||||||
int newPage = page + delta;
|
|
||||||
if (newPage < 0) return;
|
|
||||||
if (newPage * PAGE_SIZE >= fIds.size()) return;
|
|
||||||
page = newPage;
|
|
||||||
// 避免在回调中直接重建 UI,改为下帧刷新
|
|
||||||
needsRefresh = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reloadMapping() {
|
|
||||||
try {
|
|
||||||
com.extendedae_plus.util.ExtendedAEPatternUploadUtil.loadRecipeTypeNames();
|
|
||||||
var player = Minecraft.getInstance().player;
|
|
||||||
if (player != null) {
|
|
||||||
player.sendSystemMessage(Component.literal("ExtendedAE Plus: 已重载映射表"));
|
|
||||||
}
|
|
||||||
// 重载后不强制刷新筛选,但如需立即应用到名称匹配,可手动编辑搜索框或翻页
|
|
||||||
} catch (Throwable t) {
|
|
||||||
var player = Minecraft.getInstance().player;
|
|
||||||
if (player != null) {
|
|
||||||
player.sendSystemMessage(Component.literal("ExtendedAE Plus: 重载映射表失败: " + t.getClass().getSimpleName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String buildLabel(int idx) {
|
|
||||||
String name = fNames.get(idx);
|
|
||||||
int totalSlots = fTotalSlots.get(idx);
|
|
||||||
int count = fCount.get(idx);
|
|
||||||
// 不显示具体 id,显示合并统计:名称(总空位)x数量
|
|
||||||
return name + " (" + totalSlots + ") x" + count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onChoose(int idx) {
|
|
||||||
if (idx < 0 || idx >= fIds.size()) return;
|
|
||||||
long providerId = fIds.get(idx);
|
|
||||||
var conn = Minecraft.getInstance().getConnection();
|
|
||||||
if (conn != null) {
|
|
||||||
conn.send(new UploadEncodedPatternToProviderC2SPacket(providerId));
|
|
||||||
}
|
|
||||||
this.onClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClose() {
|
|
||||||
Minecraft.getInstance().setScreen(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPauseScreen() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildGroups() {
|
|
||||||
// 使用 LinkedHashMap 保持首次出现顺序
|
|
||||||
Map<String, Group> map = new LinkedHashMap<>();
|
|
||||||
for (int i = 0; i < names.size(); i++) {
|
|
||||||
String name = names.get(i);
|
|
||||||
long id = ids.get(i);
|
|
||||||
int slots = emptySlots.get(i);
|
|
||||||
Group g = map.computeIfAbsent(name, k -> new Group());
|
|
||||||
g.count++;
|
|
||||||
g.totalSlots += Math.max(0, slots);
|
|
||||||
// 挑选空位最多的作为代表 id;若并列,保留先到者
|
|
||||||
if (slots > g.bestSlots) {
|
|
||||||
g.bestSlots = slots;
|
|
||||||
g.bestId = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Map.Entry<String, Group> e : map.entrySet()) {
|
|
||||||
String name = e.getKey();
|
|
||||||
Group g = e.getValue();
|
|
||||||
gNames.add(name);
|
|
||||||
gIds.add(g.bestId);
|
|
||||||
gTotalSlots.add(g.totalSlots);
|
|
||||||
gCount.add(g.count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Group {
|
|
||||||
long bestId = Long.MIN_VALUE;
|
|
||||||
int bestSlots = Integer.MIN_VALUE;
|
|
||||||
int totalSlots = 0;
|
|
||||||
int count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyFilter() {
|
|
||||||
fIds.clear();
|
|
||||||
fNames.clear();
|
|
||||||
fTotalSlots.clear();
|
|
||||||
fCount.clear();
|
|
||||||
String q = query == null ? "" : query.trim();
|
|
||||||
for (int i = 0; i < gIds.size(); i++) {
|
|
||||||
String name = gNames.get(i);
|
|
||||||
if (q.isEmpty() || nameMatches(name, q)) {
|
|
||||||
fIds.add(gIds.get(i));
|
|
||||||
fNames.add(name);
|
|
||||||
fTotalSlots.add(gTotalSlots.get(i));
|
|
||||||
fCount.add(gCount.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 优先使用 JEC 的拼音匹配,否则回退到大小写不敏感子串匹配
|
|
||||||
private static Boolean JEC_AVAILABLE = null;
|
|
||||||
private static java.lang.reflect.Method JEC_CONTAINS = null;
|
|
||||||
|
|
||||||
private static boolean nameMatches(String name, String key) {
|
private static boolean nameMatches(String name, String key) {
|
||||||
if (name == null) return false;
|
if (name == null) return false;
|
||||||
if (key == null || key.isEmpty()) return true;
|
if (key == null || key.isEmpty()) return true;
|
||||||
|
|
@ -294,20 +92,212 @@ public class ProviderSelectScreen extends Screen {
|
||||||
return name.toLowerCase().contains(key.toLowerCase());
|
return name.toLowerCase().contains(key.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void changePage(int delta) {
|
||||||
|
int newPage = this.page + delta;
|
||||||
|
if (newPage < 0) return;
|
||||||
|
if (newPage * PAGE_SIZE >= this.fIds.size()) return;
|
||||||
|
this.page = newPage;
|
||||||
|
// 避免在回调中直接重建 UI,改为下帧刷新
|
||||||
|
this.needsRefresh = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reloadMapping() {
|
||||||
|
try {
|
||||||
|
ExtendedAEPatternUploadUtil.loadRecipeTypeNames();
|
||||||
|
var player = Minecraft.getInstance().player;
|
||||||
|
if (player != null) {
|
||||||
|
player.sendSystemMessage(Component.literal("ExtendedAE Plus: 已重载映射表"));
|
||||||
|
}
|
||||||
|
// 重载后不强制刷新筛选,但如需立即应用到名称匹配,可手动编辑搜索框或翻页
|
||||||
|
} catch (Throwable t) {
|
||||||
|
var player = Minecraft.getInstance().player;
|
||||||
|
if (player != null) {
|
||||||
|
player.sendSystemMessage(Component.literal("ExtendedAE Plus: 重载映射表失败: " + t.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildLabel(int idx) {
|
||||||
|
String name = this.fNames.get(idx);
|
||||||
|
int totalSlots = this.fTotalSlots.get(idx);
|
||||||
|
int count = this.fCount.get(idx);
|
||||||
|
// 不显示具体 id,显示合并统计:名称(总空位)x数量
|
||||||
|
return name + " (" + totalSlots + ") x" + count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onChoose(int idx) {
|
||||||
|
if (idx < 0 || idx >= this.fIds.size()) return;
|
||||||
|
long providerId = this.fIds.get(idx);
|
||||||
|
var conn = Minecraft.getInstance().getConnection();
|
||||||
|
if (conn != null) {
|
||||||
|
conn.send(new UploadEncodedPatternToProviderC2SPacket(providerId));
|
||||||
|
}
|
||||||
|
this.onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildGroups() {
|
||||||
|
// 使用 LinkedHashMap 保持首次出现顺序
|
||||||
|
Map<String, Group> map = new LinkedHashMap<>();
|
||||||
|
for (int i = 0; i < this.names.size(); i++) {
|
||||||
|
String name = this.names.get(i);
|
||||||
|
long id = this.ids.get(i);
|
||||||
|
int slots = this.emptySlots.get(i);
|
||||||
|
Group g = map.computeIfAbsent(name, k -> new Group());
|
||||||
|
g.count++;
|
||||||
|
g.totalSlots += Math.max(0, slots);
|
||||||
|
// 挑选空位最多的作为代表 id;若并列,保留先到者
|
||||||
|
if (slots > g.bestSlots) {
|
||||||
|
g.bestSlots = slots;
|
||||||
|
g.bestId = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, Group> e : map.entrySet()) {
|
||||||
|
String name = e.getKey();
|
||||||
|
Group g = e.getValue();
|
||||||
|
this.gNames.add(name);
|
||||||
|
this.gIds.add(g.bestId);
|
||||||
|
this.gTotalSlots.add(g.totalSlots);
|
||||||
|
this.gCount.add(g.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyFilter() {
|
||||||
|
this.fIds.clear();
|
||||||
|
this.fNames.clear();
|
||||||
|
this.fTotalSlots.clear();
|
||||||
|
this.fCount.clear();
|
||||||
|
String q = this.query == null ? "" : this.query.trim();
|
||||||
|
for (int i = 0; i < this.gIds.size(); i++) {
|
||||||
|
String name = this.gNames.get(i);
|
||||||
|
if (q.isEmpty() || nameMatches(name, q)) {
|
||||||
|
this.fIds.add(this.gIds.get(i));
|
||||||
|
this.fNames.add(name);
|
||||||
|
this.fTotalSlots.add(this.gTotalSlots.get(i));
|
||||||
|
this.fCount.add(this.gCount.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||||
if (searchBox != null && searchBox.keyPressed(keyCode, scanCode, modifiers)) {
|
if (this.searchBox != null && this.searchBox.keyPressed(keyCode, scanCode, modifiers)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean charTyped(char codePoint, int modifiers) {
|
public void onClose() {
|
||||||
if (searchBox != null && searchBox.charTyped(codePoint, modifiers)) {
|
Minecraft.getInstance().setScreen(this.parent);
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
this.clearWidgets();
|
||||||
|
this.entryButtons.clear();
|
||||||
|
|
||||||
|
int centerX = this.width / 2;
|
||||||
|
int startY = this.height / 2 - 70;
|
||||||
|
|
||||||
|
// 搜索框(置于条目上方)
|
||||||
|
if (this.searchBox == null) {
|
||||||
|
this.searchBox = new EditBox(this.font, centerX - 120, startY - 25, 240, 18, Component.translatable("extendedae_plus.screen.search"));
|
||||||
|
} else {
|
||||||
|
// 重新定位,保持输入值
|
||||||
|
this.searchBox.setX(centerX - 120);
|
||||||
|
this.searchBox.setY(startY - 25);
|
||||||
|
this.searchBox.setWidth(240);
|
||||||
}
|
}
|
||||||
return super.charTyped(codePoint, modifiers);
|
this.searchBox.setValue(this.query);
|
||||||
|
this.searchBox.setResponder(text -> {
|
||||||
|
// 只有当输入真正发生变化时,才重置页码与过滤
|
||||||
|
if (Objects.equals(text, this.query)) return;
|
||||||
|
this.query = text;
|
||||||
|
this.page = 0;
|
||||||
|
this.applyFilter();
|
||||||
|
// 避免在回调中直接重建 UI,延迟到下一次 tick
|
||||||
|
this.needsRefresh = true;
|
||||||
|
});
|
||||||
|
this.addRenderableWidget(this.searchBox);
|
||||||
|
|
||||||
|
int start = this.page * PAGE_SIZE;
|
||||||
|
int end = Math.min(start + PAGE_SIZE, this.fIds.size());
|
||||||
|
|
||||||
|
int buttonWidth = 240;
|
||||||
|
int buttonHeight = 20;
|
||||||
|
int gap = 5;
|
||||||
|
|
||||||
|
for (int i = start; i < end; i++) {
|
||||||
|
int idx = i;
|
||||||
|
String label = this.buildLabel(idx);
|
||||||
|
Button btn = Button.builder(Component.literal(label), b -> this.onChoose(idx))
|
||||||
|
.bounds(centerX - buttonWidth / 2, startY + (i - start) * (buttonHeight + gap), buttonWidth, buttonHeight)
|
||||||
|
.build();
|
||||||
|
this.entryButtons.add(btn);
|
||||||
|
this.addRenderableWidget(btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页按钮
|
||||||
|
int navY = startY + PAGE_SIZE * (buttonHeight + gap) + 10;
|
||||||
|
Button prev = Button.builder(Component.literal("<"), b -> this.changePage(-1))
|
||||||
|
.bounds(centerX - 60, navY, 20, 20)
|
||||||
|
.build();
|
||||||
|
Button next = Button.builder(Component.literal(">"), b -> this.changePage(1))
|
||||||
|
.bounds(centerX + 40, navY, 20, 20)
|
||||||
|
.build();
|
||||||
|
prev.active = this.page > 0;
|
||||||
|
next.active = (this.page + 1) * PAGE_SIZE < this.fIds.size();
|
||||||
|
this.addRenderableWidget(prev);
|
||||||
|
this.addRenderableWidget(next);
|
||||||
|
|
||||||
|
// 重载映射按钮(热重载 recipe_type_names.json)——移至下一行,与关闭按钮并排
|
||||||
|
Button reload = Button.builder(Component.translatable("extendedae_plus.screen.reload_mapping"), b -> this.reloadMapping())
|
||||||
|
.bounds(centerX - 130, navY + 30, 80, 20)
|
||||||
|
.build();
|
||||||
|
this.addRenderableWidget(reload);
|
||||||
|
|
||||||
|
// 中文名输入框(用于新增映射的值)
|
||||||
|
if (this.cnInput == null) {
|
||||||
|
this.cnInput = new EditBox(this.font, centerX + 50, navY + 30, 120, 20, Component.translatable("extendedae_plus.screen.cn_name"));
|
||||||
|
} else {
|
||||||
|
this.cnInput.setX(centerX + 50);
|
||||||
|
this.cnInput.setY(navY + 30);
|
||||||
|
this.cnInput.setWidth(120);
|
||||||
|
}
|
||||||
|
this.addRenderableWidget(this.cnInput);
|
||||||
|
|
||||||
|
// 增加映射按钮(使用当前搜索关键字 -> 中文)
|
||||||
|
Button addMap = Button.builder(Component.translatable("extendedae_plus.screen.add_mapping"), b -> this.addMappingFromUI())
|
||||||
|
.bounds(centerX + 175, navY + 30, 60, 20)
|
||||||
|
.build();
|
||||||
|
this.addRenderableWidget(addMap);
|
||||||
|
|
||||||
|
// 删除映射(按中文值精确匹配删除)按钮
|
||||||
|
Button delByCn = Button.builder(Component.literal("删除映射"), b -> this.deleteMappingByCnFromUI())
|
||||||
|
.bounds(centerX + 240, navY + 30, 60, 20)
|
||||||
|
.build();
|
||||||
|
this.addRenderableWidget(delByCn);
|
||||||
|
|
||||||
|
// 关闭按钮
|
||||||
|
Button close = Button.builder(Component.translatable("gui.cancel"), b -> this.onClose())
|
||||||
|
.bounds(centerX - 40, navY + 30, 80, 20)
|
||||||
|
.build();
|
||||||
|
this.addRenderableWidget(close);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
if (this.needsRefresh) {
|
||||||
|
this.needsRefresh = false;
|
||||||
|
// 重新构建当前屏幕内容
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPauseScreen() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -324,7 +314,7 @@ public class ProviderSelectScreen extends Screen {
|
||||||
}
|
}
|
||||||
this.query = "";
|
this.query = "";
|
||||||
this.page = 0;
|
this.page = 0;
|
||||||
applyFilter();
|
this.applyFilter();
|
||||||
this.needsRefresh = true;
|
this.needsRefresh = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -333,18 +323,16 @@ public class ProviderSelectScreen extends Screen {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public boolean charTyped(char codePoint, int modifiers) {
|
||||||
super.tick();
|
if (this.searchBox != null && this.searchBox.charTyped(codePoint, modifiers)) {
|
||||||
if (needsRefresh) {
|
return true;
|
||||||
needsRefresh = false;
|
|
||||||
// 重新构建当前屏幕内容
|
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
return super.charTyped(codePoint, modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMappingFromUI() {
|
private void addMappingFromUI() {
|
||||||
String key = query == null ? "" : query.trim();
|
String key = this.query == null ? "" : this.query.trim();
|
||||||
String val = cnInput == null ? "" : cnInput.getValue().trim();
|
String val = this.cnInput == null ? "" : this.cnInput.getValue().trim();
|
||||||
var player = Minecraft.getInstance().player;
|
var player = Minecraft.getInstance().player;
|
||||||
if (key.isEmpty()) {
|
if (key.isEmpty()) {
|
||||||
if (player != null) player.sendSystemMessage(Component.literal("请输入搜索关键字后再添加映射"));
|
if (player != null) player.sendSystemMessage(Component.literal("请输入搜索关键字后再添加映射"));
|
||||||
|
|
@ -354,7 +342,7 @@ public class ProviderSelectScreen extends Screen {
|
||||||
if (player != null) player.sendSystemMessage(Component.literal("请输入中文名称"));
|
if (player != null) player.sendSystemMessage(Component.literal("请输入中文名称"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean ok = com.extendedae_plus.util.ExtendedAEPatternUploadUtil.addOrUpdateAliasMapping(key, val);
|
boolean ok = ExtendedAEPatternUploadUtil.addOrUpdateAliasMapping(key, val);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
if (player != null) player.sendSystemMessage(Component.literal("已添加/更新映射: " + key + " -> " + val));
|
if (player != null) player.sendSystemMessage(Component.literal("已添加/更新映射: " + key + " -> " + val));
|
||||||
// 将刚添加的中文名写入搜索框,作为当前查询
|
// 将刚添加的中文名写入搜索框,作为当前查询
|
||||||
|
|
@ -363,10 +351,10 @@ public class ProviderSelectScreen extends Screen {
|
||||||
this.searchBox.setValue(val);
|
this.searchBox.setValue(val);
|
||||||
}
|
}
|
||||||
// 更新本地过滤显示(若名称包含中文可被搜索)
|
// 更新本地过滤显示(若名称包含中文可被搜索)
|
||||||
applyFilter();
|
this.applyFilter();
|
||||||
// 回到第一页以展示最新筛选结果
|
// 回到第一页以展示最新筛选结果
|
||||||
page = 0;
|
this.page = 0;
|
||||||
needsRefresh = true;
|
this.needsRefresh = true;
|
||||||
} else {
|
} else {
|
||||||
if (player != null) player.sendSystemMessage(Component.literal("写入映射失败"));
|
if (player != null) player.sendSystemMessage(Component.literal("写入映射失败"));
|
||||||
}
|
}
|
||||||
|
|
@ -374,19 +362,26 @@ public class ProviderSelectScreen extends Screen {
|
||||||
|
|
||||||
// 使用中文值精确匹配删除映射
|
// 使用中文值精确匹配删除映射
|
||||||
private void deleteMappingByCnFromUI() {
|
private void deleteMappingByCnFromUI() {
|
||||||
String val = cnInput == null ? "" : cnInput.getValue().trim();
|
String val = this.cnInput == null ? "" : this.cnInput.getValue().trim();
|
||||||
var player = Minecraft.getInstance().player;
|
var player = Minecraft.getInstance().player;
|
||||||
if (val.isEmpty()) {
|
if (val.isEmpty()) {
|
||||||
if (player != null) player.sendSystemMessage(Component.literal("请输入中文名称后再删除映射"));
|
if (player != null) player.sendSystemMessage(Component.literal("请输入中文名称后再删除映射"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int removed = com.extendedae_plus.util.ExtendedAEPatternUploadUtil.removeMappingsByCnValue(val);
|
int removed = ExtendedAEPatternUploadUtil.removeMappingsByCnValue(val);
|
||||||
if (removed > 0) {
|
if (removed > 0) {
|
||||||
if (player != null) player.sendSystemMessage(Component.literal("已删除 " + removed + " 条映射,中文= " + val));
|
if (player != null) player.sendSystemMessage(Component.literal("已删除 " + removed + " 条映射,中文= " + val));
|
||||||
applyFilter();
|
this.applyFilter();
|
||||||
needsRefresh = true;
|
this.needsRefresh = true;
|
||||||
} else {
|
} else {
|
||||||
if (player != null) player.sendSystemMessage(Component.literal("未找到中文为 '" + val + "' 的映射"));
|
if (player != null) player.sendSystemMessage(Component.literal("未找到中文为 '" + val + "' 的映射"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class Group {
|
||||||
|
long bestId = Long.MIN_VALUE;
|
||||||
|
int bestSlots = Integer.MIN_VALUE;
|
||||||
|
int totalSlots = 0;
|
||||||
|
int count = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package com.extendedae_plus.content.wireless;
|
package com.extendedae_plus.content.wireless;
|
||||||
|
|
||||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
|
||||||
import com.extendedae_plus.init.ModBlockEntities;
|
import com.extendedae_plus.init.ModBlockEntities;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
|
import com.extendedae_plus.items.materials.ChannelCardItem;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
|
|
@ -34,6 +34,14 @@ public class WirelessTransceiverBlock extends Block implements EntityBlock {
|
||||||
return new WirelessTransceiverBlockEntity(pos, state);
|
return new WirelessTransceiverBlockEntity(pos, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
|
||||||
|
if (level.isClientSide) return null;
|
||||||
|
return type == ModBlockEntities.WIRELESS_TRANSCEIVER_BE.get()
|
||||||
|
? (lvl, pos, st, be) -> WirelessTransceiverBlockEntity.serverTick(lvl, pos, st, (WirelessTransceiverBlockEntity) be)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
||||||
super.setPlacedBy(level, pos, state, placer, stack);
|
super.setPlacedBy(level, pos, state, placer, stack);
|
||||||
|
|
@ -45,41 +53,6 @@ public class WirelessTransceiverBlock extends Block implements EntityBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void attack(BlockState state, Level level, BlockPos pos, Player player) {
|
|
||||||
if (!level.isClientSide) {
|
|
||||||
BlockEntity be = level.getBlockEntity(pos);
|
|
||||||
if (be instanceof WirelessTransceiverBlockEntity te) {
|
|
||||||
ItemStack mainHand = player.getMainHandItem();
|
|
||||||
|
|
||||||
// 潜行左键频道卡:写入频道卡信息到收发器
|
|
||||||
if (player.isShiftKeyDown() && mainHand.getItem() == ModItems.CHANNEL_CARD.get()) {
|
|
||||||
handleChannelCardBinding(te, mainHand, player);
|
|
||||||
super.attack(state, level, pos, player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 潜行左键(其他物品):减频(-1 或 -10)
|
|
||||||
if (player.isShiftKeyDown()) {
|
|
||||||
if (te.isLocked()) {
|
|
||||||
player.displayClientMessage(Component.literal("收发器已锁定,无法修改频道"), true);
|
|
||||||
super.attack(state, level, pos, player);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int step = 1;
|
|
||||||
if (mainHand.is(Items.REDSTONE_TORCH)) step = 10;
|
|
||||||
if (mainHand.is(Items.STICK)) step = 10;
|
|
||||||
long f = te.getFrequency();
|
|
||||||
f -= step;
|
|
||||||
if (f < 0) f = 0;
|
|
||||||
te.setFrequency(f);
|
|
||||||
player.displayClientMessage(Component.literal("频道:" + te.getFrequency()), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.attack(state, level, pos, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理频道卡绑定到收发器
|
* 处理频道卡绑定到收发器
|
||||||
*/
|
*/
|
||||||
|
|
@ -101,6 +74,54 @@ public class WirelessTransceiverBlock extends Block implements EntityBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
|
if (!state.is(newState.getBlock())) {
|
||||||
|
BlockEntity be = level.getBlockEntity(pos);
|
||||||
|
if (be instanceof WirelessTransceiverBlockEntity te) {
|
||||||
|
te.onRemoved();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onRemove(state, level, pos, newState, isMoving);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) {
|
||||||
|
BlockEntity be = level.getBlockEntity(pos);
|
||||||
|
if (!(be instanceof WirelessTransceiverBlockEntity te)) {
|
||||||
|
return InteractionResult.PASS;
|
||||||
|
}
|
||||||
|
boolean sneaking = player.isShiftKeyDown();
|
||||||
|
if (sneaking) {
|
||||||
|
if (te.isLocked()) {
|
||||||
|
if (!level.isClientSide) {
|
||||||
|
player.displayClientMessage(Component.literal("收发器已锁定,无法修改频道"), true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
long f = te.getFrequency();
|
||||||
|
// 空手交互:按主手逻辑 +1
|
||||||
|
f += 1;
|
||||||
|
te.setFrequency(f);
|
||||||
|
if (!level.isClientSide) {
|
||||||
|
player.displayClientMessage(Component.literal("频道:" + te.getFrequency()), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||||
|
} else {
|
||||||
|
if (te.isLocked()) {
|
||||||
|
if (!level.isClientSide) {
|
||||||
|
player.displayClientMessage(Component.literal("收发器已锁定,无法切换模式"), true);
|
||||||
|
}
|
||||||
|
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||||
|
}
|
||||||
|
te.setMasterMode(!te.isMasterMode());
|
||||||
|
if (!level.isClientSide) {
|
||||||
|
player.displayClientMessage(Component.literal(te.isMasterMode() ? "模式:主端" : "模式:从端"), true);
|
||||||
|
}
|
||||||
|
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 1.21+: 拆分为 useItemOn 与 useWithoutItem
|
// 1.21+: 拆分为 useItemOn 与 useWithoutItem
|
||||||
@Override
|
@Override
|
||||||
protected ItemInteractionResult useItemOn(net.minecraft.world.item.ItemStack heldItem, BlockState state, Level level, BlockPos pos,
|
protected ItemInteractionResult useItemOn(net.minecraft.world.item.ItemStack heldItem, BlockState state, Level level, BlockPos pos,
|
||||||
|
|
@ -150,58 +171,37 @@ public class WirelessTransceiverBlock extends Block implements EntityBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) {
|
public void attack(BlockState state, Level level, BlockPos pos, Player player) {
|
||||||
BlockEntity be = level.getBlockEntity(pos);
|
if (!level.isClientSide) {
|
||||||
if (!(be instanceof WirelessTransceiverBlockEntity te)) {
|
BlockEntity be = level.getBlockEntity(pos);
|
||||||
return InteractionResult.PASS;
|
if (be instanceof WirelessTransceiverBlockEntity te) {
|
||||||
}
|
ItemStack mainHand = player.getMainHandItem();
|
||||||
boolean sneaking = player.isShiftKeyDown();
|
|
||||||
if (sneaking) {
|
// 潜行左键频道卡:写入频道卡信息到收发器
|
||||||
if (te.isLocked()) {
|
if (player.isShiftKeyDown() && mainHand.getItem() == ModItems.CHANNEL_CARD.get()) {
|
||||||
if (!level.isClientSide) {
|
this.handleChannelCardBinding(te, mainHand, player);
|
||||||
player.displayClientMessage(Component.literal("收发器已锁定,无法修改频道"), true);
|
super.attack(state, level, pos, player);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
long f = te.getFrequency();
|
// 潜行左键(其他物品):减频(-1 或 -10)
|
||||||
// 空手交互:按主手逻辑 +1
|
if (player.isShiftKeyDown()) {
|
||||||
f += 1;
|
if (te.isLocked()) {
|
||||||
te.setFrequency(f);
|
player.displayClientMessage(Component.literal("收发器已锁定,无法修改频道"), true);
|
||||||
if (!level.isClientSide) {
|
super.attack(state, level, pos, player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int step = 1;
|
||||||
|
if (mainHand.is(Items.REDSTONE_TORCH)) step = 10;
|
||||||
|
if (mainHand.is(Items.STICK)) step = 10;
|
||||||
|
long f = te.getFrequency();
|
||||||
|
f -= step;
|
||||||
|
if (f < 0) f = 0;
|
||||||
|
te.setFrequency(f);
|
||||||
player.displayClientMessage(Component.literal("频道:" + te.getFrequency()), true);
|
player.displayClientMessage(Component.literal("频道:" + te.getFrequency()), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
|
||||||
} else {
|
|
||||||
if (te.isLocked()) {
|
|
||||||
if (!level.isClientSide) {
|
|
||||||
player.displayClientMessage(Component.literal("收发器已锁定,无法切换模式"), true);
|
|
||||||
}
|
|
||||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
|
||||||
}
|
|
||||||
te.setMasterMode(!te.isMasterMode());
|
|
||||||
if (!level.isClientSide) {
|
|
||||||
player.displayClientMessage(Component.literal(te.isMasterMode() ? "模式:主端" : "模式:从端"), true);
|
|
||||||
}
|
|
||||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
|
||||||
}
|
}
|
||||||
}
|
super.attack(state, level, pos, player);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
|
|
||||||
if (!state.is(newState.getBlock())) {
|
|
||||||
BlockEntity be = level.getBlockEntity(pos);
|
|
||||||
if (be instanceof WirelessTransceiverBlockEntity te) {
|
|
||||||
te.onRemoved();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.onRemove(state, level, pos, newState, isMoving);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
|
|
||||||
if (level.isClientSide) return null;
|
|
||||||
return type == ModBlockEntities.WIRELESS_TRANSCEIVER_BE.get()
|
|
||||||
? (lvl, pos, st, be) -> WirelessTransceiverBlockEntity.serverTick(lvl, pos, st, (WirelessTransceiverBlockEntity) be)
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ package com.extendedae_plus.content.wireless;
|
||||||
import appeng.api.networking.*;
|
import appeng.api.networking.*;
|
||||||
import appeng.api.util.AECableType;
|
import appeng.api.util.AECableType;
|
||||||
import appeng.blockentity.AEBaseBlockEntity;
|
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.ModBlockEntities;
|
||||||
import com.extendedae_plus.init.ModItems;
|
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.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.HolderLookup;
|
import net.minecraft.core.HolderLookup;
|
||||||
|
|
@ -60,6 +60,21 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements
|
||||||
this.slaveLink = new WirelessSlaveLink(this);
|
this.slaveLink = new WirelessSlaveLink(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===================== Tick ===================== */
|
||||||
|
static void serverTick(Level level, BlockPos pos, BlockState state, WirelessTransceiverBlockEntity be) {
|
||||||
|
if (!(level instanceof ServerLevel)) return;
|
||||||
|
if (!be.masterMode) {
|
||||||
|
// 从端需要周期检查与维护连接
|
||||||
|
be.slaveLink.updateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================== IInWorldGridNodeHost ===================== */
|
||||||
|
@Override
|
||||||
|
public @Nullable IGridNode getGridNode(Direction dir) {
|
||||||
|
return this.getGridNode();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AECableType getCableConnectionType(Direction dir) {
|
public AECableType getCableConnectionType(Direction dir) {
|
||||||
// 根据相邻方块的实际连接类型渲染(优先采用相邻主机返回的类型),回退为 GLASS。
|
// 根据相邻方块的实际连接类型渲染(优先采用相邻主机返回的类型),回退为 GLASS。
|
||||||
|
|
@ -74,12 +89,6 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements
|
||||||
return AECableType.GLASS;
|
return AECableType.GLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===================== IInWorldGridNodeHost ===================== */
|
|
||||||
@Override
|
|
||||||
public @Nullable IGridNode getGridNode(Direction dir) {
|
|
||||||
return getGridNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===================== IWirelessEndpoint ===================== */
|
/* ===================== IWirelessEndpoint ===================== */
|
||||||
@Override
|
@Override
|
||||||
public ServerLevel getServerLevel() {
|
public ServerLevel getServerLevel() {
|
||||||
|
|
@ -87,14 +96,9 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements
|
||||||
return lvl instanceof ServerLevel sl ? sl : null;
|
return lvl instanceof ServerLevel sl ? sl : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos getBlockPos() {
|
|
||||||
return this.worldPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IGridNode getGridNode() {
|
public IGridNode getGridNode() {
|
||||||
return managedNode == null ? null : managedNode.getNode();
|
return this.managedNode == null ? null : this.managedNode.getNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -104,56 +108,61 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements
|
||||||
|
|
||||||
/* ===================== 公共方法(交互调用) ===================== */
|
/* ===================== 公共方法(交互调用) ===================== */
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getBlockPos() {
|
||||||
|
return this.worldPosition;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置放置者UUID和名称(在方块放置时调用)
|
* 设置放置者UUID和名称(在方块放置时调用)
|
||||||
*/
|
*/
|
||||||
public void setPlacerId(@Nullable UUID placerId, @Nullable String placerName) {
|
void setPlacerId(@Nullable UUID placerId, @Nullable String placerName) {
|
||||||
if (this.placerId != null && !this.placerId.equals(placerId)) {
|
if (this.placerId != null && !this.placerId.equals(placerId)) {
|
||||||
// 如果所有者改变,需要重新注册
|
// 如果所有者改变,需要重新注册
|
||||||
if (this.masterMode) {
|
if (this.masterMode) {
|
||||||
masterLink.onUnloadOrRemove();
|
this.masterLink.onUnloadOrRemove();
|
||||||
} else {
|
} else {
|
||||||
slaveLink.onUnloadOrRemove();
|
this.slaveLink.onUnloadOrRemove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.placerId = placerId;
|
this.placerId = placerId;
|
||||||
this.placerName = placerName;
|
this.placerName = placerName;
|
||||||
this.masterLink.setPlacerId(placerId);
|
this.masterLink.setPlacerId(placerId);
|
||||||
this.slaveLink.setPlacerId(placerId);
|
this.slaveLink.setPlacerId(placerId);
|
||||||
setChanged();
|
this.setChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public UUID getPlacerId() {
|
||||||
|
return this.placerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 仅设置UUID(兼容旧代码)
|
* 仅设置UUID(兼容旧代码)
|
||||||
*/
|
*/
|
||||||
public void setPlacerId(@Nullable UUID placerId) {
|
public void setPlacerId(@Nullable UUID placerId) {
|
||||||
setPlacerId(placerId, null);
|
this.setPlacerId(placerId, null);
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public UUID getPlacerId() {
|
|
||||||
return placerId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getPlacerName() {
|
public String getPlacerName() {
|
||||||
return placerName;
|
return this.placerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFrequency() {
|
public long getFrequency() {
|
||||||
return frequency;
|
return this.frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFrequency(long frequency) {
|
public void setFrequency(long frequency) {
|
||||||
if (this.locked) return;
|
if (this.locked) return;
|
||||||
if (this.frequency == frequency) return;
|
if (this.frequency == frequency) return;
|
||||||
this.frequency = frequency;
|
this.frequency = frequency;
|
||||||
if (isMasterMode()) {
|
if (this.isMasterMode()) {
|
||||||
masterLink.setFrequency(frequency);
|
this.masterLink.setFrequency(frequency);
|
||||||
} else {
|
} else {
|
||||||
slaveLink.setFrequency(frequency);
|
this.slaveLink.setFrequency(frequency);
|
||||||
}
|
}
|
||||||
setChanged();
|
this.setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -163,64 +172,55 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements
|
||||||
public void setFrequencyForced(long frequency) {
|
public void setFrequencyForced(long frequency) {
|
||||||
if (this.frequency == frequency) return;
|
if (this.frequency == frequency) return;
|
||||||
this.frequency = frequency;
|
this.frequency = frequency;
|
||||||
if (isMasterMode()) {
|
if (this.isMasterMode()) {
|
||||||
masterLink.setFrequency(frequency);
|
this.masterLink.setFrequency(frequency);
|
||||||
} else {
|
} else {
|
||||||
slaveLink.setFrequency(frequency);
|
this.slaveLink.setFrequency(frequency);
|
||||||
}
|
}
|
||||||
setChanged();
|
this.setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMasterMode() {
|
public boolean isMasterMode() {
|
||||||
return masterMode;
|
return this.masterMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMasterMode(boolean masterMode) {
|
void setMasterMode(boolean masterMode) {
|
||||||
if (this.locked) return;
|
if (this.locked) return;
|
||||||
if (this.masterMode == masterMode) return;
|
if (this.masterMode == masterMode) return;
|
||||||
// 切换前清理原模式状态
|
// 切换前清理原模式状态
|
||||||
if (this.masterMode) {
|
if (this.masterMode) {
|
||||||
masterLink.onUnloadOrRemove();
|
this.masterLink.onUnloadOrRemove();
|
||||||
} else {
|
} else {
|
||||||
slaveLink.onUnloadOrRemove();
|
this.slaveLink.onUnloadOrRemove();
|
||||||
}
|
}
|
||||||
this.masterMode = masterMode;
|
this.masterMode = masterMode;
|
||||||
// 切换后应用频率
|
// 切换后应用频率
|
||||||
if (this.masterMode) {
|
if (this.masterMode) {
|
||||||
masterLink.setFrequency(frequency);
|
this.masterLink.setFrequency(this.frequency);
|
||||||
} else {
|
} else {
|
||||||
slaveLink.setFrequency(frequency);
|
this.slaveLink.setFrequency(this.frequency);
|
||||||
}
|
}
|
||||||
setChanged();
|
this.setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLocked() {
|
public boolean isLocked() {
|
||||||
return locked;
|
return this.locked;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocked(boolean locked) {
|
public void setLocked(boolean locked) {
|
||||||
if (this.locked == locked) return;
|
if (this.locked == locked) return;
|
||||||
this.locked = locked;
|
this.locked = locked;
|
||||||
setChanged();
|
this.setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRemoved() {
|
void onRemoved() {
|
||||||
if (this.masterMode) {
|
if (this.masterMode) {
|
||||||
masterLink.onUnloadOrRemove();
|
this.masterLink.onUnloadOrRemove();
|
||||||
} else {
|
} else {
|
||||||
slaveLink.onUnloadOrRemove();
|
this.slaveLink.onUnloadOrRemove();
|
||||||
}
|
}
|
||||||
if (managedNode != null) {
|
if (this.managedNode != null) {
|
||||||
managedNode.destroy();
|
this.managedNode.destroy();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===================== Tick ===================== */
|
|
||||||
public static void serverTick(Level level, BlockPos pos, BlockState state, WirelessTransceiverBlockEntity be) {
|
|
||||||
if (!(level instanceof ServerLevel)) return;
|
|
||||||
if (!be.masterMode) {
|
|
||||||
// 从端需要周期检查与维护连接
|
|
||||||
be.slaveLink.updateStatus();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,7 +228,7 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
super.onLoad();
|
super.onLoad();
|
||||||
// 仅服务端创建节点
|
// 仅服务端创建节点
|
||||||
ServerLevel sl = getServerLevel();
|
ServerLevel sl = this.getServerLevel();
|
||||||
if (sl == null) return;
|
if (sl == null) return;
|
||||||
// 在首个 tick 创建,以保证区块已就绪
|
// 在首个 tick 创建,以保证区块已就绪
|
||||||
GridHelper.onFirstTick(this, be -> {
|
GridHelper.onFirstTick(this, be -> {
|
||||||
|
|
@ -244,24 +244,6 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===================== NBT ===================== */
|
|
||||||
@Override
|
|
||||||
public void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
|
|
||||||
super.saveAdditional(tag, registries);
|
|
||||||
tag.putLong("frequency", frequency);
|
|
||||||
tag.putBoolean("master", masterMode);
|
|
||||||
tag.putBoolean("locked", locked);
|
|
||||||
if (placerId != null) {
|
|
||||||
tag.putUUID("placerId", placerId);
|
|
||||||
}
|
|
||||||
if (placerName != null) {
|
|
||||||
tag.putString("placerName", placerName);
|
|
||||||
}
|
|
||||||
if (managedNode != null) {
|
|
||||||
managedNode.saveToNBT(tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadTag(CompoundTag tag, HolderLookup.Provider registries) {
|
public void loadTag(CompoundTag tag, HolderLookup.Provider registries) {
|
||||||
super.loadTag(tag, registries);
|
super.loadTag(tag, registries);
|
||||||
|
|
@ -279,14 +261,32 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements
|
||||||
this.placerName = tag.getString("placerName");
|
this.placerName = tag.getString("placerName");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (managedNode != null) {
|
if (this.managedNode != null) {
|
||||||
managedNode.loadFromNBT(tag);
|
this.managedNode.loadFromNBT(tag);
|
||||||
}
|
}
|
||||||
// 应用到链接器
|
// 应用到链接器
|
||||||
if (masterMode) {
|
if (this.masterMode) {
|
||||||
masterLink.setFrequency(frequency);
|
this.masterLink.setFrequency(this.frequency);
|
||||||
} else {
|
} else {
|
||||||
slaveLink.setFrequency(frequency);
|
this.slaveLink.setFrequency(this.frequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================== NBT ===================== */
|
||||||
|
@Override
|
||||||
|
public void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
|
||||||
|
super.saveAdditional(tag, registries);
|
||||||
|
tag.putLong("frequency", this.frequency);
|
||||||
|
tag.putBoolean("master", this.masterMode);
|
||||||
|
tag.putBoolean("locked", this.locked);
|
||||||
|
if (this.placerId != null) {
|
||||||
|
tag.putUUID("placerId", this.placerId);
|
||||||
|
}
|
||||||
|
if (this.placerName != null) {
|
||||||
|
tag.putString("placerName", this.placerName);
|
||||||
|
}
|
||||||
|
if (this.managedNode != null) {
|
||||||
|
this.managedNode.saveToNBT(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,15 +297,19 @@ public class WirelessTransceiverBlockEntity extends AEBaseBlockEntity implements
|
||||||
public void onSaveChanges(WirelessTransceiverBlockEntity host, IGridNode node) {
|
public void onSaveChanges(WirelessTransceiverBlockEntity host, IGridNode node) {
|
||||||
host.setChanged();
|
host.setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInWorldConnectionChanged(WirelessTransceiverBlockEntity host, IGridNode node) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOwnerChanged(WirelessTransceiverBlockEntity host, IGridNode node) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGridChanged(WirelessTransceiverBlockEntity host, IGridNode node) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStateChanged(WirelessTransceiverBlockEntity host, IGridNode node, State state) {
|
public void onStateChanged(WirelessTransceiverBlockEntity host, IGridNode node, State state) {
|
||||||
// 可在此响应 POWER/CHANNEL 等变化,刷新显示等
|
// 可在此响应 POWER/CHANNEL 等变化,刷新显示等
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public void onInWorldConnectionChanged(WirelessTransceiverBlockEntity host, IGridNode node) {}
|
|
||||||
@Override
|
|
||||||
public void onGridChanged(WirelessTransceiverBlockEntity host, IGridNode node) {}
|
|
||||||
@Override
|
|
||||||
public void onOwnerChanged(WirelessTransceiverBlockEntity host, IGridNode node) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
package com.extendedae_plus.hooks;
|
package com.extendedae_plus.hooks;
|
||||||
|
|
||||||
|
import appeng.block.crafting.CraftingUnitBlock;
|
||||||
import appeng.util.InteractionUtil;
|
import appeng.util.InteractionUtil;
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.client.ui.FrequencyInputScreen;
|
import com.extendedae_plus.client.screen.FrequencyInputScreen;
|
||||||
import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity;
|
import com.extendedae_plus.content.wireless.WirelessTransceiverBlockEntity;
|
||||||
import appeng.block.crafting.CraftingUnitBlock;
|
|
||||||
import appeng.blockentity.crafting.CraftingBlockEntity;
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.sounds.SoundSource;
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
|
@ -15,8 +14,6 @@ import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.neoforged.api.distmarker.Dist;
|
|
||||||
import net.neoforged.bus.api.Event;
|
|
||||||
import net.neoforged.bus.api.SubscribeEvent;
|
import net.neoforged.bus.api.SubscribeEvent;
|
||||||
import net.neoforged.fml.common.EventBusSubscriber;
|
import net.neoforged.fml.common.EventBusSubscriber;
|
||||||
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package com.extendedae_plus.init;
|
package com.extendedae_plus.init;
|
||||||
|
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem;
|
import com.extendedae_plus.items.EntitySpeedTickerPartItem;
|
||||||
import com.extendedae_plus.ae.items.EntitySpeedTickerPartItem;
|
import com.extendedae_plus.items.InfinityBigIntegerCellItem;
|
||||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
import com.extendedae_plus.items.materials.ChannelCardItem;
|
||||||
import com.extendedae_plus.ae.items.InfinityBigIntegerCellItem;
|
import com.extendedae_plus.items.materials.EntitySpeedCardItem;
|
||||||
import com.extendedae_plus.ae.items.VirtualCraftingCardItem;
|
import com.extendedae_plus.items.materials.VirtualCraftingCardItem;
|
||||||
import net.minecraft.world.item.BlockItem;
|
import net.minecraft.world.item.BlockItem;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
@ -13,84 +13,71 @@ import net.neoforged.neoforge.registries.DeferredItem;
|
||||||
import net.neoforged.neoforge.registries.DeferredRegister;
|
import net.neoforged.neoforge.registries.DeferredRegister;
|
||||||
|
|
||||||
public final class ModItems {
|
public final class ModItems {
|
||||||
private ModItems() {}
|
|
||||||
|
|
||||||
public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(ExtendedAEPlus.MODID);
|
public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(ExtendedAEPlus.MODID);
|
||||||
|
|
||||||
public static final DeferredItem<Item> WIRELESS_TRANSCEIVER = ITEMS.register(
|
public static final DeferredItem<Item> WIRELESS_TRANSCEIVER = ITEMS.register(
|
||||||
"wireless_transceiver",
|
"wireless_transceiver",
|
||||||
() -> new BlockItem(ModBlocks.WIRELESS_TRANSCEIVER.get(), new Item.Properties())
|
() -> new BlockItem(ModBlocks.WIRELESS_TRANSCEIVER.get(), new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredItem<Item> NETWORK_PATTERN_CONTROLLER = ITEMS.register(
|
|
||||||
"network_pattern_controller",
|
|
||||||
() -> new BlockItem(ModBlocks.NETWORK_PATTERN_CONTROLLER.get(), new Item.Properties())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Crafting Accelerators
|
// Crafting Accelerators
|
||||||
public static final DeferredItem<Item> ACCELERATOR_4x = ITEMS.register(
|
public static final DeferredItem<Item> ACCELERATOR_4x = ITEMS.register(
|
||||||
"4x_crafting_accelerator",
|
"4x_crafting_accelerator",
|
||||||
() -> new BlockItem(ModBlocks.ACCELERATOR_4x.get(), new Item.Properties())
|
() -> new BlockItem(ModBlocks.ACCELERATOR_4x.get(), new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredItem<Item> ACCELERATOR_16x = ITEMS.register(
|
public static final DeferredItem<Item> ACCELERATOR_16x = ITEMS.register(
|
||||||
"16x_crafting_accelerator",
|
"16x_crafting_accelerator",
|
||||||
() -> new BlockItem(ModBlocks.ACCELERATOR_16x.get(), new Item.Properties())
|
() -> new BlockItem(ModBlocks.ACCELERATOR_16x.get(), new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredItem<Item> ACCELERATOR_64x = ITEMS.register(
|
public static final DeferredItem<Item> ACCELERATOR_64x = ITEMS.register(
|
||||||
"64x_crafting_accelerator",
|
"64x_crafting_accelerator",
|
||||||
() -> new BlockItem(ModBlocks.ACCELERATOR_64x.get(), new Item.Properties())
|
() -> new BlockItem(ModBlocks.ACCELERATOR_64x.get(), new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredItem<Item> ACCELERATOR_256x = ITEMS.register(
|
public static final DeferredItem<Item> ACCELERATOR_256x = ITEMS.register(
|
||||||
"256x_crafting_accelerator",
|
"256x_crafting_accelerator",
|
||||||
() -> new BlockItem(ModBlocks.ACCELERATOR_256x.get(), new Item.Properties())
|
() -> new BlockItem(ModBlocks.ACCELERATOR_256x.get(), new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredItem<Item> ACCELERATOR_1024x = ITEMS.register(
|
public static final DeferredItem<Item> ACCELERATOR_1024x = ITEMS.register(
|
||||||
"1024x_crafting_accelerator",
|
"1024x_crafting_accelerator",
|
||||||
() -> new BlockItem(ModBlocks.ACCELERATOR_1024x.get(), new Item.Properties())
|
() -> new BlockItem(ModBlocks.ACCELERATOR_1024x.get(), new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredItem<EntitySpeedTickerPartItem> ENTITY_TICKER_PART_ITEM = ITEMS.register(
|
public static final DeferredItem<EntitySpeedTickerPartItem> ENTITY_TICKER_PART_ITEM = ITEMS.register(
|
||||||
"entity_speed_ticker",
|
"entity_speed_ticker",
|
||||||
() -> new EntitySpeedTickerPartItem(new Item.Properties())
|
() -> new EntitySpeedTickerPartItem(new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
// AE Upgrade Cards: 实体加速卡(四个等级:x2,x4,x8,x16)
|
// AE Upgrade Cards: 实体加速卡(四个等级:x2,x4,x8,x16)
|
||||||
// 单一实体加速卡 Item(不同等级由 ItemStack.nbt 存储)
|
// 单一实体加速卡 Item(不同等级由 ItemStack.nbt 存储)
|
||||||
public static final DeferredItem<EntitySpeedCardItem> ENTITY_SPEED_CARD = ITEMS.register(
|
public static final DeferredItem<EntitySpeedCardItem> ENTITY_SPEED_CARD = ITEMS.register(
|
||||||
"entity_speed_card",
|
"entity_speed_card",
|
||||||
() -> new EntitySpeedCardItem(new Item.Properties())
|
() -> new EntitySpeedCardItem(new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
// 频道卡:用于AE机器的无线频道连接
|
// 频道卡:用于AE机器的无线频道连接
|
||||||
public static final DeferredItem<ChannelCardItem> CHANNEL_CARD = ITEMS.register(
|
public static final DeferredItem<ChannelCardItem> CHANNEL_CARD = ITEMS.register(
|
||||||
"channel_card",
|
"channel_card",
|
||||||
() -> new ChannelCardItem(new Item.Properties())
|
() -> new ChannelCardItem(new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredItem<VirtualCraftingCardItem> VIRTUAL_CRAFTING_CARD = ITEMS.register(
|
public static final DeferredItem<VirtualCraftingCardItem> VIRTUAL_CRAFTING_CARD = ITEMS.register(
|
||||||
"virtual_crafting_card",
|
"virtual_crafting_card",
|
||||||
() -> new VirtualCraftingCardItem(new Item.Properties())
|
() -> new VirtualCraftingCardItem(new Item.Properties())
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredItem<Item> INFINITY_BIGINTEGER_CELL_ITEM = ITEMS.register(
|
|
||||||
"infinity_biginteger_cell", InfinityBigIntegerCellItem::new
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 工厂:创建带 multiplier 的实体加速卡 ItemStack(2/4/8/16)
|
|
||||||
*/
|
|
||||||
public static ItemStack createEntitySpeedCardStack(byte multiplier) {
|
|
||||||
return EntitySpeedCardItem.withMultiplier(multiplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 装配矩阵上传核心物品
|
// 装配矩阵上传核心物品
|
||||||
public static final DeferredItem<Item> ASSEMBLER_MATRIX_UPLOAD_CORE = ITEMS.register(
|
public static final DeferredItem<Item> ASSEMBLER_MATRIX_UPLOAD_CORE = ITEMS.register(
|
||||||
"assembler_matrix_upload_core",
|
"assembler_matrix_upload_core",
|
||||||
() -> new BlockItem(ModBlocks.ASSEMBLER_MATRIX_UPLOAD_CORE.get(), new Item.Properties())
|
() -> new BlockItem(ModBlocks.ASSEMBLER_MATRIX_UPLOAD_CORE.get(), new Item.Properties())
|
||||||
);
|
);
|
||||||
|
static final DeferredItem<Item> NETWORK_PATTERN_CONTROLLER = ITEMS.register(
|
||||||
|
"network_pattern_controller",
|
||||||
|
() -> new BlockItem(ModBlocks.NETWORK_PATTERN_CONTROLLER.get(), new Item.Properties())
|
||||||
|
);
|
||||||
|
static final DeferredItem<Item> INFINITY_BIGINTEGER_CELL_ITEM = ITEMS.register(
|
||||||
|
"infinity_biginteger_cell", InfinityBigIntegerCellItem::new
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private ModItems() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工厂:创建带 multiplier 的实体加速卡 ItemStack(2/4/8/16)
|
||||||
|
*/
|
||||||
|
static ItemStack createEntitySpeedCardStack(byte multiplier) {
|
||||||
|
return EntitySpeedCardItem.withMultiplier(multiplier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,10 @@ package com.extendedae_plus.integration.jade;
|
||||||
|
|
||||||
import appeng.api.networking.IGrid;
|
import appeng.api.networking.IGrid;
|
||||||
import appeng.api.networking.IGridNode;
|
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.content.wireless.WirelessTransceiverBlockEntity;
|
||||||
import com.extendedae_plus.wireless.IWirelessEndpoint;
|
import com.extendedae_plus.util.wireless.WirelessTeamUtil;
|
||||||
import com.extendedae_plus.wireless.WirelessMasterRegistry;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
|
@ -37,7 +38,7 @@ public enum WirelessTransceiverProvider implements IServerDataProvider<BlockAcce
|
||||||
var level = blockEntity.getServerLevel();
|
var level = blockEntity.getServerLevel();
|
||||||
if (level != null) {
|
if (level != null) {
|
||||||
// 使用WirelessTeamUtil自动判断显示团队或玩家名称
|
// 使用WirelessTeamUtil自动判断显示团队或玩家名称
|
||||||
Component ownerName = com.extendedae_plus.util.WirelessTeamUtil.getNetworkOwnerName(level, placerId);
|
Component ownerName = WirelessTeamUtil.getNetworkOwnerName(level, placerId);
|
||||||
data.putString("ownerName", ownerName.getString());
|
data.putString("ownerName", ownerName.getString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.extendedae_plus.integration.jei;
|
package com.extendedae_plus.integration.jei;
|
||||||
|
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem;
|
import com.extendedae_plus.items.materials.EntitySpeedCardItem;
|
||||||
import mezz.jei.api.IModPlugin;
|
import mezz.jei.api.IModPlugin;
|
||||||
import mezz.jei.api.JeiPlugin;
|
import mezz.jei.api.JeiPlugin;
|
||||||
import mezz.jei.api.constants.VanillaTypes;
|
import mezz.jei.api.constants.VanillaTypes;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.ae.items;
|
package com.extendedae_plus.items;
|
||||||
|
|
||||||
import appeng.items.parts.PartItem;
|
import appeng.items.parts.PartItem;
|
||||||
import com.extendedae_plus.ae.parts.EntitySpeedTickerPart;
|
import com.extendedae_plus.ae.parts.EntitySpeedTickerPart;
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package com.extendedae_plus.ae.items;
|
package com.extendedae_plus.items;
|
||||||
|
|
||||||
import appeng.api.config.FuzzyMode;
|
import appeng.api.config.FuzzyMode;
|
||||||
import appeng.api.storage.cells.ICellWorkbenchItem;
|
import appeng.api.storage.cells.ICellWorkbenchItem;
|
||||||
import com.extendedae_plus.ae.api.storage.InfinityBigIntegerCellInventory;
|
import com.extendedae_plus.api.storage.InfinityBigIntegerCellInventory;
|
||||||
import com.extendedae_plus.util.storage.InfinityConstants;
|
import com.extendedae_plus.util.storage.InfinityConstants;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
package com.extendedae_plus.ae.items;
|
package com.extendedae_plus.items.materials;
|
||||||
|
|
||||||
import appeng.items.materials.UpgradeCardItem;
|
import appeng.items.materials.UpgradeCardItem;
|
||||||
import com.extendedae_plus.util.WirelessTeamUtil;
|
|
||||||
import net.minecraft.core.component.DataComponents;
|
import net.minecraft.core.component.DataComponents;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.item.component.CustomData;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.TooltipFlag;
|
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResultHolder;
|
import net.minecraft.world.InteractionResultHolder;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.TooltipFlag;
|
||||||
|
import net.minecraft.world.item.component.CustomData;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
|
@ -28,15 +26,15 @@ import java.util.UUID;
|
||||||
* 继承 AE2 的 UpgradeCardItem 以复用升级卡判定与提示框架。
|
* 继承 AE2 的 UpgradeCardItem 以复用升级卡判定与提示框架。
|
||||||
*/
|
*/
|
||||||
public class ChannelCardItem extends UpgradeCardItem {
|
public class ChannelCardItem extends UpgradeCardItem {
|
||||||
public static final String TAG_CHANNEL = "channel";
|
private static final String TAG_CHANNEL = "channel";
|
||||||
public static final String TAG_OWNER_UUID = "ownerUUID";
|
private static final String TAG_OWNER_UUID = "ownerUUID";
|
||||||
public static final String TAG_TEAM_NAME = "teamName"; // 用于显示
|
private static final String TAG_TEAM_NAME = "teamName"; // 用于显示
|
||||||
|
|
||||||
public ChannelCardItem(Item.Properties properties) {
|
public ChannelCardItem(Item.Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setChannel(ItemStack stack, long channel) {
|
private static void setChannel(ItemStack stack, long channel) {
|
||||||
CompoundTag tag = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
CompoundTag tag = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
|
||||||
tag.putLong(TAG_CHANNEL, channel);
|
tag.putLong(TAG_CHANNEL, channel);
|
||||||
stack.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
stack.set(DataComponents.CUSTOM_DATA, CustomData.of(tag));
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.ae.definitions.upgrades;
|
package com.extendedae_plus.items.materials;
|
||||||
|
|
||||||
import appeng.items.materials.UpgradeCardItem;
|
import appeng.items.materials.UpgradeCardItem;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
|
|
@ -19,7 +19,7 @@ import java.util.List;
|
||||||
* 单一的实体加速卡 Item,通过 ItemStack 的 NBT 存储 exponent(0/1/2/3)来区分等级
|
* 单一的实体加速卡 Item,通过 ItemStack 的 NBT 存储 exponent(0/1/2/3)来区分等级
|
||||||
*/
|
*/
|
||||||
public class EntitySpeedCardItem extends UpgradeCardItem {
|
public class EntitySpeedCardItem extends UpgradeCardItem {
|
||||||
public static final String NBT_MULTIPLIER = "EAS:mult";
|
private static final String NBT_MULTIPLIER = "EAS:mult";
|
||||||
|
|
||||||
public EntitySpeedCardItem(Properties props) {
|
public EntitySpeedCardItem(Properties props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
@ -55,7 +55,7 @@ public class EntitySpeedCardItem extends UpgradeCardItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<Component> getTooltipLines(ItemStack stack) {
|
private List<Component> getTooltipLines(ItemStack stack) {
|
||||||
byte mult = readMultiplier(stack);
|
byte mult = readMultiplier(stack);
|
||||||
int cap = 1;
|
int cap = 1;
|
||||||
switch (mult) {
|
switch (mult) {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.ae.items;
|
package com.extendedae_plus.items.materials;
|
||||||
|
|
||||||
import appeng.items.materials.UpgradeCardItem;
|
import appeng.items.materials.UpgradeCardItem;
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.extendedae_plus.mixin.advancedae;
|
package com.extendedae_plus.mixin.advancedae;
|
||||||
|
|
||||||
import appeng.api.crafting.IPatternDetails;
|
import appeng.api.crafting.IPatternDetails;
|
||||||
import com.extendedae_plus.content.ScaledProcessingPattern;
|
import com.extendedae_plus.api.crafting.ScaledProcessingPattern;
|
||||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import appeng.api.config.YesNo;
|
||||||
import appeng.client.gui.AEBaseScreen;
|
import appeng.client.gui.AEBaseScreen;
|
||||||
import appeng.client.gui.style.ScreenStyle;
|
import appeng.client.gui.style.ScreenStyle;
|
||||||
import appeng.client.gui.widgets.SettingToggleButton;
|
import appeng.client.gui.widgets.SettingToggleButton;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuAdvancedSync;
|
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuDoublingSync;
|
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
|
||||||
import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket;
|
import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket;
|
||||||
import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket;
|
import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
@ -50,7 +50,7 @@ public abstract class AdvPatternProviderScreenMixin extends AEBaseScreen<AdvPatt
|
||||||
private void eap$initAdvancedBlocking(AdvPatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
private void eap$initAdvancedBlocking(AdvPatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
||||||
// 使用 @GuiSync 初始化
|
// 使用 @GuiSync 初始化
|
||||||
try {
|
try {
|
||||||
if (menu instanceof PatternProviderMenuAdvancedSync sync) {
|
if (menu instanceof IPatternProviderMenuAdvancedSync sync) {
|
||||||
this.eap$AdvancedBlockingEnabled = sync.eap$getAdvancedBlockingSynced();
|
this.eap$AdvancedBlockingEnabled = sync.eap$getAdvancedBlockingSynced();
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
@ -84,7 +84,7 @@ public abstract class AdvPatternProviderScreenMixin extends AEBaseScreen<AdvPatt
|
||||||
|
|
||||||
// 智能翻倍按钮:与高级阻挡同款样式,点击仅发送C2S,状态由@GuiSync驱动
|
// 智能翻倍按钮:与高级阻挡同款样式,点击仅发送C2S,状态由@GuiSync驱动
|
||||||
try {
|
try {
|
||||||
if (menu instanceof PatternProviderMenuDoublingSync sync2) {
|
if (menu instanceof IPatternProviderMenuDoublingSync sync2) {
|
||||||
this.eap$SmartDoublingEnabled = sync2.eap$getSmartDoublingSynced();
|
this.eap$SmartDoublingEnabled = sync2.eap$getSmartDoublingSynced();
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
@ -119,7 +119,7 @@ public abstract class AdvPatternProviderScreenMixin extends AEBaseScreen<AdvPatt
|
||||||
private void eap$updateAdvancedBlocking(CallbackInfo ci) {
|
private void eap$updateAdvancedBlocking(CallbackInfo ci) {
|
||||||
if (this.eap$AdvancedBlockingToggle != null) {
|
if (this.eap$AdvancedBlockingToggle != null) {
|
||||||
boolean desired = this.eap$AdvancedBlockingEnabled;
|
boolean desired = this.eap$AdvancedBlockingEnabled;
|
||||||
if (this.menu instanceof PatternProviderMenuAdvancedSync sync) {
|
if (this.menu instanceof IPatternProviderMenuAdvancedSync sync) {
|
||||||
desired = sync.eap$getAdvancedBlockingSynced();
|
desired = sync.eap$getAdvancedBlockingSynced();
|
||||||
}
|
}
|
||||||
this.eap$AdvancedBlockingEnabled = desired;
|
this.eap$AdvancedBlockingEnabled = desired;
|
||||||
|
|
@ -128,7 +128,7 @@ public abstract class AdvPatternProviderScreenMixin extends AEBaseScreen<AdvPatt
|
||||||
|
|
||||||
if (this.eap$SmartDoublingToggle != null) {
|
if (this.eap$SmartDoublingToggle != null) {
|
||||||
boolean desired2 = this.eap$SmartDoublingEnabled;
|
boolean desired2 = this.eap$SmartDoublingEnabled;
|
||||||
if (this.menu instanceof PatternProviderMenuDoublingSync sync2) {
|
if (this.menu instanceof IPatternProviderMenuDoublingSync sync2) {
|
||||||
desired2 = sync2.eap$getSmartDoublingSynced();
|
desired2 = sync2.eap$getSmartDoublingSynced();
|
||||||
}
|
}
|
||||||
this.eap$SmartDoublingEnabled = desired2;
|
this.eap$SmartDoublingEnabled = desired2;
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import appeng.api.config.YesNo;
|
||||||
import appeng.client.gui.AEBaseScreen;
|
import appeng.client.gui.AEBaseScreen;
|
||||||
import appeng.client.gui.style.ScreenStyle;
|
import appeng.client.gui.style.ScreenStyle;
|
||||||
import appeng.client.gui.widgets.SettingToggleButton;
|
import appeng.client.gui.widgets.SettingToggleButton;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuAdvancedSync;
|
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuDoublingSync;
|
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
|
||||||
import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket;
|
import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket;
|
||||||
import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket;
|
import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
@ -50,7 +50,7 @@ public abstract class SmallAdvPatternProviderScreenMixin extends AEBaseScreen<Sm
|
||||||
private void eap$initAdvancedBlocking(SmallAdvPatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
private void eap$initAdvancedBlocking(SmallAdvPatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
||||||
// 使用 @GuiSync 初始化
|
// 使用 @GuiSync 初始化
|
||||||
try {
|
try {
|
||||||
if (menu instanceof PatternProviderMenuAdvancedSync sync) {
|
if (menu instanceof IPatternProviderMenuAdvancedSync sync) {
|
||||||
this.eap$AdvancedBlockingEnabled = sync.eap$getAdvancedBlockingSynced();
|
this.eap$AdvancedBlockingEnabled = sync.eap$getAdvancedBlockingSynced();
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
@ -69,7 +69,7 @@ public abstract class SmallAdvPatternProviderScreenMixin extends AEBaseScreen<Sm
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
public java.util.List<Component> getTooltipMessage() {
|
public java.util.List<Component> getTooltipMessage() {
|
||||||
boolean enabled = eap$AdvancedBlockingEnabled;
|
boolean enabled = SmallAdvPatternProviderScreenMixin.this.eap$AdvancedBlockingEnabled;
|
||||||
var title = Component.literal("智能阻挡");
|
var title = Component.literal("智能阻挡");
|
||||||
var line = enabled
|
var line = enabled
|
||||||
? Component.literal("已启用:对于同一种配方将不再阻挡(需要开启原版的阻挡模式)")
|
? Component.literal("已启用:对于同一种配方将不再阻挡(需要开启原版的阻挡模式)")
|
||||||
|
|
@ -84,7 +84,7 @@ public abstract class SmallAdvPatternProviderScreenMixin extends AEBaseScreen<Sm
|
||||||
|
|
||||||
// 智能翻倍按钮:与高级阻挡同款样式,点击仅发送C2S,状态由@GuiSync驱动
|
// 智能翻倍按钮:与高级阻挡同款样式,点击仅发送C2S,状态由@GuiSync驱动
|
||||||
try {
|
try {
|
||||||
if (menu instanceof PatternProviderMenuDoublingSync sync2) {
|
if (menu instanceof IPatternProviderMenuDoublingSync sync2) {
|
||||||
this.eap$SmartDoublingEnabled = sync2.eap$getSmartDoublingSynced();
|
this.eap$SmartDoublingEnabled = sync2.eap$getSmartDoublingSynced();
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
@ -101,7 +101,7 @@ public abstract class SmallAdvPatternProviderScreenMixin extends AEBaseScreen<Sm
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
public java.util.List<Component> getTooltipMessage() {
|
public java.util.List<Component> getTooltipMessage() {
|
||||||
boolean enabled = eap$SmartDoublingEnabled;
|
boolean enabled = SmallAdvPatternProviderScreenMixin.this.eap$SmartDoublingEnabled;
|
||||||
var title = Component.literal("智能翻倍");
|
var title = Component.literal("智能翻倍");
|
||||||
var line = enabled
|
var line = enabled
|
||||||
? Component.literal("已启用:根据请求量对处理样板进行智能缩放")
|
? Component.literal("已启用:根据请求量对处理样板进行智能缩放")
|
||||||
|
|
@ -119,7 +119,7 @@ public abstract class SmallAdvPatternProviderScreenMixin extends AEBaseScreen<Sm
|
||||||
private void eap$updateAdvancedBlocking(CallbackInfo ci) {
|
private void eap$updateAdvancedBlocking(CallbackInfo ci) {
|
||||||
if (this.eap$AdvancedBlockingToggle != null) {
|
if (this.eap$AdvancedBlockingToggle != null) {
|
||||||
boolean desired = this.eap$AdvancedBlockingEnabled;
|
boolean desired = this.eap$AdvancedBlockingEnabled;
|
||||||
if (this.menu instanceof PatternProviderMenuAdvancedSync sync) {
|
if (this.menu instanceof IPatternProviderMenuAdvancedSync sync) {
|
||||||
desired = sync.eap$getAdvancedBlockingSynced();
|
desired = sync.eap$getAdvancedBlockingSynced();
|
||||||
}
|
}
|
||||||
this.eap$AdvancedBlockingEnabled = desired;
|
this.eap$AdvancedBlockingEnabled = desired;
|
||||||
|
|
@ -128,7 +128,7 @@ public abstract class SmallAdvPatternProviderScreenMixin extends AEBaseScreen<Sm
|
||||||
|
|
||||||
if (this.eap$SmartDoublingToggle != null) {
|
if (this.eap$SmartDoublingToggle != null) {
|
||||||
boolean desired2 = this.eap$SmartDoublingEnabled;
|
boolean desired2 = this.eap$SmartDoublingEnabled;
|
||||||
if (this.menu instanceof PatternProviderMenuDoublingSync sync2) {
|
if (this.menu instanceof IPatternProviderMenuDoublingSync sync2) {
|
||||||
desired2 = sync2.eap$getSmartDoublingSynced();
|
desired2 = sync2.eap$getSmartDoublingSynced();
|
||||||
}
|
}
|
||||||
this.eap$SmartDoublingEnabled = desired2;
|
this.eap$SmartDoublingEnabled = desired2;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import appeng.api.crafting.IPatternDetails.IInput;
|
||||||
import appeng.api.stacks.AEKey;
|
import appeng.api.stacks.AEKey;
|
||||||
import appeng.api.stacks.GenericStack;
|
import appeng.api.stacks.GenericStack;
|
||||||
import appeng.helpers.patternprovider.PatternProviderTarget;
|
import appeng.helpers.patternprovider.PatternProviderTarget;
|
||||||
import com.extendedae_plus.api.AdvancedBlockingHolder;
|
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
|
||||||
import net.minecraft.core.HolderLookup;
|
import net.minecraft.core.HolderLookup;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
||||||
|
|
@ -20,7 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@Mixin(value = AdvPatternProviderLogic.class, remap = false)
|
@Mixin(value = AdvPatternProviderLogic.class, remap = false)
|
||||||
public class AdvPatternProviderLogicAdvancedMixin implements AdvancedBlockingHolder {
|
public class AdvPatternProviderLogicAdvancedMixin implements IAdvancedBlocking {
|
||||||
@Unique
|
@Unique
|
||||||
private static final String EAP_ADV_BLOCKING_KEY = "eap_advanced_blocking";
|
private static final String EAP_ADV_BLOCKING_KEY = "eap_advanced_blocking";
|
||||||
|
|
||||||
|
|
@ -29,7 +29,7 @@ public class AdvPatternProviderLogicAdvancedMixin implements AdvancedBlockingHol
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean eap$getAdvancedBlocking() {
|
public boolean eap$getAdvancedBlocking() {
|
||||||
return eap$advancedBlocking;
|
return this.eap$advancedBlocking;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -63,7 +63,7 @@ public class AdvPatternProviderLogicAdvancedMixin implements AdvancedBlockingHol
|
||||||
|
|
||||||
// 仅当高级阻挡启用时启用“匹配则不阻挡”
|
// 仅当高级阻挡启用时启用“匹配则不阻挡”
|
||||||
if (this.eap$advancedBlocking) {
|
if (this.eap$advancedBlocking) {
|
||||||
if (eap$targetFullyMatchesPatternInputs(adapter, patternDetails)) {
|
if (this.eap$targetFullyMatchesPatternInputs(adapter, patternDetails)) {
|
||||||
// 返回 false 表示“不包含阻挡关键物”,从而不触发 continue,允许发配
|
// 返回 false 表示“不包含阻挡关键物”,从而不触发 continue,允许发配
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ package com.extendedae_plus.mixin.advancedae.helpers;
|
||||||
|
|
||||||
import appeng.api.crafting.IPatternDetails;
|
import appeng.api.crafting.IPatternDetails;
|
||||||
import appeng.crafting.pattern.AEProcessingPattern;
|
import appeng.crafting.pattern.AEProcessingPattern;
|
||||||
import com.extendedae_plus.api.SmartDoublingAwarePattern;
|
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
|
||||||
import com.extendedae_plus.api.SmartDoublingHolder;
|
import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern;
|
||||||
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderLogicPatternsAccessor;
|
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderLogicPatternsAccessor;
|
||||||
import net.minecraft.core.HolderLookup;
|
import net.minecraft.core.HolderLookup;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(value = AdvPatternProviderLogic.class, remap = false)
|
@Mixin(value = AdvPatternProviderLogic.class, remap = false)
|
||||||
public class AdvPatternProviderLogicDoublingMixin implements SmartDoublingHolder {
|
public class AdvPatternProviderLogicDoublingMixin implements ISmartDoubling {
|
||||||
@Unique
|
@Unique
|
||||||
private static final String EAP_SMART_DOUBLING_KEY = "eap_smart_doubling";
|
private static final String EAP_SMART_DOUBLING_KEY = "eap_smart_doubling";
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ public class AdvPatternProviderLogicDoublingMixin implements SmartDoublingHolder
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean eap$getSmartDoubling() {
|
public boolean eap$getSmartDoubling() {
|
||||||
return eap$smartDoubling;
|
return this.eap$smartDoubling;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -35,7 +35,7 @@ public class AdvPatternProviderLogicDoublingMixin implements SmartDoublingHolder
|
||||||
try {
|
try {
|
||||||
var list = ((AdvPatternProviderLogicPatternsAccessor) this).eap$patterns();
|
var list = ((AdvPatternProviderLogicPatternsAccessor) this).eap$patterns();
|
||||||
for (IPatternDetails details : list) {
|
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);
|
aware.eap$setAllowScaling(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +63,7 @@ public class AdvPatternProviderLogicDoublingMixin implements SmartDoublingHolder
|
||||||
var list = ((AdvPatternProviderLogicPatternsAccessor) this).eap$patterns();
|
var list = ((AdvPatternProviderLogicPatternsAccessor) this).eap$patterns();
|
||||||
boolean allow = this.eap$smartDoubling;
|
boolean allow = this.eap$smartDoubling;
|
||||||
for (IPatternDetails details : list) {
|
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);
|
aware.eap$setAllowScaling(allow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ package com.extendedae_plus.mixin.advancedae.menu;
|
||||||
|
|
||||||
import appeng.menu.AEBaseMenu;
|
import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.guisync.GuiSync;
|
import appeng.menu.guisync.GuiSync;
|
||||||
import com.extendedae_plus.api.AdvancedBlockingHolder;
|
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuAdvancedSync;
|
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
|
||||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
||||||
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
|
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
|
@ -15,22 +15,21 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(AdvPatternProviderMenu.class)
|
@Mixin(AdvPatternProviderMenu.class)
|
||||||
public abstract class AdvPatternProviderMenuAdvancedMixin implements PatternProviderMenuAdvancedSync {
|
public abstract class AdvPatternProviderMenuAdvancedMixin implements IPatternProviderMenuAdvancedSync {
|
||||||
@Final
|
@Final
|
||||||
@Shadow(remap = false)
|
@Shadow(remap = false)
|
||||||
protected AdvPatternProviderLogic logic;
|
protected AdvPatternProviderLogic logic;
|
||||||
|
|
||||||
// 选择一个未占用的 GUI 同步 id(AE2 已用到 7),这里使用 21 以避冲突
|
// 选择一个未占用的 GUI 同步 id(AE2 已用到 7),这里使用 21 以避冲突
|
||||||
@Unique
|
@Unique
|
||||||
@GuiSync(22)
|
@GuiSync(22) private boolean eap$AdvancedBlocking = false;
|
||||||
public boolean eap$AdvancedBlocking = false;
|
|
||||||
|
|
||||||
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
||||||
private void eap$syncAdvancedBlocking(CallbackInfo ci) {
|
private void eap$syncAdvancedBlocking(CallbackInfo ci) {
|
||||||
// 避免@Shadow父类方法,改用公共API:AEBaseMenu#isClientSide()
|
// 避免@Shadow父类方法,改用公共API:AEBaseMenu#isClientSide()
|
||||||
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
||||||
var l = this.logic;
|
var l = this.logic;
|
||||||
if (l instanceof AdvancedBlockingHolder holder) {
|
if (l instanceof IAdvancedBlocking holder) {
|
||||||
this.eap$AdvancedBlocking = holder.eap$getAdvancedBlocking();
|
this.eap$AdvancedBlocking = holder.eap$getAdvancedBlocking();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ package com.extendedae_plus.mixin.advancedae.menu;
|
||||||
|
|
||||||
import appeng.menu.AEBaseMenu;
|
import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.guisync.GuiSync;
|
import appeng.menu.guisync.GuiSync;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuDoublingSync;
|
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
|
||||||
import com.extendedae_plus.api.SmartDoublingHolder;
|
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
|
||||||
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
import net.pedroksl.advanced_ae.common.logic.AdvPatternProviderLogic;
|
||||||
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
|
import net.pedroksl.advanced_ae.gui.advpatternprovider.AdvPatternProviderMenu;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
|
@ -15,20 +15,19 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(AdvPatternProviderMenu.class)
|
@Mixin(AdvPatternProviderMenu.class)
|
||||||
public abstract class AdvPatternProviderMenuDoublingMixin implements PatternProviderMenuDoublingSync {
|
public abstract class AdvPatternProviderMenuDoublingMixin implements IPatternProviderMenuDoublingSync {
|
||||||
@Final
|
@Final
|
||||||
@Shadow(remap = false)
|
@Shadow(remap = false)
|
||||||
protected AdvPatternProviderLogic logic;
|
protected AdvPatternProviderLogic logic;
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
@GuiSync(23)
|
@GuiSync(23) private boolean eap$SmartDoubling = false;
|
||||||
public boolean eap$SmartDoubling = false;
|
|
||||||
|
|
||||||
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
||||||
private void eap$syncSmartDoubling(CallbackInfo ci) {
|
private void eap$syncSmartDoubling(CallbackInfo ci) {
|
||||||
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
||||||
var l = this.logic;
|
var l = this.logic;
|
||||||
if (l instanceof SmartDoublingHolder holder) {
|
if (l instanceof ISmartDoubling holder) {
|
||||||
this.eap$SmartDoubling = holder.eap$getSmartDoubling();
|
this.eap$SmartDoubling = holder.eap$getSmartDoubling();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
package com.extendedae_plus.mixin.ae2;
|
package com.extendedae_plus.mixin.ae2;
|
||||||
|
|
||||||
import appeng.crafting.pattern.AEProcessingPattern;
|
import appeng.crafting.pattern.AEProcessingPattern;
|
||||||
import com.extendedae_plus.api.SmartDoublingAwarePattern;
|
import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
||||||
@Mixin(value = AEProcessingPattern.class, remap = false)
|
@Mixin(value = AEProcessingPattern.class, remap = false)
|
||||||
public class AEProcessingPatternMixin implements SmartDoublingAwarePattern {
|
public class AEProcessingPatternMixin implements ISmartDoublingAwarePattern {
|
||||||
@Unique
|
@Unique
|
||||||
private boolean eap$allowScaling = false; // 默认不允许缩放
|
private boolean eap$allowScaling = false; // 默认不允许缩放
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean eap$allowScaling() {
|
public boolean eap$allowScaling() {
|
||||||
return eap$allowScaling;
|
return this.eap$allowScaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package com.extendedae_plus.mixin.ae2.autopattern;
|
||||||
|
|
||||||
import appeng.api.crafting.IPatternDetails;
|
import appeng.api.crafting.IPatternDetails;
|
||||||
import appeng.me.service.CraftingService;
|
import appeng.me.service.CraftingService;
|
||||||
import com.extendedae_plus.content.ScaledProcessingPattern;
|
import com.extendedae_plus.api.crafting.ScaledProcessingPattern;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package com.extendedae_plus.mixin.ae2.autopattern;
|
||||||
import appeng.api.stacks.KeyCounter;
|
import appeng.api.stacks.KeyCounter;
|
||||||
import appeng.crafting.CraftingTreeNode;
|
import appeng.crafting.CraftingTreeNode;
|
||||||
import appeng.crafting.inv.CraftingSimulationState;
|
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.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ import appeng.crafting.CraftingTreeNode;
|
||||||
import appeng.crafting.CraftingTreeProcess;
|
import appeng.crafting.CraftingTreeProcess;
|
||||||
import appeng.crafting.pattern.AEProcessingPattern;
|
import appeng.crafting.pattern.AEProcessingPattern;
|
||||||
import appeng.me.service.CraftingService;
|
import appeng.me.service.CraftingService;
|
||||||
import com.extendedae_plus.api.SmartDoublingAwarePattern;
|
import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern;
|
||||||
|
import com.extendedae_plus.api.crafting.ScaledProcessingPattern;
|
||||||
import com.extendedae_plus.config.ModConfigs;
|
import com.extendedae_plus.config.ModConfigs;
|
||||||
import com.extendedae_plus.content.ScaledProcessingPattern;
|
import com.extendedae_plus.util.smartDoubling.PatternScaler;
|
||||||
import com.extendedae_plus.util.PatternScaler;
|
import com.extendedae_plus.util.smartDoubling.RequestedAmountHolder;
|
||||||
import com.extendedae_plus.util.RequestedAmountHolder;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
|
@ -40,7 +40,7 @@ public abstract class CraftingTreeProcessMixin {
|
||||||
// 若传入的 details 已经是缩放样板,且原始样板不允许缩放,则直接解包为原始样板
|
// 若传入的 details 已经是缩放样板,且原始样板不允许缩放,则直接解包为原始样板
|
||||||
if (details instanceof ScaledProcessingPattern sp) {
|
if (details instanceof ScaledProcessingPattern sp) {
|
||||||
var proc0 = sp.getOriginal();
|
var proc0 = sp.getOriginal();
|
||||||
if (proc0 instanceof SmartDoublingAwarePattern aware0 && !aware0.eap$allowScaling()) {
|
if (proc0 instanceof ISmartDoublingAwarePattern aware0 && !aware0.eap$allowScaling()) {
|
||||||
return proc0;
|
return proc0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ public abstract class CraftingTreeProcessMixin {
|
||||||
if (!(details instanceof AEProcessingPattern proc)) return original;
|
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;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package com.extendedae_plus.mixin.ae2.autopattern;
|
||||||
|
|
||||||
import appeng.api.crafting.IPatternDetails;
|
import appeng.api.crafting.IPatternDetails;
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogic;
|
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
import com.extendedae_plus.content.ScaledProcessingPattern;
|
import com.extendedae_plus.api.crafting.ScaledProcessingPattern;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,12 @@ import appeng.client.gui.style.ScreenStyle;
|
||||||
import appeng.client.gui.style.Text;
|
import appeng.client.gui.style.Text;
|
||||||
import appeng.client.gui.style.TextAlignment;
|
import appeng.client.gui.style.TextAlignment;
|
||||||
import appeng.menu.slot.AppEngSlot;
|
import appeng.menu.slot.AppEngSlot;
|
||||||
import com.extendedae_plus.api.ExPatternPageAccessor;
|
import com.extendedae_plus.api.IExPatternPage;
|
||||||
import com.extendedae_plus.content.ClientPatternHighlightStore;
|
import com.extendedae_plus.content.ClientPatternHighlightStore;
|
||||||
import com.extendedae_plus.network.CraftingMonitorJumpC2SPacket;
|
import com.extendedae_plus.network.CraftingMonitorJumpC2SPacket;
|
||||||
import com.extendedae_plus.network.CraftingMonitorOpenProviderC2SPacket;
|
import com.extendedae_plus.network.CraftingMonitorOpenProviderC2SPacket;
|
||||||
import com.extendedae_plus.util.GuiUtil;
|
import com.extendedae_plus.util.GuiUtil;
|
||||||
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
|
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
|
||||||
import com.mojang.logging.LogUtils;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.Font;
|
import net.minecraft.client.gui.Font;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
|
@ -40,6 +39,36 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
@Mixin(value = AEBaseScreen.class, remap = false)
|
@Mixin(value = AEBaseScreen.class, remap = false)
|
||||||
public abstract class AEBaseScreenMixin {
|
public abstract class AEBaseScreenMixin {
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static int eap$getIntField(Object self, String name, int def) {
|
||||||
|
Class<?> c = self.getClass();
|
||||||
|
while (c != null && c != Object.class) {
|
||||||
|
try {
|
||||||
|
var f = c.getDeclaredField(name);
|
||||||
|
f.setAccessible(true);
|
||||||
|
Object v = f.get(self);
|
||||||
|
if (v instanceof Integer i) return i;
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
c = c.getSuperclass();
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static Font eap$getFont(Object self) {
|
||||||
|
Class<?> c = self.getClass();
|
||||||
|
while (c != null && c != Object.class) {
|
||||||
|
try {
|
||||||
|
var f = c.getDeclaredField("font");
|
||||||
|
f.setAccessible(true);
|
||||||
|
Object v = f.get(self);
|
||||||
|
if (v instanceof Font font) return font;
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
c = c.getSuperclass();
|
||||||
|
}
|
||||||
|
return net.minecraft.client.Minecraft.getInstance().font;
|
||||||
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private ScreenStyle eap$getStyle(Object self) {
|
private ScreenStyle eap$getStyle(Object self) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -111,36 +140,6 @@ public abstract class AEBaseScreenMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
|
||||||
private static int eap$getIntField(Object self, String name, int def) {
|
|
||||||
Class<?> c = self.getClass();
|
|
||||||
while (c != null && c != Object.class) {
|
|
||||||
try {
|
|
||||||
var f = c.getDeclaredField(name);
|
|
||||||
f.setAccessible(true);
|
|
||||||
Object v = f.get(self);
|
|
||||||
if (v instanceof Integer i) return i;
|
|
||||||
} catch (Throwable ignored) {}
|
|
||||||
c = c.getSuperclass();
|
|
||||||
}
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private static Font eap$getFont(Object self) {
|
|
||||||
Class<?> c = self.getClass();
|
|
||||||
while (c != null && c != Object.class) {
|
|
||||||
try {
|
|
||||||
var f = c.getDeclaredField("font");
|
|
||||||
f.setAccessible(true);
|
|
||||||
Object v = f.get(self);
|
|
||||||
if (v instanceof Font font) return font;
|
|
||||||
} catch (Throwable ignored) {}
|
|
||||||
c = c.getSuperclass();
|
|
||||||
}
|
|
||||||
return net.minecraft.client.Minecraft.getInstance().font;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重写renderSlot方法,为所有可见的样板槽位添加数量显示
|
* 重写renderSlot方法,为所有可见的样板槽位添加数量显示
|
||||||
*/
|
*/
|
||||||
|
|
@ -266,7 +265,7 @@ public abstract class AEBaseScreenMixin {
|
||||||
|
|
||||||
int cur = 1;
|
int cur = 1;
|
||||||
int max = 1;
|
int max = 1;
|
||||||
if (self instanceof ExPatternPageAccessor accessor) {
|
if (self instanceof IExPatternPage accessor) {
|
||||||
cur = Math.max(0, accessor.eap$getCurrentPage()) + 1;
|
cur = Math.max(0, accessor.eap$getCurrentPage()) + 1;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
@ -281,7 +280,7 @@ public abstract class AEBaseScreenMixin {
|
||||||
|
|
||||||
String pageText = "第" + cur + "页" + "/" + max + "页";
|
String pageText = "第" + cur + "页" + "/" + max + "页";
|
||||||
|
|
||||||
ScreenStyle style = eap$getStyle(self);
|
ScreenStyle style = this.eap$getStyle(self);
|
||||||
int color = 0xFFFFFFFF;
|
int color = 0xFFFFFFFF;
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import appeng.client.gui.AEBaseScreen;
|
||||||
import appeng.client.gui.implementations.InterfaceScreen;
|
import appeng.client.gui.implementations.InterfaceScreen;
|
||||||
import appeng.menu.AEBaseMenu;
|
import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.SlotSemantics;
|
import appeng.menu.SlotSemantics;
|
||||||
import com.extendedae_plus.NewIcon;
|
import com.extendedae_plus.client.gui.NewIcon;
|
||||||
import com.extendedae_plus.mixin.accessor.AbstractContainerScreenAccessor;
|
import com.extendedae_plus.mixin.accessor.AbstractContainerScreenAccessor;
|
||||||
import com.extendedae_plus.mixin.accessor.ScreenAccessor;
|
import com.extendedae_plus.mixin.accessor.ScreenAccessor;
|
||||||
import com.extendedae_plus.network.InterfaceAdjustConfigAmountC2SPacket;
|
import com.extendedae_plus.network.InterfaceAdjustConfigAmountC2SPacket;
|
||||||
|
|
@ -40,107 +40,117 @@ public abstract class InterfaceScreenMixin<T extends AEBaseMenu> {
|
||||||
|
|
||||||
@Inject(method = "init", at = @At("TAIL"))
|
@Inject(method = "init", at = @At("TAIL"))
|
||||||
private void eap$addScaleButtons(CallbackInfo ci) {
|
private void eap$addScaleButtons(CallbackInfo ci) {
|
||||||
if (!eap$isSupportedInterfaceScreen()) {
|
if (!this.eap$isSupportedInterfaceScreen()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (eap$x2Button == null) {
|
if (this.eap$x2Button == null) {
|
||||||
eap$x2Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(false, 2), NewIcon.MULTIPLY2);
|
this.eap$x2Button = new ActionEPPButton((b) -> this.eap$sendAdjustForAllConfigs(false, 2), NewIcon.MULTIPLY2);
|
||||||
eap$x2Button.setTooltip(null);
|
this.eap$x2Button.setTooltip(null);
|
||||||
eap$x2Button.setVisibility(true);
|
this.eap$x2Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (eap$divideBy2Button == null) {
|
if (this.eap$divideBy2Button == null) {
|
||||||
eap$divideBy2Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(true, 2), NewIcon.DIVIDE2);
|
this.eap$divideBy2Button = new ActionEPPButton((b) -> this.eap$sendAdjustForAllConfigs(true, 2), NewIcon.DIVIDE2);
|
||||||
eap$divideBy2Button.setTooltip(null);
|
this.eap$divideBy2Button.setTooltip(null);
|
||||||
eap$divideBy2Button.setVisibility(true);
|
this.eap$divideBy2Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (eap$x5Button == null) {
|
if (this.eap$x5Button == null) {
|
||||||
eap$x5Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(false, 5), NewIcon.MULTIPLY5);
|
this.eap$x5Button = new ActionEPPButton((b) -> this.eap$sendAdjustForAllConfigs(false, 5), NewIcon.MULTIPLY5);
|
||||||
eap$x5Button.setTooltip(null);
|
this.eap$x5Button.setTooltip(null);
|
||||||
eap$x5Button.setVisibility(true);
|
this.eap$x5Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (eap$divideBy5Button == null) {
|
if (this.eap$divideBy5Button == null) {
|
||||||
eap$divideBy5Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(true, 5), NewIcon.DIVIDE5);
|
this.eap$divideBy5Button = new ActionEPPButton((b) -> this.eap$sendAdjustForAllConfigs(true, 5), NewIcon.DIVIDE5);
|
||||||
eap$divideBy5Button.setTooltip(null);
|
this.eap$divideBy5Button.setTooltip(null);
|
||||||
eap$divideBy5Button.setVisibility(true);
|
this.eap$divideBy5Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (eap$x10Button == null) {
|
if (this.eap$x10Button == null) {
|
||||||
eap$x10Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(false, 10), NewIcon.MULTIPLY10);
|
this.eap$x10Button = new ActionEPPButton((b) -> this.eap$sendAdjustForAllConfigs(false, 10), NewIcon.MULTIPLY10);
|
||||||
eap$x10Button.setTooltip(null);
|
this.eap$x10Button.setTooltip(null);
|
||||||
eap$x10Button.setVisibility(true);
|
this.eap$x10Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (eap$divideBy10Button == null) {
|
if (this.eap$divideBy10Button == null) {
|
||||||
eap$divideBy10Button = new ActionEPPButton((b) -> eap$sendAdjustForAllConfigs(true, 10), NewIcon.DIVIDE10);
|
this.eap$divideBy10Button = new ActionEPPButton((b) -> this.eap$sendAdjustForAllConfigs(true, 10), NewIcon.DIVIDE10);
|
||||||
eap$divideBy10Button.setTooltip(null);
|
this.eap$divideBy10Button.setTooltip(null);
|
||||||
eap$divideBy10Button.setVisibility(true);
|
this.eap$divideBy10Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注册到渲染与交互列表
|
// 注册到渲染与交互列表
|
||||||
var accessor = (ScreenAccessor) (Object) this;
|
var accessor = (ScreenAccessor) (Object) this;
|
||||||
if (!accessor.eap$getRenderables().contains(eap$divideBy2Button)) accessor.eap$getRenderables().add(eap$divideBy2Button);
|
if (!accessor.eap$getRenderables().contains(this.eap$divideBy2Button))
|
||||||
if (!accessor.eap$getChildren().contains(eap$divideBy2Button)) accessor.eap$getChildren().add(eap$divideBy2Button);
|
accessor.eap$getRenderables().add(this.eap$divideBy2Button);
|
||||||
if (!accessor.eap$getRenderables().contains(eap$x2Button)) accessor.eap$getRenderables().add(eap$x2Button);
|
if (!accessor.eap$getChildren().contains(this.eap$divideBy2Button))
|
||||||
if (!accessor.eap$getChildren().contains(eap$x2Button)) accessor.eap$getChildren().add(eap$x2Button);
|
accessor.eap$getChildren().add(this.eap$divideBy2Button);
|
||||||
if (!accessor.eap$getRenderables().contains(eap$divideBy5Button)) accessor.eap$getRenderables().add(eap$divideBy5Button);
|
if (!accessor.eap$getRenderables().contains(this.eap$x2Button))
|
||||||
if (!accessor.eap$getChildren().contains(eap$divideBy5Button)) accessor.eap$getChildren().add(eap$divideBy5Button);
|
accessor.eap$getRenderables().add(this.eap$x2Button);
|
||||||
if (!accessor.eap$getRenderables().contains(eap$x5Button)) accessor.eap$getRenderables().add(eap$x5Button);
|
if (!accessor.eap$getChildren().contains(this.eap$x2Button)) accessor.eap$getChildren().add(this.eap$x2Button);
|
||||||
if (!accessor.eap$getChildren().contains(eap$x5Button)) accessor.eap$getChildren().add(eap$x5Button);
|
if (!accessor.eap$getRenderables().contains(this.eap$divideBy5Button))
|
||||||
if (!accessor.eap$getRenderables().contains(eap$divideBy10Button)) accessor.eap$getRenderables().add(eap$divideBy10Button);
|
accessor.eap$getRenderables().add(this.eap$divideBy5Button);
|
||||||
if (!accessor.eap$getChildren().contains(eap$divideBy10Button)) accessor.eap$getChildren().add(eap$divideBy10Button);
|
if (!accessor.eap$getChildren().contains(this.eap$divideBy5Button))
|
||||||
if (!accessor.eap$getRenderables().contains(eap$x10Button)) accessor.eap$getRenderables().add(eap$x10Button);
|
accessor.eap$getChildren().add(this.eap$divideBy5Button);
|
||||||
if (!accessor.eap$getChildren().contains(eap$x10Button)) accessor.eap$getChildren().add(eap$x10Button);
|
if (!accessor.eap$getRenderables().contains(this.eap$x5Button))
|
||||||
|
accessor.eap$getRenderables().add(this.eap$x5Button);
|
||||||
|
if (!accessor.eap$getChildren().contains(this.eap$x5Button)) accessor.eap$getChildren().add(this.eap$x5Button);
|
||||||
|
if (!accessor.eap$getRenderables().contains(this.eap$divideBy10Button))
|
||||||
|
accessor.eap$getRenderables().add(this.eap$divideBy10Button);
|
||||||
|
if (!accessor.eap$getChildren().contains(this.eap$divideBy10Button))
|
||||||
|
accessor.eap$getChildren().add(this.eap$divideBy10Button);
|
||||||
|
if (!accessor.eap$getRenderables().contains(this.eap$x10Button))
|
||||||
|
accessor.eap$getRenderables().add(this.eap$x10Button);
|
||||||
|
if (!accessor.eap$getChildren().contains(this.eap$x10Button))
|
||||||
|
accessor.eap$getChildren().add(this.eap$x10Button);
|
||||||
|
|
||||||
eap$relayoutButtons();
|
this.eap$relayoutButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "containerTick", at = @At("TAIL"))
|
@Inject(method = "containerTick", at = @At("TAIL"))
|
||||||
private void eap$ensureButtons(CallbackInfo ci) {
|
private void eap$ensureButtons(CallbackInfo ci) {
|
||||||
if (!eap$isSupportedInterfaceScreen()) {
|
if (!this.eap$isSupportedInterfaceScreen()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var accessor = (ScreenAccessor) (Object) this;
|
var accessor = (ScreenAccessor) (Object) this;
|
||||||
if (eap$divideBy2Button != null && !accessor.eap$getRenderables().contains(eap$divideBy2Button)) {
|
if (this.eap$divideBy2Button != null && !accessor.eap$getRenderables().contains(this.eap$divideBy2Button)) {
|
||||||
accessor.eap$getRenderables().add(eap$divideBy2Button);
|
accessor.eap$getRenderables().add(this.eap$divideBy2Button);
|
||||||
accessor.eap$getChildren().add(eap$divideBy2Button);
|
accessor.eap$getChildren().add(this.eap$divideBy2Button);
|
||||||
}
|
}
|
||||||
if (eap$x2Button != null && !accessor.eap$getRenderables().contains(eap$x2Button)) {
|
if (this.eap$x2Button != null && !accessor.eap$getRenderables().contains(this.eap$x2Button)) {
|
||||||
accessor.eap$getRenderables().add(eap$x2Button);
|
accessor.eap$getRenderables().add(this.eap$x2Button);
|
||||||
accessor.eap$getChildren().add(eap$x2Button);
|
accessor.eap$getChildren().add(this.eap$x2Button);
|
||||||
}
|
}
|
||||||
if (eap$divideBy5Button != null && !accessor.eap$getRenderables().contains(eap$divideBy5Button)) {
|
if (this.eap$divideBy5Button != null && !accessor.eap$getRenderables().contains(this.eap$divideBy5Button)) {
|
||||||
accessor.eap$getRenderables().add(eap$divideBy5Button);
|
accessor.eap$getRenderables().add(this.eap$divideBy5Button);
|
||||||
accessor.eap$getChildren().add(eap$divideBy5Button);
|
accessor.eap$getChildren().add(this.eap$divideBy5Button);
|
||||||
}
|
}
|
||||||
if (eap$x5Button != null && !accessor.eap$getRenderables().contains(eap$x5Button)) {
|
if (this.eap$x5Button != null && !accessor.eap$getRenderables().contains(this.eap$x5Button)) {
|
||||||
accessor.eap$getRenderables().add(eap$x5Button);
|
accessor.eap$getRenderables().add(this.eap$x5Button);
|
||||||
accessor.eap$getChildren().add(eap$x5Button);
|
accessor.eap$getChildren().add(this.eap$x5Button);
|
||||||
}
|
}
|
||||||
if (eap$divideBy10Button != null && !accessor.eap$getRenderables().contains(eap$divideBy10Button)) {
|
if (this.eap$divideBy10Button != null && !accessor.eap$getRenderables().contains(this.eap$divideBy10Button)) {
|
||||||
accessor.eap$getRenderables().add(eap$divideBy10Button);
|
accessor.eap$getRenderables().add(this.eap$divideBy10Button);
|
||||||
accessor.eap$getChildren().add(eap$divideBy10Button);
|
accessor.eap$getChildren().add(this.eap$divideBy10Button);
|
||||||
}
|
}
|
||||||
if (eap$x10Button != null && !accessor.eap$getRenderables().contains(eap$x10Button)) {
|
if (this.eap$x10Button != null && !accessor.eap$getRenderables().contains(this.eap$x10Button)) {
|
||||||
accessor.eap$getRenderables().add(eap$x10Button);
|
accessor.eap$getRenderables().add(this.eap$x10Button);
|
||||||
accessor.eap$getChildren().add(eap$x10Button);
|
accessor.eap$getChildren().add(this.eap$x10Button);
|
||||||
}
|
}
|
||||||
|
|
||||||
int curLeft = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos();
|
int curLeft = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos();
|
||||||
int curTop = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos();
|
int curTop = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos();
|
||||||
int curImgW = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth();
|
int curImgW = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth();
|
||||||
int curImgH = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageHeight();
|
int curImgH = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageHeight();
|
||||||
if (curLeft != eap$lastLeftPos || curTop != eap$lastTopPos || curImgW != eap$lastImageWidth || curImgH != eap$lastImageHeight) {
|
if (curLeft != this.eap$lastLeftPos || curTop != this.eap$lastTopPos || curImgW != this.eap$lastImageWidth || curImgH != this.eap$lastImageHeight) {
|
||||||
eap$lastLeftPos = curLeft;
|
this.eap$lastLeftPos = curLeft;
|
||||||
eap$lastTopPos = curTop;
|
this.eap$lastTopPos = curTop;
|
||||||
eap$lastImageWidth = curImgW;
|
this.eap$lastImageWidth = curImgW;
|
||||||
eap$lastImageHeight = curImgH;
|
this.eap$lastImageHeight = curImgH;
|
||||||
eap$relayoutButtons();
|
this.eap$relayoutButtons();
|
||||||
}
|
}
|
||||||
eap$updateLastConfigFromHover();
|
this.eap$updateLastConfigFromHover();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void eap$sendAdjustForHoveredConfig(boolean divide, int factor) {
|
private void eap$sendAdjustForHoveredConfig(boolean divide, int factor) {
|
||||||
try {
|
try {
|
||||||
if (!eap$isSupportedInterfaceScreen()) {
|
if (!this.eap$isSupportedInterfaceScreen()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Slot hovered = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getHoveredSlot();
|
Slot hovered = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getHoveredSlot();
|
||||||
|
|
@ -176,8 +186,8 @@ public abstract class InterfaceScreenMixin<T extends AEBaseMenu> {
|
||||||
int slotField = -1;
|
int slotField = -1;
|
||||||
if (slotFieldObj != null) {
|
if (slotFieldObj != null) {
|
||||||
slotField = slotFieldObj;
|
slotField = slotFieldObj;
|
||||||
} else if (eap$lastConfigIndex >= 0 && eap$lastConfigIndex < configSlots.size()) {
|
} else if (this.eap$lastConfigIndex >= 0 && this.eap$lastConfigIndex < configSlots.size()) {
|
||||||
slotField = eap$lastConfigIndex;
|
slotField = this.eap$lastConfigIndex;
|
||||||
}
|
}
|
||||||
if (slotField < 0) {
|
if (slotField < 0) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -191,7 +201,7 @@ public abstract class InterfaceScreenMixin<T extends AEBaseMenu> {
|
||||||
@Unique
|
@Unique
|
||||||
private void eap$sendAdjustForAllConfigs(boolean divide, int factor) {
|
private void eap$sendAdjustForAllConfigs(boolean divide, int factor) {
|
||||||
try {
|
try {
|
||||||
if (!eap$isSupportedInterfaceScreen()) {
|
if (!this.eap$isSupportedInterfaceScreen()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var conn = Minecraft.getInstance().getConnection();
|
var conn = Minecraft.getInstance().getConnection();
|
||||||
|
|
@ -219,15 +229,33 @@ public abstract class InterfaceScreenMixin<T extends AEBaseMenu> {
|
||||||
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos();
|
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getLeftPos();
|
||||||
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos();
|
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getTopPos();
|
||||||
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth();
|
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).eap$getImageWidth();
|
||||||
int bx = leftPos - eap$divideBy2Button.getWidth() -1;
|
int bx = leftPos - this.eap$divideBy2Button.getWidth() - 1;
|
||||||
int by = topPos + 30;
|
int by = topPos + 30;
|
||||||
int spacing = 22;
|
int spacing = 22;
|
||||||
if (eap$divideBy2Button != null) { eap$divideBy2Button.setX(bx); eap$divideBy2Button.setY(by); }
|
if (this.eap$divideBy2Button != null) {
|
||||||
if (eap$x2Button != null) { eap$x2Button.setX(bx); eap$x2Button.setY(by + spacing); }
|
this.eap$divideBy2Button.setX(bx);
|
||||||
if (eap$divideBy5Button != null) { eap$divideBy5Button.setX(bx); eap$divideBy5Button.setY(by + spacing * 2); }
|
this.eap$divideBy2Button.setY(by);
|
||||||
if (eap$x5Button != null) { eap$x5Button.setX(bx); eap$x5Button.setY(by + spacing * 3); }
|
}
|
||||||
if (eap$divideBy10Button != null) { eap$divideBy10Button.setX(bx); eap$divideBy10Button.setY(by + spacing * 4); }
|
if (this.eap$x2Button != null) {
|
||||||
if (eap$x10Button != null) { eap$x10Button.setX(bx); eap$x10Button.setY(by + spacing * 5); }
|
this.eap$x2Button.setX(bx);
|
||||||
|
this.eap$x2Button.setY(by + spacing);
|
||||||
|
}
|
||||||
|
if (this.eap$divideBy5Button != null) {
|
||||||
|
this.eap$divideBy5Button.setX(bx);
|
||||||
|
this.eap$divideBy5Button.setY(by + spacing * 2);
|
||||||
|
}
|
||||||
|
if (this.eap$x5Button != null) {
|
||||||
|
this.eap$x5Button.setX(bx);
|
||||||
|
this.eap$x5Button.setY(by + spacing * 3);
|
||||||
|
}
|
||||||
|
if (this.eap$divideBy10Button != null) {
|
||||||
|
this.eap$divideBy10Button.setX(bx);
|
||||||
|
this.eap$divideBy10Button.setY(by + spacing * 4);
|
||||||
|
}
|
||||||
|
if (this.eap$x10Button != null) {
|
||||||
|
this.eap$x10Button.setX(bx);
|
||||||
|
this.eap$x10Button.setY(by + spacing * 5);
|
||||||
|
}
|
||||||
} catch (Throwable ignored) {}
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,8 +296,8 @@ public abstract class InterfaceScreenMixin<T extends AEBaseMenu> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (idx != null && idx >= 0) {
|
if (idx != null && idx >= 0) {
|
||||||
if (eap$lastConfigIndex != idx) {
|
if (this.eap$lastConfigIndex != idx) {
|
||||||
eap$lastConfigIndex = idx;
|
this.eap$lastConfigIndex = idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable ignored) {}
|
} catch (Throwable ignored) {}
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ import appeng.client.gui.implementations.PatternProviderScreen;
|
||||||
import appeng.client.gui.style.ScreenStyle;
|
import appeng.client.gui.style.ScreenStyle;
|
||||||
import appeng.client.gui.widgets.SettingToggleButton;
|
import appeng.client.gui.widgets.SettingToggleButton;
|
||||||
import appeng.menu.implementations.PatternProviderMenu;
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
import com.extendedae_plus.api.ExPatternButtonsAccessor;
|
import com.extendedae_plus.api.IExPatternButton;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuAdvancedSync;
|
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuDoublingSync;
|
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
|
||||||
import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket;
|
import com.extendedae_plus.network.ToggleAdvancedBlockingC2SPacket;
|
||||||
import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket;
|
import com.extendedae_plus.network.ToggleSmartDoublingC2SPacket;
|
||||||
import com.extendedae_plus.util.ExtendedAELogger;
|
import com.extendedae_plus.util.ExtendedAELogger;
|
||||||
|
|
@ -51,7 +51,7 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
||||||
private void eap$initAdvancedBlocking(C menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
private void eap$initAdvancedBlocking(C menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
||||||
// 使用 @GuiSync 初始化
|
// 使用 @GuiSync 初始化
|
||||||
try {
|
try {
|
||||||
if (menu instanceof PatternProviderMenuAdvancedSync sync) {
|
if (menu instanceof IPatternProviderMenuAdvancedSync sync) {
|
||||||
this.eap$AdvancedBlockingEnabled = sync.eap$getAdvancedBlockingSynced();
|
this.eap$AdvancedBlockingEnabled = sync.eap$getAdvancedBlockingSynced();
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
@ -71,7 +71,7 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
public java.util.List<net.minecraft.network.chat.Component> getTooltipMessage() {
|
public java.util.List<net.minecraft.network.chat.Component> getTooltipMessage() {
|
||||||
boolean enabled = eap$AdvancedBlockingEnabled;
|
boolean enabled = PatternProviderScreenMixin.this.eap$AdvancedBlockingEnabled;
|
||||||
var title = net.minecraft.network.chat.Component.literal("智能阻挡");
|
var title = net.minecraft.network.chat.Component.literal("智能阻挡");
|
||||||
var line = enabled
|
var line = enabled
|
||||||
? net.minecraft.network.chat.Component.literal("已启用:对于同一种配方将不再阻挡(需要开启原版的阻挡模式)")
|
? net.minecraft.network.chat.Component.literal("已启用:对于同一种配方将不再阻挡(需要开启原版的阻挡模式)")
|
||||||
|
|
@ -87,7 +87,7 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
||||||
|
|
||||||
// 智能翻倍按钮:与高级阻挡同款样式,点击仅发送C2S,状态由@GuiSync驱动
|
// 智能翻倍按钮:与高级阻挡同款样式,点击仅发送C2S,状态由@GuiSync驱动
|
||||||
try {
|
try {
|
||||||
if (menu instanceof PatternProviderMenuDoublingSync sync2) {
|
if (menu instanceof IPatternProviderMenuDoublingSync sync2) {
|
||||||
this.eap$SmartDoublingEnabled = sync2.eap$getSmartDoublingSynced();
|
this.eap$SmartDoublingEnabled = sync2.eap$getSmartDoublingSynced();
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
@ -105,7 +105,7 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
||||||
) {
|
) {
|
||||||
@Override
|
@Override
|
||||||
public java.util.List<net.minecraft.network.chat.Component> getTooltipMessage() {
|
public java.util.List<net.minecraft.network.chat.Component> getTooltipMessage() {
|
||||||
boolean enabled = eap$SmartDoublingEnabled;
|
boolean enabled = PatternProviderScreenMixin.this.eap$SmartDoublingEnabled;
|
||||||
var title = net.minecraft.network.chat.Component.literal("智能翻倍");
|
var title = net.minecraft.network.chat.Component.literal("智能翻倍");
|
||||||
var line = enabled
|
var line = enabled
|
||||||
? net.minecraft.network.chat.Component.literal("已启用:根据请求量对处理样板进行智能缩放")
|
? net.minecraft.network.chat.Component.literal("已启用:根据请求量对处理样板进行智能缩放")
|
||||||
|
|
@ -123,7 +123,7 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
||||||
private void eap$updateAdvancedBlocking(CallbackInfo ci) {
|
private void eap$updateAdvancedBlocking(CallbackInfo ci) {
|
||||||
if (this.eap$AdvancedBlockingToggle != null) {
|
if (this.eap$AdvancedBlockingToggle != null) {
|
||||||
boolean desired = this.eap$AdvancedBlockingEnabled;
|
boolean desired = this.eap$AdvancedBlockingEnabled;
|
||||||
if (this.menu instanceof PatternProviderMenuAdvancedSync sync) {
|
if (this.menu instanceof IPatternProviderMenuAdvancedSync sync) {
|
||||||
desired = sync.eap$getAdvancedBlockingSynced();
|
desired = sync.eap$getAdvancedBlockingSynced();
|
||||||
}
|
}
|
||||||
// debug removed
|
// debug removed
|
||||||
|
|
@ -133,7 +133,7 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
||||||
|
|
||||||
if (this.eap$SmartDoublingToggle != null) {
|
if (this.eap$SmartDoublingToggle != null) {
|
||||||
boolean desired2 = this.eap$SmartDoublingEnabled;
|
boolean desired2 = this.eap$SmartDoublingEnabled;
|
||||||
if (this.menu instanceof PatternProviderMenuDoublingSync sync2) {
|
if (this.menu instanceof IPatternProviderMenuDoublingSync sync2) {
|
||||||
desired2 = sync2.eap$getSmartDoublingSynced();
|
desired2 = sync2.eap$getSmartDoublingSynced();
|
||||||
}
|
}
|
||||||
// debug removed
|
// debug removed
|
||||||
|
|
@ -143,7 +143,7 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
||||||
|
|
||||||
if ((Object) this instanceof GuiExPatternProvider) {
|
if ((Object) this instanceof GuiExPatternProvider) {
|
||||||
try {
|
try {
|
||||||
((ExPatternButtonsAccessor) this).eap$updateButtonsLayout();
|
((IExPatternButton) this).eap$updateButtonsLayout();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
// debug removed
|
// debug removed
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||||
import appeng.menu.AEBaseMenu;
|
import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.SlotSemantics;
|
import appeng.menu.SlotSemantics;
|
||||||
import appeng.menu.implementations.PatternProviderMenu;
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
|
import com.extendedae_plus.api.IStyleAccessor;
|
||||||
import com.extendedae_plus.compat.AppliedFluxCompat;
|
import com.extendedae_plus.compat.AppliedFluxCompat;
|
||||||
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
import com.extendedae_plus.util.IStyleAccessor;
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
@ -32,6 +32,10 @@ import java.util.List;
|
||||||
@Mixin(value = PatternProviderScreen.class, priority = 1500, remap = false)
|
@Mixin(value = PatternProviderScreen.class, priority = 1500, remap = false)
|
||||||
public abstract class PatternProviderScreenUpgradesMixin<C extends PatternProviderMenu> extends AEBaseScreen<C> {
|
public abstract class PatternProviderScreenUpgradesMixin<C extends PatternProviderMenu> extends AEBaseScreen<C> {
|
||||||
|
|
||||||
|
public PatternProviderScreenUpgradesMixin(C menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
||||||
|
super(menu, playerInventory, title, style);
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("TAIL"), remap = false)
|
@Inject(method = "<init>", at = @At("TAIL"), remap = false)
|
||||||
private void eap$initUpgrades(PatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
private void eap$initUpgrades(PatternProviderMenu menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
||||||
|
|
||||||
|
|
@ -77,7 +81,7 @@ public abstract class PatternProviderScreenUpgradesMixin<C extends PatternProvid
|
||||||
((IStyleAccessor) style).getWidgets().put("toolbox", ws);
|
((IStyleAccessor) style).getWidgets().put("toolbox", ws);
|
||||||
|
|
||||||
// 添加工具箱面板
|
// 添加工具箱面板
|
||||||
if (menu instanceof AEBaseMenu base && base instanceof com.extendedae_plus.bridge.IUpgradableMenu upg && upg.eap$getToolbox() != null && upg.eap$getToolbox().isPresent()) {
|
if (menu instanceof AEBaseMenu base && base instanceof com.extendedae_plus.api.bridge.IUpgradableMenu upg && upg.eap$getToolbox() != null && upg.eap$getToolbox().isPresent()) {
|
||||||
try {
|
try {
|
||||||
this.widgets.add("toolbox", new ToolboxPanel(style, upg.eap$getToolbox().getName()));
|
this.widgets.add("toolbox", new ToolboxPanel(style, upg.eap$getToolbox().getName()));
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
|
|
@ -88,12 +92,11 @@ public abstract class PatternProviderScreenUpgradesMixin<C extends PatternProvid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private List<Component> eap$getCompatibleUpgrades() {
|
private List<Component> eap$getCompatibleUpgrades() {
|
||||||
var list = new ArrayList<Component>();
|
var list = new ArrayList<Component>();
|
||||||
list.add(GuiText.CompatibleUpgrades.text());
|
list.add(GuiText.CompatibleUpgrades.text());
|
||||||
if (menu instanceof AEBaseMenu base) {
|
if (this.menu instanceof AEBaseMenu base) {
|
||||||
var target = base.getTarget();
|
var target = base.getTarget();
|
||||||
if (target instanceof PatternProviderLogicHost host) {
|
if (target instanceof PatternProviderLogicHost host) {
|
||||||
list.addAll(Upgrades.getTooltipLinesForMachine(host.getTerminalIcon().getItem()));
|
list.addAll(Upgrades.getTooltipLinesForMachine(host.getTerminalIcon().getItem()));
|
||||||
|
|
@ -101,8 +104,4 @@ public abstract class PatternProviderScreenUpgradesMixin<C extends PatternProvid
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PatternProviderScreenUpgradesMixin(C menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
|
||||||
super(menu, playerInventory, title, style);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package com.extendedae_plus.mixin.ae2.client.gui;
|
||||||
import appeng.client.gui.style.Blitter;
|
import appeng.client.gui.style.Blitter;
|
||||||
import appeng.client.gui.style.ScreenStyle;
|
import appeng.client.gui.style.ScreenStyle;
|
||||||
import appeng.client.gui.style.WidgetStyle;
|
import appeng.client.gui.style.WidgetStyle;
|
||||||
import com.extendedae_plus.util.IStyleAccessor;
|
import com.extendedae_plus.api.IStyleAccessor;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.extendedae_plus.mixin.ae2.client.gui;
|
||||||
|
|
||||||
import appeng.client.Point;
|
import appeng.client.Point;
|
||||||
import appeng.client.gui.layout.SlotGridLayout;
|
import appeng.client.gui.layout.SlotGridLayout;
|
||||||
|
import com.extendedae_plus.api.IExPatternPage;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
@ -32,7 +33,7 @@ public abstract class SlotGridLayoutMixin {
|
||||||
// 读取实际当前页码:优先从 GUI accessor,其次反射容器,失败则为 0
|
// 读取实际当前页码:优先从 GUI accessor,其次反射容器,失败则为 0
|
||||||
int currentPage = 0;
|
int currentPage = 0;
|
||||||
try {
|
try {
|
||||||
if (screen instanceof com.extendedae_plus.api.ExPatternPageAccessor accessor) {
|
if (screen instanceof IExPatternPage accessor) {
|
||||||
currentPage = accessor.eap$getCurrentPage();
|
currentPage = accessor.eap$getCurrentPage();
|
||||||
} else {
|
} else {
|
||||||
var menu = ((com.glodblock.github.extendedae.client.gui.GuiExPatternProvider) screen).getMenu();
|
var menu = ((com.glodblock.github.extendedae.client.gui.GuiExPatternProvider) screen).getMenu();
|
||||||
|
|
|
||||||
|
|
@ -12,20 +12,19 @@ import appeng.api.upgrades.UpgradeInventories;
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogic;
|
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
import com.extendedae_plus.ae.wireless.WirelessSlaveLink;
|
||||||
import com.extendedae_plus.bridge.CompatUpgradeProvider;
|
import com.extendedae_plus.ae.wireless.endpoint.GenericNodeEndpointImpl;
|
||||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
import com.extendedae_plus.api.bridge.CompatUpgradeProvider;
|
||||||
|
import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge;
|
||||||
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
|
import com.extendedae_plus.init.ModItems;
|
||||||
|
import com.extendedae_plus.items.materials.ChannelCardItem;
|
||||||
import com.extendedae_plus.mixin.advancedae.accessor.AdvCraftingCPULogicAccessor;
|
import com.extendedae_plus.mixin.advancedae.accessor.AdvCraftingCPULogicAccessor;
|
||||||
import com.extendedae_plus.mixin.advancedae.accessor.AdvExecutingCraftingJobAccessor;
|
import com.extendedae_plus.mixin.advancedae.accessor.AdvExecutingCraftingJobAccessor;
|
||||||
import com.extendedae_plus.mixin.advancedae.accessor.AdvExecutingCraftingJobTaskProgressAccessor;
|
import com.extendedae_plus.mixin.advancedae.accessor.AdvExecutingCraftingJobTaskProgressAccessor;
|
||||||
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
|
||||||
import com.extendedae_plus.init.ModItems;
|
|
||||||
import com.extendedae_plus.mixin.ae2.accessor.CraftingCpuLogicAccessor;
|
import com.extendedae_plus.mixin.ae2.accessor.CraftingCpuLogicAccessor;
|
||||||
import com.extendedae_plus.mixin.ae2.accessor.ExecutingCraftingJobAccessor;
|
import com.extendedae_plus.mixin.ae2.accessor.ExecutingCraftingJobAccessor;
|
||||||
import com.extendedae_plus.mixin.ae2.accessor.ExecutingCraftingJobTaskProgressAccessor;
|
|
||||||
import com.extendedae_plus.util.ExtendedAELogger;
|
import com.extendedae_plus.util.ExtendedAELogger;
|
||||||
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
|
||||||
import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
@ -94,7 +93,7 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
this.eap$compatUpgrades = UpgradeInventories.empty();
|
this.eap$compatUpgrades = UpgradeInventories.empty();
|
||||||
|
|
||||||
// 尝试监听AppliedFlux的升级变更
|
// 尝试监听AppliedFlux的升级变更
|
||||||
eap$tryHookAppliedFluxUpgradeChanges();
|
this.eap$tryHookAppliedFluxUpgradeChanges();
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
ExtendedAELogger.LOGGER.error("[样板供应器] 初始化兼容升级槽失败", t);
|
ExtendedAELogger.LOGGER.error("[样板供应器] 初始化兼容升级槽失败", t);
|
||||||
|
|
@ -105,10 +104,10 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
private void eap$compatOnUpgradesChanged() {
|
private void eap$compatOnUpgradesChanged() {
|
||||||
try {
|
try {
|
||||||
this.host.saveChanges();
|
this.host.saveChanges();
|
||||||
eap$compatLastChannel = -1;
|
this.eap$compatLastChannel = -1;
|
||||||
eap$compatHasInitialized = false;
|
this.eap$compatHasInitialized = false;
|
||||||
eap$compatInitializeChannelLink();
|
this.eap$compatInitializeChannelLink();
|
||||||
eap$compatSyncVirtualCraftingState();
|
this.eap$compatSyncVirtualCraftingState();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
ExtendedAELogger.LOGGER.error("[样板供应器] 兼容升级变更处理失败", t);
|
ExtendedAELogger.LOGGER.error("[样板供应器] 兼容升级变更处理失败", t);
|
||||||
}
|
}
|
||||||
|
|
@ -150,10 +149,10 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
this.eap$compatUpgrades.readFromNBT(tag, "compat_upgrades", registries);
|
this.eap$compatUpgrades.readFromNBT(tag, "compat_upgrades", registries);
|
||||||
}
|
}
|
||||||
// 无论哪种模式都重新初始化
|
// 无论哪种模式都重新初始化
|
||||||
eap$compatLastChannel = -1;
|
this.eap$compatLastChannel = -1;
|
||||||
eap$compatHasInitialized = false;
|
this.eap$compatHasInitialized = false;
|
||||||
eap$compatInitializeChannelLink();
|
this.eap$compatInitializeChannelLink();
|
||||||
eap$compatSyncVirtualCraftingState();
|
this.eap$compatSyncVirtualCraftingState();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
ExtendedAELogger.LOGGER.error("[样板供应器] 读取兼容升级失败", t);
|
ExtendedAELogger.LOGGER.error("[样板供应器] 读取兼容升级失败", t);
|
||||||
}
|
}
|
||||||
|
|
@ -186,11 +185,11 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
@Inject(method = "onMainNodeStateChanged", at = @At("TAIL"))
|
@Inject(method = "onMainNodeStateChanged", at = @At("TAIL"))
|
||||||
private void eap$compatOnNodeChange(CallbackInfo ci) {
|
private void eap$compatOnNodeChange(CallbackInfo ci) {
|
||||||
try {
|
try {
|
||||||
eap$compatLastChannel = -1;
|
this.eap$compatLastChannel = -1;
|
||||||
eap$compatHasInitialized = false;
|
this.eap$compatHasInitialized = false;
|
||||||
// 直接初始化,不使用延迟
|
// 直接初始化,不使用延迟
|
||||||
eap$compatInitializeChannelLink();
|
this.eap$compatInitializeChannelLink();
|
||||||
mainNode.ifPresent((grid, node) -> {
|
this.mainNode.ifPresent((grid, node) -> {
|
||||||
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
||||||
});
|
});
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
@ -203,22 +202,126 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eap$updateWirelessLink() {
|
public void eap$updateWirelessLink() {
|
||||||
if (eap$compatLink != null) {
|
if (this.eap$compatLink != null) {
|
||||||
eap$compatLink.updateStatus();
|
this.eap$compatLink.updateStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eap$isWirelessConnected() {
|
||||||
|
if (this.host.getBlockEntity() != null && this.host.getBlockEntity().getLevel() != null && this.host.getBlockEntity().getLevel().isClientSide) {
|
||||||
|
return this.eap$compatClientConnected;
|
||||||
|
} else {
|
||||||
|
return this.eap$compatLink != null && this.eap$compatLink.isConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$setClientWirelessState(boolean connected) {
|
||||||
|
this.eap$compatClientConnected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eap$hasTickInitialized() {
|
||||||
|
return this.eap$compatHasInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$setTickInitialized(boolean initialized) {
|
||||||
|
this.eap$compatHasInitialized = initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$handleDelayedInit() {
|
||||||
|
// 如果还未初始化,或者需要重新检查AppliedFlux升级槽
|
||||||
|
if (!this.eap$compatHasInitialized) {
|
||||||
|
this.eap$compatInitializeChannelLink();
|
||||||
|
} else if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
// 安装了AppliedFlux时,定期检查升级槽变化
|
||||||
|
try {
|
||||||
|
IUpgradeInventory afUpgrades = this.eap$getAppliedFluxUpgrades();
|
||||||
|
if (afUpgrades != null && this.eap$hasChannelCard(afUpgrades)) {
|
||||||
|
// 检查频道是否发生变化
|
||||||
|
for (ItemStack stack : afUpgrades) {
|
||||||
|
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
|
||||||
|
long newChannel = ChannelCardItem.getChannel(stack);
|
||||||
|
if (newChannel != this.eap$compatLastChannel) {
|
||||||
|
this.eap$compatLastChannel = -1; // 强制重新初始化
|
||||||
|
this.eap$compatHasInitialized = false;
|
||||||
|
this.eap$compatInitializeChannelLink();
|
||||||
|
this.eap$compatSyncVirtualCraftingState();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.eap$compatLastChannel != 0L) {
|
||||||
|
// 频道卡被移除
|
||||||
|
this.eap$compatLastChannel = -1;
|
||||||
|
this.eap$compatHasInitialized = false;
|
||||||
|
this.eap$compatInitializeChannelLink();
|
||||||
|
this.eap$compatSyncVirtualCraftingState();
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指示 PatternProviderLogic 的 Ticker 是否需要保持慢速 tick 以轮询频道卡或维持无线连接。
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean eap$shouldKeepTicking() {
|
||||||
|
try {
|
||||||
|
// 仅在服务端保持tick
|
||||||
|
if (this.host.getBlockEntity() == null || this.host.getBlockEntity().getLevel() == null || this.host.getBlockEntity().getLevel().isClientSide) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 未初始化:需要继续tick直到初始化完成
|
||||||
|
if (!this.eap$compatHasInitialized) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 安装了 AppliedFlux:根据连接状态与频道卡存在性决定是否维持慢速tick
|
||||||
|
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
|
// 若曾经设置过频道或者当前存在未连通的链接,则保持tick
|
||||||
|
if (this.eap$compatLastChannel != 0L) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (this.eap$compatLink != null && !this.eap$compatLink.isConnected()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
IUpgradeInventory afUpgrades = this.eap$getAppliedFluxUpgrades();
|
||||||
|
if (afUpgrades != null && this.eap$hasChannelCard(afUpgrades)) {
|
||||||
|
// 槽中有频道卡,保持tick以尽快完成连接
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
// 否则可以休眠
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 未安装 AppliedFlux:当存在频道卡但连接尚未建立时保持tick
|
||||||
|
if (this.eap$compatUpgrades != null && this.eap$hasChannelCard(this.eap$compatUpgrades)) {
|
||||||
|
if (this.eap$compatLink == null || !this.eap$compatLink.isConnected()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
public void eap$compatInitializeChannelLink() {
|
private void eap$compatInitializeChannelLink() {
|
||||||
try {
|
try {
|
||||||
// 客户端早退
|
// 客户端早退
|
||||||
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
|
if (this.host.getBlockEntity() != null && this.host.getBlockEntity().getLevel() != null && this.host.getBlockEntity().getLevel().isClientSide) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (eap$compatHasInitialized) {
|
if (this.eap$compatHasInitialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mainNode == null || mainNode.getNode() == null) {
|
if (this.mainNode == null || this.mainNode.getNode() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,7 +335,7 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
// 安装了appflux:优先使用appflux的升级槽
|
// 安装了appflux:优先使用appflux的升级槽
|
||||||
try {
|
try {
|
||||||
// 更安全的方式获取AppliedFlux升级槽
|
// 更安全的方式获取AppliedFlux升级槽
|
||||||
upgrades = eap$getAppliedFluxUpgrades();
|
upgrades = this.eap$getAppliedFluxUpgrades();
|
||||||
if (upgrades != null) {
|
if (upgrades != null) {
|
||||||
} else {
|
} else {
|
||||||
ExtendedAELogger.LOGGER.warn("[样板供应器] 无法获取 appflux 升级槽,回退到兼容槽");
|
ExtendedAELogger.LOGGER.warn("[样板供应器] 无法获取 appflux 升级槽,回退到兼容槽");
|
||||||
|
|
@ -248,20 +351,20 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
}
|
}
|
||||||
|
|
||||||
// 双重保险:如果主要方式失败,尝试备用方式
|
// 双重保险:如果主要方式失败,尝试备用方式
|
||||||
if (upgrades == null || !eap$hasChannelCard(upgrades)) {
|
if (upgrades == null || !this.eap$hasChannelCard(upgrades)) {
|
||||||
|
|
||||||
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
// 如果我们的槽无频道卡,尝试检查是否有AppliedFlux的槽
|
// 如果我们的槽无频道卡,尝试检查是否有AppliedFlux的槽
|
||||||
try {
|
try {
|
||||||
IUpgradeInventory backupUpgrades = eap$getAppliedFluxUpgrades();
|
IUpgradeInventory backupUpgrades = this.eap$getAppliedFluxUpgrades();
|
||||||
if (backupUpgrades != null && eap$hasChannelCard(backupUpgrades)) {
|
if (backupUpgrades != null && this.eap$hasChannelCard(backupUpgrades)) {
|
||||||
upgrades = backupUpgrades;
|
upgrades = backupUpgrades;
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果AppliedFlux的槽无频道卡,尝试我们的兼容槽
|
// 如果AppliedFlux的槽无频道卡,尝试我们的兼容槽
|
||||||
if (this.eap$compatUpgrades != null && eap$hasChannelCard(this.eap$compatUpgrades)) {
|
if (this.eap$compatUpgrades != null && this.eap$hasChannelCard(this.eap$compatUpgrades)) {
|
||||||
upgrades = this.eap$compatUpgrades;
|
upgrades = this.eap$compatUpgrades;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -278,23 +381,26 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
eap$compatSyncVirtualCraftingState();
|
this.eap$compatSyncVirtualCraftingState();
|
||||||
if (eap$compatLink != null) {
|
if (this.eap$compatLink != null) {
|
||||||
eap$compatLink.setFrequency(0L);
|
this.eap$compatLink.setFrequency(0L);
|
||||||
eap$compatLink.updateStatus();
|
this.eap$compatLink.updateStatus();
|
||||||
|
}
|
||||||
|
this.eap$compatLastChannel = 0L;
|
||||||
|
this.eap$compatHasInitialized = true;
|
||||||
|
try {
|
||||||
|
this.host.saveChanges();
|
||||||
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
eap$compatLastChannel = 0L;
|
|
||||||
eap$compatHasInitialized = true;
|
|
||||||
try { host.saveChanges(); } catch (Throwable ignored) {}
|
|
||||||
// 唤醒节点,加速 AE2 感知到连接断开
|
// 唤醒节点,加速 AE2 感知到连接断开
|
||||||
mainNode.ifPresent((grid, node) -> {
|
this.mainNode.ifPresent((grid, node) -> {
|
||||||
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
||||||
// 兜底:如仍存在针对无线主端的直连(非 in-world),强制销毁
|
// 兜底:如仍存在针对无线主端的直连(非 in-world),强制销毁
|
||||||
try {
|
try {
|
||||||
for (IGridConnection gc : node.getConnections()) {
|
for (IGridConnection gc : node.getConnections()) {
|
||||||
if (gc != null && !gc.isInWorld()) {
|
if (gc != null && !gc.isInWorld()) {
|
||||||
var other = gc.getOtherSide(node);
|
var other = gc.getOtherSide(node);
|
||||||
if (other != null && other.getOwner() instanceof com.extendedae_plus.wireless.IWirelessEndpoint) {
|
if (other != null && other.getOwner() instanceof com.extendedae_plus.ae.wireless.IWirelessEndpoint) {
|
||||||
gc.destroy();
|
gc.destroy();
|
||||||
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored2) {}
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored2) {}
|
||||||
try { if (other.getGrid() != null) { other.getGrid().getTickManager().wakeDevice(other); } } catch (Throwable ignored2) {}
|
try { if (other.getGrid() != null) { other.getGrid().getTickManager().wakeDevice(other); } } catch (Throwable ignored2) {}
|
||||||
|
|
@ -306,140 +412,42 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eap$compatLink == null) {
|
if (this.eap$compatLink == null) {
|
||||||
var endpoint = new GenericNodeEndpointImpl(() -> host.getBlockEntity(), () -> this.mainNode.getNode());
|
var endpoint = new GenericNodeEndpointImpl(() -> this.host.getBlockEntity(), () -> this.mainNode.getNode());
|
||||||
eap$compatLink = new WirelessSlaveLink(endpoint);
|
this.eap$compatLink = new WirelessSlaveLink(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
eap$compatLink.setFrequency(channel);
|
this.eap$compatLink.setFrequency(channel);
|
||||||
eap$compatLink.updateStatus();
|
this.eap$compatLink.updateStatus();
|
||||||
eap$compatLastChannel = channel; // 记录当前频道
|
this.eap$compatLastChannel = channel; // 记录当前频道
|
||||||
try { host.saveChanges(); } catch (Throwable ignored) {}
|
try {
|
||||||
mainNode.ifPresent((grid, node) -> {
|
this.host.saveChanges();
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
this.mainNode.ifPresent((grid, node) -> {
|
||||||
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (eap$compatLink.isConnected()) {
|
if (this.eap$compatLink.isConnected()) {
|
||||||
eap$compatHasInitialized = true;
|
this.eap$compatHasInitialized = true;
|
||||||
} else {
|
} else {
|
||||||
eap$compatHasInitialized = false;
|
this.eap$compatHasInitialized = false;
|
||||||
// 如果连接失败,唤醒设备以便稍后重试
|
// 如果连接失败,唤醒设备以便稍后重试
|
||||||
mainNode.ifPresent((grid, node) -> {
|
this.mainNode.ifPresent((grid, node) -> {
|
||||||
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored) {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
eap$compatSyncVirtualCraftingState();
|
this.eap$compatSyncVirtualCraftingState();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
ExtendedAELogger.LOGGER.error("[样板供应器] 初始化频道链接失败", t);
|
ExtendedAELogger.LOGGER.error("[样板供应器] 初始化频道链接失败", t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$setClientWirelessState(boolean connected) {
|
|
||||||
eap$compatClientConnected = connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean eap$isWirelessConnected() {
|
|
||||||
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
|
|
||||||
return eap$compatClientConnected;
|
|
||||||
} else {
|
|
||||||
return eap$compatLink != null && eap$compatLink.isConnected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean eap$hasTickInitialized() {
|
|
||||||
return eap$compatHasInitialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$setTickInitialized(boolean initialized) {
|
|
||||||
eap$compatHasInitialized = initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$handleDelayedInit() {
|
|
||||||
// 如果还未初始化,或者需要重新检查AppliedFlux升级槽
|
|
||||||
if (!eap$compatHasInitialized) {
|
|
||||||
eap$compatInitializeChannelLink();
|
|
||||||
} else if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
|
||||||
// 安装了AppliedFlux时,定期检查升级槽变化
|
|
||||||
try {
|
|
||||||
IUpgradeInventory afUpgrades = eap$getAppliedFluxUpgrades();
|
|
||||||
if (afUpgrades != null && eap$hasChannelCard(afUpgrades)) {
|
|
||||||
// 检查频道是否发生变化
|
|
||||||
for (ItemStack stack : afUpgrades) {
|
|
||||||
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
|
|
||||||
long newChannel = ChannelCardItem.getChannel(stack);
|
|
||||||
if (newChannel != eap$compatLastChannel) {
|
|
||||||
eap$compatLastChannel = -1; // 强制重新初始化
|
|
||||||
eap$compatHasInitialized = false;
|
|
||||||
eap$compatInitializeChannelLink();
|
|
||||||
eap$compatSyncVirtualCraftingState();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (eap$compatLastChannel != 0L) {
|
|
||||||
// 频道卡被移除
|
|
||||||
eap$compatLastChannel = -1;
|
|
||||||
eap$compatHasInitialized = false;
|
|
||||||
eap$compatInitializeChannelLink();
|
|
||||||
eap$compatSyncVirtualCraftingState();
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 指示 PatternProviderLogic 的 Ticker 是否需要保持慢速 tick 以轮询频道卡或维持无线连接。
|
|
||||||
*/
|
|
||||||
public boolean eap$shouldKeepTicking() {
|
|
||||||
try {
|
|
||||||
// 仅在服务端保持tick
|
|
||||||
if (host.getBlockEntity() == null || host.getBlockEntity().getLevel() == null || host.getBlockEntity().getLevel().isClientSide) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 未初始化:需要继续tick直到初始化完成
|
|
||||||
if (!eap$compatHasInitialized) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// 安装了 AppliedFlux:根据连接状态与频道卡存在性决定是否维持慢速tick
|
|
||||||
if (!UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
|
||||||
// 若曾经设置过频道或者当前存在未连通的链接,则保持tick
|
|
||||||
if (eap$compatLastChannel != 0L) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (eap$compatLink != null && !eap$compatLink.isConnected()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
IUpgradeInventory afUpgrades = eap$getAppliedFluxUpgrades();
|
|
||||||
if (afUpgrades != null && eap$hasChannelCard(afUpgrades)) {
|
|
||||||
// 槽中有频道卡,保持tick以尽快完成连接
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {}
|
|
||||||
// 否则可以休眠
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 未安装 AppliedFlux:当存在频道卡但连接尚未建立时保持tick
|
|
||||||
if (this.eap$compatUpgrades != null && eap$hasChannelCard(this.eap$compatUpgrades)) {
|
|
||||||
if (eap$compatLink == null || !eap$compatLink.isConnected()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompatUpgradeProvider 实现:仅在未安装 appflux 时由我们提供升级槽
|
// CompatUpgradeProvider 实现:仅在未安装 appflux 时由我们提供升级槽
|
||||||
@Unique
|
@Unique
|
||||||
private boolean eap$hasChannelCard(IUpgradeInventory inventory) {
|
private boolean eap$hasChannelCard(IUpgradeInventory inventory) {
|
||||||
return eap$compatInventoryContains(inventory, ModItems.CHANNEL_CARD.get());
|
return this.eap$compatInventoryContains(inventory, ModItems.CHANNEL_CARD.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -474,14 +482,14 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
@Inject(method = "pushPattern", at = @At("RETURN"), cancellable = true)
|
@Inject(method = "pushPattern", at = @At("RETURN"), cancellable = true)
|
||||||
private void eap$compatAfterPushPattern(IPatternDetails patternDetails, KeyCounter[] inputHolder, CallbackInfoReturnable<Boolean> cir) {
|
private void eap$compatAfterPushPattern(IPatternDetails patternDetails, KeyCounter[] inputHolder, CallbackInfoReturnable<Boolean> cir) {
|
||||||
if (cir.getReturnValueZ()) {
|
if (cir.getReturnValueZ()) {
|
||||||
eap$compatTryVirtualCompletion(patternDetails);
|
this.eap$compatTryVirtualCompletion(patternDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private void eap$compatTryVirtualCompletion(IPatternDetails patternDetails) {
|
private void eap$compatTryVirtualCompletion(IPatternDetails patternDetails) {
|
||||||
if (!eap$compatVirtualCraftingEnabled) {
|
if (!this.eap$compatVirtualCraftingEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -576,8 +584,8 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
@Unique
|
@Unique
|
||||||
private void eap$compatSyncVirtualCraftingState() {
|
private void eap$compatSyncVirtualCraftingState() {
|
||||||
try {
|
try {
|
||||||
IUpgradeInventory upgrades = eap$compatGetEffectiveUpgrades();
|
IUpgradeInventory upgrades = this.eap$compatGetEffectiveUpgrades();
|
||||||
this.eap$compatVirtualCraftingEnabled = eap$compatInventoryContains(upgrades, ModItems.VIRTUAL_CRAFTING_CARD.get());
|
this.eap$compatVirtualCraftingEnabled = this.eap$compatInventoryContains(upgrades, ModItems.VIRTUAL_CRAFTING_CARD.get());
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
ExtendedAELogger.LOGGER.error("[样板供应器] 同步虚拟合成卡状态失败", t);
|
ExtendedAELogger.LOGGER.error("[样板供应器] 同步虚拟合成卡状态失败", t);
|
||||||
}
|
}
|
||||||
|
|
@ -589,14 +597,14 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
if (UpgradeSlotCompat.shouldEnableUpgradeSlots()) {
|
||||||
upgrades = this.eap$compatUpgrades;
|
upgrades = this.eap$compatUpgrades;
|
||||||
} else {
|
} else {
|
||||||
upgrades = eap$getAppliedFluxUpgrades();
|
upgrades = this.eap$getAppliedFluxUpgrades();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (upgrades == null || upgrades == UpgradeInventories.empty()) {
|
if (upgrades == null || upgrades == UpgradeInventories.empty()) {
|
||||||
if (upgrades != this.eap$compatUpgrades && this.eap$compatUpgrades != null) {
|
if (upgrades != this.eap$compatUpgrades && this.eap$compatUpgrades != null) {
|
||||||
upgrades = this.eap$compatUpgrades;
|
upgrades = this.eap$compatUpgrades;
|
||||||
} else {
|
} else {
|
||||||
var fallback = eap$getAppliedFluxUpgrades();
|
var fallback = this.eap$getAppliedFluxUpgrades();
|
||||||
if (fallback != null) {
|
if (fallback != null) {
|
||||||
upgrades = fallback;
|
upgrades = fallback;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ package com.extendedae_plus.mixin.ae2.helpers;
|
||||||
import appeng.api.upgrades.IUpgradeInventory;
|
import appeng.api.upgrades.IUpgradeInventory;
|
||||||
import appeng.helpers.InterfaceLogic;
|
import appeng.helpers.InterfaceLogic;
|
||||||
import appeng.helpers.InterfaceLogicHost;
|
import appeng.helpers.InterfaceLogicHost;
|
||||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
import com.extendedae_plus.ae.wireless.WirelessSlaveLink;
|
||||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
import com.extendedae_plus.ae.wireless.endpoint.InterfaceNodeEndpointImpl;
|
||||||
|
import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
import com.extendedae_plus.items.materials.ChannelCardItem;
|
||||||
import com.extendedae_plus.wireless.endpoint.InterfaceNodeEndpointImpl;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
@ -19,50 +19,46 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@Mixin(InterfaceLogic.class)
|
@Mixin(InterfaceLogic.class)
|
||||||
public abstract class InterfaceLogicChannelCardMixin implements InterfaceWirelessLinkBridge {
|
public abstract class InterfaceLogicChannelCardMixin implements InterfaceWirelessLinkBridge {
|
||||||
|
|
||||||
@Shadow(remap = false) public abstract IUpgradeInventory getUpgrades();
|
|
||||||
|
|
||||||
@Shadow(remap = false) public abstract appeng.api.networking.IGridNode getActionableNode();
|
|
||||||
|
|
||||||
@Shadow(remap = false) protected InterfaceLogicHost host;
|
|
||||||
|
|
||||||
@Shadow(remap = false) protected appeng.api.networking.IManagedGridNode mainNode;
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private WirelessSlaveLink eap$link;
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private long eap$lastChannel = -1;
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private boolean eap$clientConnected = false;
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private boolean eap$hasInitialized = false;
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private int eap$delayedInitTicks = 0;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// InterfaceLogicChannelCardMixin 已加载
|
// InterfaceLogicChannelCardMixin 已加载
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Shadow(remap = false) protected InterfaceLogicHost host;
|
||||||
|
@Shadow(remap = false) protected appeng.api.networking.IManagedGridNode mainNode;
|
||||||
|
@Unique
|
||||||
|
private WirelessSlaveLink eap$link;
|
||||||
|
@Unique
|
||||||
|
private long eap$lastChannel = -1;
|
||||||
|
@Unique
|
||||||
|
private boolean eap$clientConnected = false;
|
||||||
|
@Unique
|
||||||
|
private boolean eap$hasInitialized = false;
|
||||||
|
@Unique
|
||||||
|
private int eap$delayedInitTicks = 0;
|
||||||
|
|
||||||
|
@Shadow(remap = false)
|
||||||
|
public abstract IUpgradeInventory getUpgrades();
|
||||||
|
|
||||||
|
@Shadow(remap = false)
|
||||||
|
public abstract appeng.api.networking.IGridNode getActionableNode();
|
||||||
|
|
||||||
@Inject(method = "onUpgradesChanged", at = @At("TAIL"), remap = false)
|
@Inject(method = "onUpgradesChanged", at = @At("TAIL"), remap = false)
|
||||||
private void eap$onUpgradesChangedTail(CallbackInfo ci) {
|
private void eap$onUpgradesChangedTail(CallbackInfo ci) {
|
||||||
// 升级变更时重置标志并尝试初始化
|
// 升级变更时重置标志并尝试初始化
|
||||||
eap$lastChannel = -1;
|
this.eap$lastChannel = -1;
|
||||||
eap$hasInitialized = false;
|
this.eap$hasInitialized = false;
|
||||||
eap$initializeChannelLink();
|
this.eap$initializeChannelLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "gridChanged", at = @At("TAIL"), remap = false)
|
@Inject(method = "gridChanged", at = @At("TAIL"), remap = false)
|
||||||
private void eap$afterGridChanged(CallbackInfo ci) {
|
private void eap$afterGridChanged(CallbackInfo ci) {
|
||||||
// 网格状态变化时重置标志并设置延迟初始化
|
// 网格状态变化时重置标志并设置延迟初始化
|
||||||
eap$lastChannel = -1;
|
this.eap$lastChannel = -1;
|
||||||
eap$hasInitialized = false;
|
this.eap$hasInitialized = false;
|
||||||
eap$delayedInitTicks = 10; // 适当增加延迟tick,等待网格完成引导
|
this.eap$delayedInitTicks = 10; // 适当增加延迟tick,等待网格完成引导
|
||||||
// 尝试唤醒设备,确保后续还能继续tick
|
// 尝试唤醒设备,确保后续还能继续tick
|
||||||
if (mainNode != null) {
|
if (this.mainNode != null) {
|
||||||
mainNode.ifPresent((grid, node) -> {
|
this.mainNode.ifPresent((grid, node) -> {
|
||||||
try {
|
try {
|
||||||
grid.getTickManager().wakeDevice(node);
|
grid.getTickManager().wakeDevice(node);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
|
@ -74,40 +70,73 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
|
||||||
@Inject(method = "readFromNBT", at = @At("TAIL"), remap = false)
|
@Inject(method = "readFromNBT", at = @At("TAIL"), remap = false)
|
||||||
private void eap$afterReadNBT(net.minecraft.nbt.CompoundTag tag, net.minecraft.core.HolderLookup.Provider registries, CallbackInfo ci) {
|
private void eap$afterReadNBT(net.minecraft.nbt.CompoundTag tag, net.minecraft.core.HolderLookup.Provider registries, CallbackInfo ci) {
|
||||||
// 从 NBT加载时重置标志
|
// 从 NBT加载时重置标志
|
||||||
eap$lastChannel = -1;
|
this.eap$lastChannel = -1;
|
||||||
eap$hasInitialized = false;
|
this.eap$hasInitialized = false;
|
||||||
// 直接尝试初始化
|
// 直接尝试初始化
|
||||||
eap$initializeChannelLink();
|
this.eap$initializeChannelLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "clearContent", at = @At("HEAD"), remap = false)
|
@Inject(method = "clearContent", at = @At("HEAD"), remap = false)
|
||||||
private void eap$onClearContent(CallbackInfo ci) {
|
private void eap$onClearContent(CallbackInfo ci) {
|
||||||
if (eap$link != null) {
|
if (this.eap$link != null) {
|
||||||
eap$link.onUnloadOrRemove();
|
this.eap$link.onUnloadOrRemove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$updateWirelessLink() {
|
||||||
|
if (this.eap$link != null) {
|
||||||
|
this.eap$link.updateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eap$isWirelessConnected() {
|
||||||
|
// InterfaceLogic没有isClientSide方法,需要通过host判断
|
||||||
|
if (this.host.getBlockEntity() != null && this.host.getBlockEntity().getLevel() != null && this.host.getBlockEntity().getLevel().isClientSide) {
|
||||||
|
return this.eap$clientConnected;
|
||||||
|
} else {
|
||||||
|
return this.eap$link != null && this.eap$link.isConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$setClientWirelessState(boolean connected) {
|
||||||
|
this.eap$clientConnected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eap$hasTickInitialized() {
|
||||||
|
return this.eap$hasInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$setTickInitialized(boolean initialized) {
|
||||||
|
this.eap$hasInitialized = initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Unique
|
@Unique
|
||||||
public void eap$initializeChannelLink() {
|
public void eap$initializeChannelLink() {
|
||||||
// 仅在服务端执行,避免在渲染线程/客户端触发任何初始化路径
|
// 仅在服务端执行,避免在渲染线程/客户端触发任何初始化路径
|
||||||
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
|
if (this.host.getBlockEntity() != null && this.host.getBlockEntity().getLevel() != null && this.host.getBlockEntity().getLevel().isClientSide) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 避免重复初始化
|
// 避免重复初始化
|
||||||
if (eap$hasInitialized) {
|
if (this.eap$hasInitialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 仅要求节点对象可用;不要依赖 isActive(无线连接本身会建立连接与激活节点)
|
// 仅要求节点对象可用;不要依赖 isActive(无线连接本身会建立连接与激活节点)
|
||||||
if (mainNode == null || mainNode.getNode() == null) {
|
if (this.mainNode == null || this.mainNode.getNode() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
long channel = 0L;
|
long channel = 0L;
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (ItemStack stack : getUpgrades()) {
|
for (ItemStack stack : this.getUpgrades()) {
|
||||||
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
|
if (!stack.isEmpty() && stack.getItem() == ModItems.CHANNEL_CARD.get()) {
|
||||||
channel = ChannelCardItem.getChannel(stack);
|
channel = ChannelCardItem.getChannel(stack);
|
||||||
found = true;
|
found = true;
|
||||||
|
|
@ -117,46 +146,52 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
// 无频道卡:断开并视为初始化完成
|
// 无频道卡:断开并视为初始化完成
|
||||||
if (eap$link != null) {
|
if (this.eap$link != null) {
|
||||||
eap$link.setFrequency(0L);
|
this.eap$link.setFrequency(0L);
|
||||||
eap$link.updateStatus();
|
this.eap$link.updateStatus();
|
||||||
}
|
}
|
||||||
eap$hasInitialized = true;
|
this.eap$hasInitialized = true;
|
||||||
// 保存一次状态
|
// 保存一次状态
|
||||||
try { host.saveChanges(); } catch (Throwable ignored) {}
|
try {
|
||||||
|
this.host.saveChanges();
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
// 唤醒设备以刷新客户端/邻居
|
// 唤醒设备以刷新客户端/邻居
|
||||||
try {
|
try {
|
||||||
mainNode.ifPresent((grid, node) -> {
|
this.mainNode.ifPresent((grid, node) -> {
|
||||||
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored2) {}
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored2) {}
|
||||||
});
|
});
|
||||||
} catch (Throwable ignored2) {}
|
} catch (Throwable ignored2) {}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eap$link == null) {
|
if (this.eap$link == null) {
|
||||||
var endpoint = new InterfaceNodeEndpointImpl(host, () -> this.mainNode.getNode());
|
var endpoint = new InterfaceNodeEndpointImpl(this.host, () -> this.mainNode.getNode());
|
||||||
eap$link = new WirelessSlaveLink(endpoint);
|
this.eap$link = new WirelessSlaveLink(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
eap$link.setFrequency(channel);
|
this.eap$link.setFrequency(channel);
|
||||||
eap$link.updateStatus();
|
this.eap$link.updateStatus();
|
||||||
try { host.saveChanges(); } catch (Throwable ignored) {}
|
try {
|
||||||
|
this.host.saveChanges();
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
// 唤醒设备,加速后续 tick 以完成连接
|
// 唤醒设备,加速后续 tick 以完成连接
|
||||||
try {
|
try {
|
||||||
mainNode.ifPresent((grid, node) -> {
|
this.mainNode.ifPresent((grid, node) -> {
|
||||||
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored2) {}
|
try { grid.getTickManager().wakeDevice(node); } catch (Throwable ignored2) {}
|
||||||
});
|
});
|
||||||
} catch (Throwable ignored2) {}
|
} catch (Throwable ignored2) {}
|
||||||
|
|
||||||
if (eap$link.isConnected()) {
|
if (this.eap$link.isConnected()) {
|
||||||
eap$hasInitialized = true; // 设置初始化完成标志
|
this.eap$hasInitialized = true; // 设置初始化完成标志
|
||||||
} else {
|
} else {
|
||||||
// 不标记为完成,允许后续tick重试
|
// 不标记为完成,允许后续tick重试
|
||||||
eap$hasInitialized = false;
|
this.eap$hasInitialized = false;
|
||||||
// 设置一个短延迟窗口,避免每tick刷屏
|
// 设置一个短延迟窗口,避免每tick刷屏
|
||||||
eap$delayedInitTicks = Math.max(eap$delayedInitTicks, 5);
|
this.eap$delayedInitTicks = Math.max(this.eap$delayedInitTicks, 5);
|
||||||
try {
|
try {
|
||||||
mainNode.ifPresent((grid, node) -> {
|
this.mainNode.ifPresent((grid, node) -> {
|
||||||
try {
|
try {
|
||||||
grid.getTickManager().wakeDevice(node);
|
grid.getTickManager().wakeDevice(node);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
|
@ -169,58 +204,26 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$updateWirelessLink() {
|
|
||||||
if (eap$link != null) {
|
|
||||||
eap$link.updateStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean eap$isWirelessConnected() {
|
|
||||||
// InterfaceLogic没有isClientSide方法,需要通过host判断
|
|
||||||
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
|
|
||||||
return eap$clientConnected;
|
|
||||||
} else {
|
|
||||||
return eap$link != null && eap$link.isConnected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$setClientWirelessState(boolean connected) {
|
|
||||||
eap$clientConnected = connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean eap$hasTickInitialized() {
|
|
||||||
return eap$hasInitialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$setTickInitialized(boolean initialized) {
|
|
||||||
eap$hasInitialized = initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eap$handleDelayedInit() {
|
public void eap$handleDelayedInit() {
|
||||||
// 仅在服务端执行延迟初始化,避免在渲染线程/客户端触发任何初始化路径
|
// 仅在服务端执行延迟初始化,避免在渲染线程/客户端触发任何初始化路径
|
||||||
if (host.getBlockEntity() != null && host.getBlockEntity().getLevel() != null && host.getBlockEntity().getLevel().isClientSide) {
|
if (this.host.getBlockEntity() != null && this.host.getBlockEntity().getLevel() != null && this.host.getBlockEntity().getLevel().isClientSide) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 若尚未初始化,则持续尝试,直到网格完成引导
|
// 若尚未初始化,则持续尝试,直到网格完成引导
|
||||||
if (!eap$hasInitialized) {
|
if (!this.eap$hasInitialized) {
|
||||||
// 若节点对象尚未就绪,则等待;无需等待 isActive(无线接入后会激活)
|
// 若节点对象尚未就绪,则等待;无需等待 isActive(无线接入后会激活)
|
||||||
if (mainNode == null || mainNode.getNode() == null) {
|
if (this.mainNode == null || this.mainNode.getNode() == null) {
|
||||||
// 仍在引导,消耗计时器
|
// 仍在引导,消耗计时器
|
||||||
if (eap$delayedInitTicks > 0) {
|
if (this.eap$delayedInitTicks > 0) {
|
||||||
eap$delayedInitTicks--;
|
this.eap$delayedInitTicks--;
|
||||||
}
|
}
|
||||||
if (eap$delayedInitTicks == 0) {
|
if (this.eap$delayedInitTicks == 0) {
|
||||||
// 重新设定一个短延迟窗口,并唤醒设备,以保证后续还能继续 tick
|
// 重新设定一个短延迟窗口,并唤醒设备,以保证后续还能继续 tick
|
||||||
eap$delayedInitTicks = 5;
|
this.eap$delayedInitTicks = 5;
|
||||||
try {
|
try {
|
||||||
mainNode.ifPresent((grid, node) -> {
|
this.mainNode.ifPresent((grid, node) -> {
|
||||||
try {
|
try {
|
||||||
grid.getTickManager().wakeDevice(node);
|
grid.getTickManager().wakeDevice(node);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
|
@ -231,7 +234,7 @@ public abstract class InterfaceLogicChannelCardMixin implements InterfaceWireles
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 网格已引导完成,执行初始化
|
// 网格已引导完成,执行初始化
|
||||||
eap$initializeChannelLink();
|
this.eap$initializeChannelLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.extendedae_plus.mixin.ae2.helpers;
|
package com.extendedae_plus.mixin.ae2.helpers;
|
||||||
|
|
||||||
import appeng.helpers.InterfaceLogic;
|
import appeng.helpers.InterfaceLogic;
|
||||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
@ -27,7 +27,7 @@ public abstract class InterfaceLogicTickerMixin {
|
||||||
if (node != null && node.getLevel() != null && node.getLevel().isClientSide) {
|
if (node != null && node.getLevel() != null && node.getLevel().isClientSide) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this$0 instanceof InterfaceWirelessLinkBridge bridge) {
|
if (this.this$0 instanceof InterfaceWirelessLinkBridge bridge) {
|
||||||
bridge.eap$handleDelayedInit();
|
bridge.eap$handleDelayedInit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +35,7 @@ public abstract class InterfaceLogicTickerMixin {
|
||||||
@Inject(method = "tickingRequest", at = @At("TAIL"), remap = false)
|
@Inject(method = "tickingRequest", at = @At("TAIL"), remap = false)
|
||||||
private void eap$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall,
|
private void eap$tickTail(appeng.api.networking.IGridNode node, int ticksSinceLastCall,
|
||||||
CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {
|
CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {
|
||||||
if (this$0 instanceof InterfaceWirelessLinkBridge bridge) {
|
if (this.this$0 instanceof InterfaceWirelessLinkBridge bridge) {
|
||||||
bridge.eap$updateWirelessLink();
|
bridge.eap$updateWirelessLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import appeng.api.upgrades.IUpgradeInventory;
|
||||||
import appeng.api.upgrades.UpgradeInventories;
|
import appeng.api.upgrades.UpgradeInventories;
|
||||||
import appeng.helpers.InterfaceLogic;
|
import appeng.helpers.InterfaceLogic;
|
||||||
import appeng.helpers.InterfaceLogicHost;
|
import appeng.helpers.InterfaceLogicHost;
|
||||||
import com.extendedae_plus.bridge.CompatUpgradeProvider;
|
import com.extendedae_plus.api.bridge.CompatUpgradeProvider;
|
||||||
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
import com.extendedae_plus.util.ExtendedAELogger;
|
import com.extendedae_plus.util.ExtendedAELogger;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import appeng.api.stacks.AEKey;
|
||||||
import appeng.api.stacks.GenericStack;
|
import appeng.api.stacks.GenericStack;
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogic;
|
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
import appeng.helpers.patternprovider.PatternProviderTarget;
|
import appeng.helpers.patternprovider.PatternProviderTarget;
|
||||||
import com.extendedae_plus.api.AdvancedBlockingHolder;
|
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
|
||||||
import com.extendedae_plus.api.ids.EAPComponents;
|
import com.extendedae_plus.api.ids.EAPComponents;
|
||||||
import net.minecraft.core.HolderLookup;
|
import net.minecraft.core.HolderLookup;
|
||||||
import net.minecraft.core.component.DataComponentMap;
|
import net.minecraft.core.component.DataComponentMap;
|
||||||
|
|
@ -23,7 +23,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@Mixin(value = PatternProviderLogic.class, remap = false)
|
@Mixin(value = PatternProviderLogic.class, remap = false)
|
||||||
public class PatternProviderLogicAdvancedMixin implements AdvancedBlockingHolder {
|
public class PatternProviderLogicAdvancedMixin implements IAdvancedBlocking {
|
||||||
@Unique
|
@Unique
|
||||||
private static final String EAP_ADV_BLOCKING_KEY = "epp_advanced_blocking";
|
private static final String EAP_ADV_BLOCKING_KEY = "epp_advanced_blocking";
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ public class PatternProviderLogicAdvancedMixin implements AdvancedBlockingHolder
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean eap$getAdvancedBlocking() {
|
public boolean eap$getAdvancedBlocking() {
|
||||||
return eap$advancedBlocking;
|
return this.eap$advancedBlocking;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -66,7 +66,7 @@ public class PatternProviderLogicAdvancedMixin implements AdvancedBlockingHolder
|
||||||
|
|
||||||
// 仅当高级阻挡启用时启用“匹配则不阻挡”
|
// 仅当高级阻挡启用时启用“匹配则不阻挡”
|
||||||
if (this.eap$advancedBlocking) {
|
if (this.eap$advancedBlocking) {
|
||||||
if (eap$targetFullyMatchesPatternInputs(adapter, patternDetails)) {
|
if (this.eap$targetFullyMatchesPatternInputs(adapter, patternDetails)) {
|
||||||
// 返回 false 表示“不包含阻挡关键物”,从而不触发 continue,允许发配
|
// 返回 false 表示“不包含阻挡关键物”,从而不触发 continue,允许发配
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ package com.extendedae_plus.mixin.ae2.helpers;
|
||||||
import appeng.api.crafting.IPatternDetails;
|
import appeng.api.crafting.IPatternDetails;
|
||||||
import appeng.crafting.pattern.AEProcessingPattern;
|
import appeng.crafting.pattern.AEProcessingPattern;
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogic;
|
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
import com.extendedae_plus.api.SmartDoublingAwarePattern;
|
|
||||||
import com.extendedae_plus.api.SmartDoublingHolder;
|
|
||||||
import com.extendedae_plus.api.ids.EAPComponents;
|
import com.extendedae_plus.api.ids.EAPComponents;
|
||||||
|
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
|
||||||
|
import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern;
|
||||||
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicPatternsAccessor;
|
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderLogicPatternsAccessor;
|
||||||
import net.minecraft.core.component.DataComponentMap;
|
import net.minecraft.core.component.DataComponentMap;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(value = PatternProviderLogic.class, remap = false)
|
@Mixin(value = PatternProviderLogic.class, remap = false)
|
||||||
public class PatternProviderLogicDoublingMixin implements SmartDoublingHolder {
|
public class PatternProviderLogicDoublingMixin implements ISmartDoubling {
|
||||||
@Unique
|
@Unique
|
||||||
private static final String EAP_SMART_DOUBLING_KEY = "epp_smart_doubling";
|
private static final String EAP_SMART_DOUBLING_KEY = "epp_smart_doubling";
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ public class PatternProviderLogicDoublingMixin implements SmartDoublingHolder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean eap$getSmartDoubling() {
|
public boolean eap$getSmartDoubling() {
|
||||||
return eap$smartDoubling;
|
return this.eap$smartDoubling;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -37,7 +37,7 @@ public class PatternProviderLogicDoublingMixin implements SmartDoublingHolder {
|
||||||
try {
|
try {
|
||||||
var list = ((PatternProviderLogicPatternsAccessor) this).eap$patterns();
|
var list = ((PatternProviderLogicPatternsAccessor) this).eap$patterns();
|
||||||
for (IPatternDetails details : list) {
|
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);
|
aware.eap$setAllowScaling(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +65,7 @@ public class PatternProviderLogicDoublingMixin implements SmartDoublingHolder {
|
||||||
var list = ((PatternProviderLogicPatternsAccessor) this).eap$patterns();
|
var list = ((PatternProviderLogicPatternsAccessor) this).eap$patterns();
|
||||||
boolean allow = this.eap$smartDoubling;
|
boolean allow = this.eap$smartDoubling;
|
||||||
for (IPatternDetails details : list) {
|
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);
|
aware.eap$setAllowScaling(allow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.extendedae_plus.mixin.ae2.helpers.patternprovider;
|
package com.extendedae_plus.mixin.ae2.helpers.patternprovider;
|
||||||
|
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogic;
|
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
@ -27,7 +27,7 @@ public abstract class PatternProviderLogicTickerMixin {
|
||||||
if (node != null && node.getLevel() != null && node.getLevel().isClientSide) {
|
if (node != null && node.getLevel() != null && node.getLevel().isClientSide) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this$0 instanceof InterfaceWirelessLinkBridge bridge) {
|
if (this.this$0 instanceof InterfaceWirelessLinkBridge bridge) {
|
||||||
bridge.eap$handleDelayedInit();
|
bridge.eap$handleDelayedInit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ public abstract class PatternProviderLogicTickerMixin {
|
||||||
if (node != null && node.getLevel() != null && node.getLevel().isClientSide) {
|
if (node != null && node.getLevel() != null && node.getLevel().isClientSide) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this$0 instanceof InterfaceWirelessLinkBridge bridge) {
|
if (this.this$0 instanceof InterfaceWirelessLinkBridge bridge) {
|
||||||
bridge.eap$updateWirelessLink();
|
bridge.eap$updateWirelessLink();
|
||||||
if (bridge.eap$shouldKeepTicking()) {
|
if (bridge.eap$shouldKeepTicking()) {
|
||||||
cir.setReturnValue(appeng.api.networking.ticking.TickRateModulation.SLOWER);
|
cir.setReturnValue(appeng.api.networking.ticking.TickRateModulation.SLOWER);
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,15 @@ import appeng.api.crafting.PatternDetailsHelper;
|
||||||
import appeng.menu.me.items.PatternEncodingTermMenu;
|
import appeng.menu.me.items.PatternEncodingTermMenu;
|
||||||
import appeng.menu.slot.RestrictedInputSlot;
|
import appeng.menu.slot.RestrictedInputSlot;
|
||||||
import appeng.parts.encoding.EncodingMode;
|
import appeng.parts.encoding.EncodingMode;
|
||||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
import com.extendedae_plus.util.uploadPattern.ExtendedAEPatternUploadUtil;
|
||||||
import com.glodblock.github.glodium.network.packet.sync.ActionMap;
|
import com.glodblock.github.glodium.network.packet.sync.ActionMap;
|
||||||
import com.glodblock.github.glodium.network.packet.sync.IActionHolder;
|
import com.glodblock.github.glodium.network.packet.sync.IActionHolder;
|
||||||
|
import net.minecraft.core.component.DataComponents;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import net.minecraft.core.component.DataComponents;
|
|
||||||
import net.minecraft.world.item.component.CustomData;
|
import net.minecraft.world.item.component.CustomData;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
@ -21,9 +21,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 给 AE2 的 PatternEncodingTermMenu 增加一个通用动作持有者,实现接收 EPP 的 CGenericPacket 动作。
|
* 给 AE2 的 PatternEncodingTermMenu 增加一个通用动作持有者,实现接收 EPP 的 CGenericPacket 动作。
|
||||||
* 注册动作 "upload_to_matrix":仅上传“合成图样”到 ExtendedAE 装配矩阵。
|
* 注册动作 "upload_to_matrix":仅上传“合成图样”到 ExtendedAE 装配矩阵。
|
||||||
|
|
@ -53,7 +50,7 @@ public abstract class ContainerPatternEncodingTermMenuMixin implements IActionHo
|
||||||
} else {
|
} else {
|
||||||
// 槽位可能尚未同步到位,继续下一 tick 重试
|
// 槽位可能尚未同步到位,继续下一 tick 重试
|
||||||
if (attemptsLeft > 0) {
|
if (attemptsLeft > 0) {
|
||||||
eap$scheduleUploadWithRetry(sp, menu, attemptsLeft - 1);
|
this.eap$scheduleUploadWithRetry(sp, menu, attemptsLeft - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import appeng.helpers.InterfaceLogicHost;
|
||||||
import appeng.menu.AEBaseMenu;
|
import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.ToolboxMenu;
|
import appeng.menu.ToolboxMenu;
|
||||||
import appeng.menu.implementations.InterfaceMenu;
|
import appeng.menu.implementations.InterfaceMenu;
|
||||||
import com.extendedae_plus.bridge.IUpgradableMenu;
|
import com.extendedae_plus.api.bridge.IUpgradableMenu;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.inventory.MenuType;
|
import net.minecraft.world.inventory.MenuType;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
@ -22,6 +22,10 @@ public abstract class InterfaceMenuUpgradesMixin extends AEBaseMenu implements I
|
||||||
@Unique
|
@Unique
|
||||||
private ToolboxMenu eap$toolbox;
|
private ToolboxMenu eap$toolbox;
|
||||||
|
|
||||||
|
public InterfaceMenuUpgradesMixin(MenuType<?> menuType, int id, Inventory playerInventory, Object host) {
|
||||||
|
super(menuType, id, playerInventory, host);
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/InterfaceLogicHost;)V",
|
@Inject(method = "<init>(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/InterfaceLogicHost;)V",
|
||||||
at = @At("TAIL"))
|
at = @At("TAIL"))
|
||||||
private void eap$initUpgrades(MenuType<?> menuType, int id, Inventory playerInventory, InterfaceLogicHost host, CallbackInfo ci) {
|
private void eap$initUpgrades(MenuType<?> menuType, int id, Inventory playerInventory, InterfaceLogicHost host, CallbackInfo ci) {
|
||||||
|
|
@ -34,8 +38,4 @@ public abstract class InterfaceMenuUpgradesMixin extends AEBaseMenu implements I
|
||||||
public ToolboxMenu eap$getToolbox() {
|
public ToolboxMenu eap$getToolbox() {
|
||||||
return this.eap$toolbox;
|
return this.eap$toolbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InterfaceMenuUpgradesMixin(MenuType<?> menuType, int id, Inventory playerInventory, Object host) {
|
|
||||||
super(menuType, id, playerInventory, host);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
import appeng.menu.AEBaseMenu;
|
import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.guisync.GuiSync;
|
import appeng.menu.guisync.GuiSync;
|
||||||
import appeng.menu.implementations.PatternProviderMenu;
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
import com.extendedae_plus.api.AdvancedBlockingHolder;
|
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuAdvancedSync;
|
import com.extendedae_plus.api.advancedBlocking.IPatternProviderMenuAdvancedSync;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
@ -15,21 +15,20 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
@Mixin(PatternProviderMenu.class)
|
@Mixin(PatternProviderMenu.class)
|
||||||
public abstract class PatternProviderMenuAdvancedMixin implements PatternProviderMenuAdvancedSync {
|
public abstract class PatternProviderMenuAdvancedMixin implements IPatternProviderMenuAdvancedSync {
|
||||||
@Shadow
|
@Shadow
|
||||||
protected PatternProviderLogic logic;
|
protected PatternProviderLogic logic;
|
||||||
|
|
||||||
// 选择一个未占用的 GUI 同步 id(AE2 已用到 7),这里使用 20 以避冲突
|
// 选择一个未占用的 GUI 同步 id(AE2 已用到 7),这里使用 20 以避冲突
|
||||||
@Unique
|
@Unique
|
||||||
@GuiSync(20)
|
@GuiSync(20) private boolean eap$AdvancedBlocking = false;
|
||||||
public boolean eap$AdvancedBlocking = false;
|
|
||||||
|
|
||||||
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
||||||
private void eap$syncAdvancedBlocking(CallbackInfo ci) {
|
private void eap$syncAdvancedBlocking(CallbackInfo ci) {
|
||||||
// 避免@Shadow父类方法,改用公共API:AEBaseMenu#isClientSide()
|
// 避免@Shadow父类方法,改用公共API:AEBaseMenu#isClientSide()
|
||||||
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
||||||
var l = this.logic;
|
var l = this.logic;
|
||||||
if (l instanceof AdvancedBlockingHolder holder) {
|
if (l instanceof IAdvancedBlocking holder) {
|
||||||
this.eap$AdvancedBlocking = holder.eap$getAdvancedBlocking();
|
this.eap$AdvancedBlocking = holder.eap$getAdvancedBlocking();
|
||||||
// debug removed
|
// debug removed
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
import appeng.menu.AEBaseMenu;
|
import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.guisync.GuiSync;
|
import appeng.menu.guisync.GuiSync;
|
||||||
import appeng.menu.implementations.PatternProviderMenu;
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
import com.extendedae_plus.api.PatternProviderMenuDoublingSync;
|
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
|
||||||
import com.extendedae_plus.api.SmartDoublingHolder;
|
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
@ -14,19 +14,18 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(PatternProviderMenu.class)
|
@Mixin(PatternProviderMenu.class)
|
||||||
public abstract class PatternProviderMenuDoublingMixin implements PatternProviderMenuDoublingSync {
|
public abstract class PatternProviderMenuDoublingMixin implements IPatternProviderMenuDoublingSync {
|
||||||
@Shadow
|
@Shadow
|
||||||
protected PatternProviderLogic logic;
|
protected PatternProviderLogic logic;
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
@GuiSync(21)
|
@GuiSync(21) private boolean eap$SmartDoubling = false;
|
||||||
public boolean eap$SmartDoubling = false;
|
|
||||||
|
|
||||||
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
@Inject(method = "broadcastChanges", at = @At("HEAD"))
|
||||||
private void eap$syncSmartDoubling(CallbackInfo ci) {
|
private void eap$syncSmartDoubling(CallbackInfo ci) {
|
||||||
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
if (!((AEBaseMenu) (Object) this).isClientSide()) {
|
||||||
var l = this.logic;
|
var l = this.logic;
|
||||||
if (l instanceof SmartDoublingHolder holder) {
|
if (l instanceof ISmartDoubling holder) {
|
||||||
this.eap$SmartDoubling = holder.eap$getSmartDoubling();
|
this.eap$SmartDoubling = holder.eap$getSmartDoubling();
|
||||||
// debug removed
|
// debug removed
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||||
import appeng.menu.AEBaseMenu;
|
import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.ToolboxMenu;
|
import appeng.menu.ToolboxMenu;
|
||||||
import appeng.menu.implementations.PatternProviderMenu;
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
import com.extendedae_plus.bridge.CompatUpgradeProvider;
|
import com.extendedae_plus.api.bridge.CompatUpgradeProvider;
|
||||||
import com.extendedae_plus.bridge.IUpgradableMenu;
|
import com.extendedae_plus.api.bridge.IUpgradableMenu;
|
||||||
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.inventory.MenuType;
|
import net.minecraft.world.inventory.MenuType;
|
||||||
|
|
@ -26,6 +26,10 @@ public abstract class PatternProviderMenuUpgradesMixin extends AEBaseMenu implem
|
||||||
@Unique
|
@Unique
|
||||||
private ToolboxMenu eap$toolbox;
|
private ToolboxMenu eap$toolbox;
|
||||||
|
|
||||||
|
public PatternProviderMenuUpgradesMixin(MenuType<?> menuType, int id, Inventory playerInventory, Object host) {
|
||||||
|
super(menuType, id, playerInventory, host);
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/patternprovider/PatternProviderLogicHost;)V",
|
@Inject(method = "<init>(Lnet/minecraft/world/inventory/MenuType;ILnet/minecraft/world/entity/player/Inventory;Lappeng/helpers/patternprovider/PatternProviderLogicHost;)V",
|
||||||
at = @At("TAIL"))
|
at = @At("TAIL"))
|
||||||
private void eap$initUpgrades(MenuType<?> menuType, int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) {
|
private void eap$initUpgrades(MenuType<?> menuType, int id, Inventory playerInventory, PatternProviderLogicHost host, CallbackInfo ci) {
|
||||||
|
|
@ -42,8 +46,4 @@ public abstract class PatternProviderMenuUpgradesMixin extends AEBaseMenu implem
|
||||||
public ToolboxMenu eap$getToolbox() {
|
public ToolboxMenu eap$getToolbox() {
|
||||||
return this.eap$toolbox;
|
return this.eap$toolbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PatternProviderMenuUpgradesMixin(MenuType<?> menuType, int id, Inventory playerInventory, Object host) {
|
|
||||||
super(menuType, id, playerInventory, host);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ import appeng.api.networking.security.IActionHost;
|
||||||
import appeng.api.upgrades.IUpgradeInventory;
|
import appeng.api.upgrades.IUpgradeInventory;
|
||||||
import appeng.api.upgrades.IUpgradeableObject;
|
import appeng.api.upgrades.IUpgradeableObject;
|
||||||
import appeng.parts.automation.IOBusPart;
|
import appeng.parts.automation.IOBusPart;
|
||||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
import com.extendedae_plus.ae.wireless.WirelessSlaveLink;
|
||||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
import com.extendedae_plus.ae.wireless.endpoint.GenericNodeEndpointImpl;
|
||||||
|
import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
|
import com.extendedae_plus.items.materials.ChannelCardItem;
|
||||||
import com.extendedae_plus.util.ExtendedAELogger;
|
import com.extendedae_plus.util.ExtendedAELogger;
|
||||||
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
|
||||||
import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
@ -39,16 +39,16 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink
|
||||||
private void eap$onUpgradesChanged(CallbackInfo ci) {
|
private void eap$onUpgradesChanged(CallbackInfo ci) {
|
||||||
// 只在服务端初始化频道链接
|
// 只在服务端初始化频道链接
|
||||||
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
||||||
eap$initializeChannelLink();
|
this.eap$initializeChannelLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "tickingRequest", at = @At("HEAD"))
|
@Inject(method = "tickingRequest", at = @At("HEAD"))
|
||||||
private void eap$beforeTick(appeng.api.networking.IGridNode node, int ticksSinceLastCall, org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {
|
private void eap$beforeTick(appeng.api.networking.IGridNode node, int ticksSinceLastCall, org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable<appeng.api.networking.ticking.TickRateModulation> cir) {
|
||||||
// 在第一次tick时初始化频道链接(此时网格节点已经在线)
|
// 在第一次tick时初始化频道链接(此时网格节点已经在线)
|
||||||
if (!eap$hasTickInitialized && !((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
if (!this.eap$hasTickInitialized && !((appeng.parts.AEBasePart) (Object) this).isClientSide()) {
|
||||||
eap$hasTickInitialized = true;
|
this.eap$hasTickInitialized = true;
|
||||||
eap$initializeChannelLink();
|
this.eap$initializeChannelLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,11 +56,33 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink
|
||||||
private void eap$afterReadFromNBT(CompoundTag extra, net.minecraft.core.HolderLookup.Provider registries, CallbackInfo ci) {
|
private void eap$afterReadFromNBT(CompoundTag extra, net.minecraft.core.HolderLookup.Provider registries, CallbackInfo ci) {
|
||||||
// 从NBT加载时重置频道缓存和tick初始化标志
|
// 从NBT加载时重置频道缓存和tick初始化标志
|
||||||
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
||||||
eap$lastChannel = -1;
|
this.eap$lastChannel = -1;
|
||||||
eap$hasTickInitialized = false; // 重置标志,允许再次初始化
|
this.eap$hasTickInitialized = false; // 重置标志,允许再次初始化
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$updateWirelessLink() {
|
||||||
|
if (this.eap$link != null) {
|
||||||
|
this.eap$link.updateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eap$isWirelessConnected() {
|
||||||
|
if (((appeng.parts.AEBasePart) (Object) this).isClientSide()) {
|
||||||
|
return this.eap$clientConnected;
|
||||||
|
} else {
|
||||||
|
return this.eap$link != null && this.eap$link.isConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$setClientWirelessState(boolean connected) {
|
||||||
|
this.eap$clientConnected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Unique
|
@Unique
|
||||||
public void eap$initializeChannelLink() {
|
public void eap$initializeChannelLink() {
|
||||||
// 防止重复调用
|
// 防止重复调用
|
||||||
|
|
@ -81,33 +103,33 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink
|
||||||
}
|
}
|
||||||
|
|
||||||
// 频道没有变化则跳过
|
// 频道没有变化则跳过
|
||||||
if (eap$lastChannel == channel) {
|
if (this.eap$lastChannel == channel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eap$lastChannel = channel;
|
this.eap$lastChannel = channel;
|
||||||
|
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
// 无频道卡则断开
|
// 无频道卡则断开
|
||||||
if (eap$link != null) {
|
if (this.eap$link != null) {
|
||||||
eap$link.setFrequency(0L);
|
this.eap$link.setFrequency(0L);
|
||||||
eap$link.updateStatus();
|
this.eap$link.updateStatus();
|
||||||
// 立即通知客户端状态变化(断开连接无需延迟)
|
// 立即通知客户端状态变化(断开连接无需延迟)
|
||||||
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
|
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eap$link == null) {
|
if (this.eap$link == null) {
|
||||||
var endpoint = new GenericNodeEndpointImpl(
|
var endpoint = new GenericNodeEndpointImpl(
|
||||||
() -> ((appeng.parts.AEBasePart)(Object)this).getHost().getBlockEntity(),
|
() -> ((appeng.parts.AEBasePart)(Object)this).getHost().getBlockEntity(),
|
||||||
() -> ((IActionHost)(Object)this).getActionableNode()
|
() -> ((IActionHost)(Object)this).getActionableNode()
|
||||||
);
|
);
|
||||||
eap$link = new WirelessSlaveLink(endpoint);
|
this.eap$link = new WirelessSlaveLink(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
eap$link.setFrequency(channel);
|
this.eap$link.setFrequency(channel);
|
||||||
eap$link.updateStatus();
|
this.eap$link.updateStatus();
|
||||||
|
|
||||||
// 通知客户端状态变化
|
// 通知客户端状态变化
|
||||||
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
|
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
|
||||||
|
|
@ -115,25 +137,4 @@ public abstract class IOBusPartChannelCardMixin implements InterfaceWirelessLink
|
||||||
ExtendedAELogger.LOGGER.error("[服务端] IOBus 初始化频道链接失败", e);
|
ExtendedAELogger.LOGGER.error("[服务端] IOBus 初始化频道链接失败", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$updateWirelessLink() {
|
|
||||||
if (eap$link != null) {
|
|
||||||
eap$link.updateStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean eap$isWirelessConnected() {
|
|
||||||
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
|
||||||
return eap$clientConnected;
|
|
||||||
} else {
|
|
||||||
return eap$link != null && eap$link.isConnected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$setClientWirelessState(boolean connected) {
|
|
||||||
eap$clientConnected = connected;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@ import appeng.api.networking.security.IActionHost;
|
||||||
import appeng.api.upgrades.IUpgradeInventory;
|
import appeng.api.upgrades.IUpgradeInventory;
|
||||||
import appeng.api.upgrades.IUpgradeableObject;
|
import appeng.api.upgrades.IUpgradeableObject;
|
||||||
import appeng.parts.storagebus.StorageBusPart;
|
import appeng.parts.storagebus.StorageBusPart;
|
||||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
import com.extendedae_plus.ae.wireless.WirelessSlaveLink;
|
||||||
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
|
import com.extendedae_plus.ae.wireless.endpoint.GenericNodeEndpointImpl;
|
||||||
|
import com.extendedae_plus.api.bridge.InterfaceWirelessLinkBridge;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
|
import com.extendedae_plus.items.materials.ChannelCardItem;
|
||||||
import com.extendedae_plus.util.ExtendedAELogger;
|
import com.extendedae_plus.util.ExtendedAELogger;
|
||||||
import com.extendedae_plus.wireless.WirelessSlaveLink;
|
|
||||||
import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
|
@ -37,7 +37,7 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles
|
||||||
private void eap$onUpgradesChanged(CallbackInfo ci) {
|
private void eap$onUpgradesChanged(CallbackInfo ci) {
|
||||||
// 只在服务端初始化频道链接
|
// 只在服务端初始化频道链接
|
||||||
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
||||||
eap$initializeChannelLink();
|
this.eap$initializeChannelLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles
|
||||||
private void eap$onMainNodeStateChanged(IGridNodeListener.State reason, CallbackInfo ci) {
|
private void eap$onMainNodeStateChanged(IGridNodeListener.State reason, CallbackInfo ci) {
|
||||||
// 在节点状态变化时(包括加载后的GRID_BOOT)重新初始化频道链接
|
// 在节点状态变化时(包括加载后的GRID_BOOT)重新初始化频道链接
|
||||||
if (reason == IGridNodeListener.State.GRID_BOOT && !((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
if (reason == IGridNodeListener.State.GRID_BOOT && !((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
||||||
eap$initializeChannelLink();
|
this.eap$initializeChannelLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,11 +54,33 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles
|
||||||
// 从NBT加载后也重新初始化频道链接(只在服务端)
|
// 从NBT加载后也重新初始化频道链接(只在服务端)
|
||||||
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
if (!((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
||||||
// 从NBT加载时重置频道缓存,强制重新初始化
|
// 从NBT加载时重置频道缓存,强制重新初始化
|
||||||
eap$lastChannel = -1;
|
this.eap$lastChannel = -1;
|
||||||
eap$initializeChannelLink();
|
this.eap$initializeChannelLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$updateWirelessLink() {
|
||||||
|
if (this.eap$link != null) {
|
||||||
|
this.eap$link.updateStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eap$isWirelessConnected() {
|
||||||
|
if (((appeng.parts.AEBasePart) (Object) this).isClientSide()) {
|
||||||
|
return this.eap$clientConnected;
|
||||||
|
} else {
|
||||||
|
return this.eap$link != null && this.eap$link.isConnected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eap$setClientWirelessState(boolean connected) {
|
||||||
|
this.eap$clientConnected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@Unique
|
@Unique
|
||||||
public void eap$initializeChannelLink() {
|
public void eap$initializeChannelLink() {
|
||||||
// 防止重复调用
|
// 防止重复调用
|
||||||
|
|
@ -79,32 +101,32 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles
|
||||||
}
|
}
|
||||||
|
|
||||||
// 频道没有变化则跳过
|
// 频道没有变化则跳过
|
||||||
if (eap$lastChannel == channel) {
|
if (this.eap$lastChannel == channel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eap$lastChannel = channel;
|
this.eap$lastChannel = channel;
|
||||||
|
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
if (eap$link != null) {
|
if (this.eap$link != null) {
|
||||||
eap$link.setFrequency(0L);
|
this.eap$link.setFrequency(0L);
|
||||||
eap$link.updateStatus();
|
this.eap$link.updateStatus();
|
||||||
// 通知客户端状态变化
|
// 通知客户端状态变化
|
||||||
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
|
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eap$link == null) {
|
if (this.eap$link == null) {
|
||||||
var endpoint = new GenericNodeEndpointImpl(
|
var endpoint = new GenericNodeEndpointImpl(
|
||||||
() -> ((appeng.parts.AEBasePart)(Object)this).getHost().getBlockEntity(),
|
() -> ((appeng.parts.AEBasePart)(Object)this).getHost().getBlockEntity(),
|
||||||
() -> ((IActionHost)(Object)this).getActionableNode()
|
() -> ((IActionHost)(Object)this).getActionableNode()
|
||||||
);
|
);
|
||||||
eap$link = new WirelessSlaveLink(endpoint);
|
this.eap$link = new WirelessSlaveLink(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
eap$link.setFrequency(channel);
|
this.eap$link.setFrequency(channel);
|
||||||
eap$link.updateStatus();
|
this.eap$link.updateStatus();
|
||||||
|
|
||||||
// 通知客户端状态变化
|
// 通知客户端状态变化
|
||||||
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
|
((appeng.parts.AEBasePart)(Object)this).getHost().markForUpdate();
|
||||||
|
|
@ -112,25 +134,4 @@ public abstract class StorageBusPartChannelCardMixin implements InterfaceWireles
|
||||||
ExtendedAELogger.LOGGER.error("[服务端] StorageBus 初始化频道链接失败", e);
|
ExtendedAELogger.LOGGER.error("[服务端] StorageBus 初始化频道链接失败", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$updateWirelessLink() {
|
|
||||||
if (eap$link != null) {
|
|
||||||
eap$link.updateStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean eap$isWirelessConnected() {
|
|
||||||
if (((appeng.parts.AEBasePart)(Object)this).isClientSide()) {
|
|
||||||
return eap$clientConnected;
|
|
||||||
} else {
|
|
||||||
return eap$link != null && eap$link.isConnected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eap$setClientWirelessState(boolean connected) {
|
|
||||||
eap$clientConnected = connected;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,9 @@ import appeng.client.gui.implementations.PatternProviderScreen;
|
||||||
import appeng.client.gui.style.ScreenStyle;
|
import appeng.client.gui.style.ScreenStyle;
|
||||||
import appeng.menu.SlotSemantics;
|
import appeng.menu.SlotSemantics;
|
||||||
import appeng.menu.slot.AppEngSlot;
|
import appeng.menu.slot.AppEngSlot;
|
||||||
import com.extendedae_plus.NewIcon;
|
import com.extendedae_plus.api.IExPatternButton;
|
||||||
import com.extendedae_plus.api.ExPatternButtonsAccessor;
|
import com.extendedae_plus.api.IExPatternPage;
|
||||||
|
import com.extendedae_plus.client.gui.NewIcon;
|
||||||
import com.extendedae_plus.config.ModConfigs;
|
import com.extendedae_plus.config.ModConfigs;
|
||||||
import com.extendedae_plus.network.ScalePatternsC2SPacket;
|
import com.extendedae_plus.network.ScalePatternsC2SPacket;
|
||||||
import com.glodblock.github.extendedae.client.button.ActionEPPButton;
|
import com.glodblock.github.extendedae.client.button.ActionEPPButton;
|
||||||
|
|
@ -27,38 +28,63 @@ import java.lang.reflect.Method;
|
||||||
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
|
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
|
||||||
|
|
||||||
@Mixin(value = GuiExPatternProvider.class, remap = false)
|
@Mixin(value = GuiExPatternProvider.class, remap = false)
|
||||||
public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<ContainerExPatternProvider> implements ExPatternButtonsAccessor, com.extendedae_plus.api.ExPatternPageAccessor {
|
public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<ContainerExPatternProvider> implements IExPatternButton, IExPatternPage {
|
||||||
|
|
||||||
@Unique
|
|
||||||
ScreenStyle eap$screenStyle;
|
|
||||||
|
|
||||||
// 跟踪上次屏幕尺寸,处理 GUI 缩放/窗口大小变化后按钮丢失问题
|
|
||||||
@Unique private int eap$lastScreenWidth = -1;
|
|
||||||
@Unique private int eap$lastScreenHeight = -1;
|
|
||||||
|
|
||||||
// 不再使用右侧 VerticalButtonBar,直接把按钮注册为独立 AE2 小部件
|
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private static final int SLOTS_PER_PAGE = 36; // 每页显示36个槽位
|
private static final int SLOTS_PER_PAGE = 36; // 每页显示36个槽位
|
||||||
|
@Unique private
|
||||||
|
ScreenStyle eap$screenStyle;
|
||||||
|
// 跟踪上次屏幕尺寸,处理 GUI 缩放/窗口大小变化后按钮丢失问题
|
||||||
|
@Unique private int eap$lastScreenWidth = -1;
|
||||||
|
|
||||||
|
// 不再使用右侧 VerticalButtonBar,直接把按钮注册为独立 AE2 小部件
|
||||||
|
@Unique private int eap$lastScreenHeight = -1;
|
||||||
@Unique
|
@Unique
|
||||||
private int eap$currentPage = 0;
|
private int eap$currentPage = 0;
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private int eap$maxPageLocal = 1;
|
private int eap$maxPageLocal = 1;
|
||||||
|
private ActionEPPButton nextPage;
|
||||||
public GuiExPatternProviderMixin(ContainerExPatternProvider menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
|
||||||
super(menu, playerInventory, title, style);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 移除手动挪动 Slot 坐标,交由 SlotGridLayout + 原生布局控制
|
// 移除手动挪动 Slot 坐标,交由 SlotGridLayout + 原生布局控制
|
||||||
|
private ActionEPPButton prevPage;
|
||||||
|
private ActionEPPButton x2Button;
|
||||||
|
private ActionEPPButton divideBy2Button;
|
||||||
|
private ActionEPPButton x5Button;
|
||||||
|
private ActionEPPButton divideBy5Button;
|
||||||
|
private ActionEPPButton x10Button;
|
||||||
|
private ActionEPPButton divideBy10Button;
|
||||||
|
public GuiExPatternProviderMixin(ContainerExPatternProvider menu, Inventory playerInventory, Component title, ScreenStyle style) {
|
||||||
|
super(menu, playerInventory, title, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static Field eap$findFieldRecursive(Class<?> cls, String name) {
|
||||||
|
Class<?> c = cls;
|
||||||
|
while (c != null && c != Object.class) {
|
||||||
|
try {
|
||||||
|
return c.getDeclaredField(name);
|
||||||
|
} catch (NoSuchFieldException ignored) {}
|
||||||
|
c = c.getSuperclass();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private static void eap$setIntFieldRecursive(Object obj, String name, int value) {
|
||||||
|
if (obj == null) return;
|
||||||
|
Field f = eap$findFieldRecursive(obj.getClass(), name);
|
||||||
|
if (f != null) {
|
||||||
|
try { f.setAccessible(true); f.set(obj, value); } catch (Throwable ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private int getCurrentPage() {
|
private int getCurrentPage() {
|
||||||
// 优先使用本地 GUI 维护的页码
|
// 优先使用本地 GUI 维护的页码
|
||||||
return Math.max(0, eap$currentPage % Math.max(1, eap$maxPageLocal));
|
return Math.max(0, this.eap$currentPage % Math.max(1, this.eap$maxPageLocal));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
|
|
@ -85,36 +111,6 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
|
||||||
private static Field eap$findFieldRecursive(Class<?> cls, String name) {
|
|
||||||
Class<?> c = cls;
|
|
||||||
while (c != null && c != Object.class) {
|
|
||||||
try {
|
|
||||||
return c.getDeclaredField(name);
|
|
||||||
} catch (NoSuchFieldException ignored) {}
|
|
||||||
c = c.getSuperclass();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private static void eap$setIntFieldRecursive(Object obj, String name, int value) {
|
|
||||||
if (obj == null) return;
|
|
||||||
Field f = eap$findFieldRecursive(obj.getClass(), name);
|
|
||||||
if (f != null) {
|
|
||||||
try { f.setAccessible(true); f.set(obj, value); } catch (Throwable ignored) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionEPPButton nextPage;
|
|
||||||
public ActionEPPButton prevPage;
|
|
||||||
public ActionEPPButton x2Button;
|
|
||||||
public ActionEPPButton divideBy2Button;
|
|
||||||
public ActionEPPButton x5Button;
|
|
||||||
public ActionEPPButton divideBy5Button;
|
|
||||||
public ActionEPPButton x10Button;
|
|
||||||
public ActionEPPButton divideBy10Button;
|
|
||||||
|
|
||||||
// 在构造器返回后初始化按钮与翻页控制
|
// 在构造器返回后初始化按钮与翻页控制
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
private void injectInit(ContainerExPatternProvider menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
private void injectInit(ContainerExPatternProvider menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {
|
||||||
|
|
@ -139,8 +135,8 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
||||||
// 翻页按钮(当存在多页时显示;支持仅由配置决定的“空白页”)
|
// 翻页按钮(当存在多页时显示;支持仅由配置决定的“空白页”)
|
||||||
if (desiredMaxPage > 1) {
|
if (desiredMaxPage > 1) {
|
||||||
this.prevPage = new ActionEPPButton((b) -> {
|
this.prevPage = new ActionEPPButton((b) -> {
|
||||||
int currentPage = getCurrentPage();
|
int currentPage = this.getCurrentPage();
|
||||||
int maxPage = Math.max(this.eap$maxPageLocal, getMaxPage());
|
int maxPage = Math.max(this.eap$maxPageLocal, this.getMaxPage());
|
||||||
int newPage = (currentPage - 1 + maxPage) % maxPage;
|
int newPage = (currentPage - 1 + maxPage) % maxPage;
|
||||||
try {
|
try {
|
||||||
ContainerExPatternProvider menu1 = this.getMenu();
|
ContainerExPatternProvider menu1 = this.getMenu();
|
||||||
|
|
@ -164,12 +160,12 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
||||||
this.repositionSlots(SlotSemantics.STORAGE);
|
this.repositionSlots(SlotSemantics.STORAGE);
|
||||||
this.hoveredSlot = null;
|
this.hoveredSlot = null;
|
||||||
// 更新当前页可见状态
|
// 更新当前页可见状态
|
||||||
eap$updatePageSlotActivity();
|
this.eap$updatePageSlotActivity();
|
||||||
}, Icon.ARROW_LEFT);
|
}, Icon.ARROW_LEFT);
|
||||||
|
|
||||||
this.nextPage = new ActionEPPButton((b) -> {
|
this.nextPage = new ActionEPPButton((b) -> {
|
||||||
int currentPage = getCurrentPage();
|
int currentPage = this.getCurrentPage();
|
||||||
int maxPage = Math.max(this.eap$maxPageLocal, getMaxPage());
|
int maxPage = Math.max(this.eap$maxPageLocal, this.getMaxPage());
|
||||||
int newPage = (currentPage + 1) % maxPage;
|
int newPage = (currentPage + 1) % maxPage;
|
||||||
try {
|
try {
|
||||||
ContainerExPatternProvider menu1 = this.getMenu();
|
ContainerExPatternProvider menu1 = this.getMenu();
|
||||||
|
|
@ -193,7 +189,7 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
||||||
this.repositionSlots(SlotSemantics.STORAGE);
|
this.repositionSlots(SlotSemantics.STORAGE);
|
||||||
this.hoveredSlot = null;
|
this.hoveredSlot = null;
|
||||||
// 更新当前页可见状态
|
// 更新当前页可见状态
|
||||||
eap$updatePageSlotActivity();
|
this.eap$updatePageSlotActivity();
|
||||||
}, Icon.ARROW_RIGHT);
|
}, Icon.ARROW_RIGHT);
|
||||||
|
|
||||||
// 恢复到 AE2 左侧工具栏
|
// 恢复到 AE2 左侧工具栏
|
||||||
|
|
@ -249,7 +245,7 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int eap$getCurrentPage() {
|
public int eap$getCurrentPage() {
|
||||||
return getCurrentPage();
|
return this.getCurrentPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页码文本绘制移交给 AEBaseScreenMixin.renderLabels 尾部执行
|
// 页码文本绘制移交给 AEBaseScreenMixin.renderLabels 尾部执行
|
||||||
|
|
@ -259,26 +255,26 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
||||||
@Override
|
@Override
|
||||||
public void eap$updateButtonsLayout() {
|
public void eap$updateButtonsLayout() {
|
||||||
// 只处理按钮可见性与定位,不再强制 showPage 或挪动 Slot 坐标,避免与原布局/tooltip 冲突
|
// 只处理按钮可见性与定位,不再强制 showPage 或挪动 Slot 坐标,避免与原布局/tooltip 冲突
|
||||||
if (nextPage != null && prevPage != null) {
|
if (this.nextPage != null && this.prevPage != null) {
|
||||||
this.nextPage.setVisibility(true);
|
this.nextPage.setVisibility(true);
|
||||||
this.prevPage.setVisibility(true);
|
this.prevPage.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (x2Button != null) {
|
if (this.x2Button != null) {
|
||||||
this.x2Button.setVisibility(true);
|
this.x2Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (divideBy2Button != null) {
|
if (this.divideBy2Button != null) {
|
||||||
this.divideBy2Button.setVisibility(true);
|
this.divideBy2Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (x10Button != null) {
|
if (this.x10Button != null) {
|
||||||
this.x10Button.setVisibility(true);
|
this.x10Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (divideBy10Button != null) {
|
if (this.divideBy10Button != null) {
|
||||||
this.divideBy10Button.setVisibility(true);
|
this.divideBy10Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (divideBy5Button != null) {
|
if (this.divideBy5Button != null) {
|
||||||
this.divideBy5Button.setVisibility(true);
|
this.divideBy5Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
if (x5Button != null) {
|
if (this.x5Button != null) {
|
||||||
this.x5Button.setVisibility(true);
|
this.x5Button.setVisibility(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,9 +302,9 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
||||||
} catch (Throwable ignored) {}
|
} catch (Throwable ignored) {}
|
||||||
|
|
||||||
// 如果屏幕尺寸发生变化(窗口/GUI缩放),重新注册右侧外列的自定义按钮,翻页按钮由左侧工具栏托管
|
// 如果屏幕尺寸发生变化(窗口/GUI缩放),重新注册右侧外列的自定义按钮,翻页按钮由左侧工具栏托管
|
||||||
if (this.width != eap$lastScreenWidth || this.height != eap$lastScreenHeight) {
|
if (this.width != this.eap$lastScreenWidth || this.height != this.eap$lastScreenHeight) {
|
||||||
eap$lastScreenWidth = this.width;
|
this.eap$lastScreenWidth = this.width;
|
||||||
eap$lastScreenHeight = this.height;
|
this.eap$lastScreenHeight = this.height;
|
||||||
try {
|
try {
|
||||||
if (this.divideBy2Button != null) {
|
if (this.divideBy2Button != null) {
|
||||||
this.removeWidget(this.divideBy2Button);
|
this.removeWidget(this.divideBy2Button);
|
||||||
|
|
@ -368,7 +364,7 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
||||||
}
|
}
|
||||||
|
|
||||||
// 每帧确保当前页槽位处于启用状态,非当前页禁用
|
// 每帧确保当前页槽位处于启用状态,非当前页禁用
|
||||||
eap$updatePageSlotActivity();
|
this.eap$updatePageSlotActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 本文件原包含本地样板缩放实现(单机模式)和 ExtendedAE 网络派发,已移除以兼容 1.21.1 与最小可构建集。
|
// 本文件原包含本地样板缩放实现(单机模式)和 ExtendedAE 网络派发,已移除以兼容 1.21.1 与最小可构建集。
|
||||||
|
|
@ -381,7 +377,7 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
||||||
var list = this.getMenu().getSlots(SlotSemantics.ENCODED_PATTERN);
|
var list = this.getMenu().getSlots(SlotSemantics.ENCODED_PATTERN);
|
||||||
if (list == null || list.isEmpty()) return;
|
if (list == null || list.isEmpty()) return;
|
||||||
|
|
||||||
int currentPage = getCurrentPage();
|
int currentPage = this.getCurrentPage();
|
||||||
int base = currentPage * SLOTS_PER_PAGE;
|
int base = currentPage * SLOTS_PER_PAGE;
|
||||||
int end = Math.min(list.size(), base + SLOTS_PER_PAGE);
|
int end = Math.min(list.size(), base + SLOTS_PER_PAGE);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package com.extendedae_plus.mixin.jei;
|
||||||
|
|
||||||
import appeng.integration.modules.itemlists.EncodingHelper;
|
import appeng.integration.modules.itemlists.EncodingHelper;
|
||||||
import appeng.menu.me.items.PatternEncodingTermMenu;
|
import appeng.menu.me.items.PatternEncodingTermMenu;
|
||||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
import com.extendedae_plus.util.uploadPattern.ExtendedAEPatternUploadUtil;
|
||||||
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
|
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package com.extendedae_plus.mixin.jei;
|
||||||
import appeng.integration.modules.itemlists.EncodingHelper;
|
import appeng.integration.modules.itemlists.EncodingHelper;
|
||||||
import appeng.integration.modules.rei.transfer.EncodePatternTransferHandler;
|
import appeng.integration.modules.rei.transfer.EncodePatternTransferHandler;
|
||||||
import appeng.menu.me.items.PatternEncodingTermMenu;
|
import appeng.menu.me.items.PatternEncodingTermMenu;
|
||||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
import com.extendedae_plus.util.uploadPattern.ExtendedAEPatternUploadUtil;
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
package com.extendedae_plus.network;
|
package com.extendedae_plus.network;
|
||||||
|
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.ae.items.ChannelCardItem;
|
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
import com.extendedae_plus.util.WirelessTeamUtil;
|
import com.extendedae_plus.items.materials.ChannelCardItem;
|
||||||
|
import com.extendedae_plus.util.wireless.WirelessTeamUtil;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
|
|
@ -37,11 +37,6 @@ public class ChannelCardBindPacket implements CustomPacketPayload {
|
||||||
this.hand = hand;
|
this.hand = hand;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final ChannelCardBindPacket msg, final IPayloadContext ctx) {
|
public static void handle(final ChannelCardBindPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
if (!(ctx.player() instanceof ServerPlayer player)) {
|
if (!(ctx.player() instanceof ServerPlayer player)) {
|
||||||
|
|
@ -79,5 +74,10 @@ public class ChannelCardBindPacket implements CustomPacketPayload {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,31 +3,31 @@ package com.extendedae_plus.network;
|
||||||
import appeng.api.config.Settings;
|
import appeng.api.config.Settings;
|
||||||
import appeng.api.config.YesNo;
|
import appeng.api.config.YesNo;
|
||||||
import appeng.api.networking.IGrid;
|
import appeng.api.networking.IGrid;
|
||||||
|
import appeng.api.networking.IInWorldGridNodeHost;
|
||||||
import appeng.blockentity.crafting.PatternProviderBlockEntity;
|
import appeng.blockentity.crafting.PatternProviderBlockEntity;
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogic;
|
import appeng.helpers.patternprovider.PatternProviderLogic;
|
||||||
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
import appeng.helpers.patternprovider.PatternProviderLogicHost;
|
||||||
import appeng.parts.crafting.PatternProviderPart;
|
import appeng.parts.crafting.PatternProviderPart;
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.api.AdvancedBlockingHolder;
|
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
|
||||||
import com.extendedae_plus.api.SmartDoublingHolder;
|
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
|
||||||
import appeng.api.networking.IInWorldGridNodeHost;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C2S:全网批量切换样板供应器的三种模式:
|
* C2S:全网批量切换样板供应器的三种模式:
|
||||||
* - 阻挡模式(AE2 内置 BLOCKING_MODE 设置)
|
* - 阻挡模式(AE2 内置 BLOCKING_MODE 设置)
|
||||||
* - 高级阻挡模式(AdvancedBlockingHolder mixin)
|
* - 高级阻挡模式(IAdvancedBlocking mixin)
|
||||||
* - 智能翻倍模式(SmartDoublingHolder mixin)
|
* - 智能翻倍模式(ISmartDoubling mixin)
|
||||||
*
|
*
|
||||||
* 负载为三个操作码(各1字节),分别对应:blocking、advancedBlocking、smartDoubling。
|
* 负载为三个操作码(各1字节),分别对应:blocking、advancedBlocking、smartDoubling。
|
||||||
*/
|
*/
|
||||||
|
|
@ -44,28 +44,10 @@ public class GlobalToggleProviderModesC2SPacket implements CustomPacketPayload {
|
||||||
},
|
},
|
||||||
buf -> new GlobalToggleProviderModesC2SPacket(Op.byId(buf.readByte()), Op.byId(buf.readByte()), Op.byId(buf.readByte()), buf.readBlockPos())
|
buf -> new GlobalToggleProviderModesC2SPacket(Op.byId(buf.readByte()), Op.byId(buf.readByte()), Op.byId(buf.readByte()), buf.readBlockPos())
|
||||||
);
|
);
|
||||||
public enum Op {
|
|
||||||
NOOP((byte) 0),
|
|
||||||
SET_TRUE((byte) 1),
|
|
||||||
SET_FALSE((byte) 2),
|
|
||||||
TOGGLE((byte) 3);
|
|
||||||
public final byte id;
|
|
||||||
Op(byte id) { this.id = id; }
|
|
||||||
public static Op byId(byte id) {
|
|
||||||
return switch (id) {
|
|
||||||
case 1 -> SET_TRUE;
|
|
||||||
case 2 -> SET_FALSE;
|
|
||||||
case 3 -> TOGGLE;
|
|
||||||
default -> NOOP;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Op opBlocking;
|
private final Op opBlocking;
|
||||||
private final Op opAdvancedBlocking;
|
private final Op opAdvancedBlocking;
|
||||||
private final Op opSmartDoubling;
|
private final Op opSmartDoubling;
|
||||||
private final BlockPos controllerPos;
|
private final BlockPos controllerPos;
|
||||||
|
|
||||||
public GlobalToggleProviderModesC2SPacket(Op opBlocking, Op opAdvancedBlocking, Op opSmartDoubling, BlockPos controllerPos) {
|
public GlobalToggleProviderModesC2SPacket(Op opBlocking, Op opAdvancedBlocking, Op opSmartDoubling, BlockPos controllerPos) {
|
||||||
this.opBlocking = opBlocking;
|
this.opBlocking = opBlocking;
|
||||||
this.opAdvancedBlocking = opAdvancedBlocking;
|
this.opAdvancedBlocking = opAdvancedBlocking;
|
||||||
|
|
@ -73,11 +55,6 @@ public class GlobalToggleProviderModesC2SPacket implements CustomPacketPayload {
|
||||||
this.controllerPos = controllerPos;
|
this.controllerPos = controllerPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final GlobalToggleProviderModesC2SPacket msg, final IPayloadContext ctx) {
|
public static void handle(final GlobalToggleProviderModesC2SPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||||
|
|
@ -176,14 +153,14 @@ public class GlobalToggleProviderModesC2SPacket implements CustomPacketPayload {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 2) 高级阻挡(mixin 接口)
|
// 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 current = adv.eap$getAdvancedBlocking();
|
||||||
boolean target = computeTarget(current, msg.opAdvancedBlocking);
|
boolean target = computeTarget(current, msg.opAdvancedBlocking);
|
||||||
adv.eap$setAdvancedBlocking(target);
|
adv.eap$setAdvancedBlocking(target);
|
||||||
changed = changed || (current != target);
|
changed = changed || (current != target);
|
||||||
}
|
}
|
||||||
// 3) 智能翻倍(mixin 接口)
|
// 3) 智能翻倍(mixin 接口)
|
||||||
if (msg.opSmartDoubling != Op.NOOP && logic instanceof SmartDoublingHolder sd) {
|
if (msg.opSmartDoubling != Op.NOOP && logic instanceof ISmartDoubling sd) {
|
||||||
boolean current = sd.eap$getSmartDoubling();
|
boolean current = sd.eap$getSmartDoubling();
|
||||||
boolean target = computeTarget(current, msg.opSmartDoubling);
|
boolean target = computeTarget(current, msg.opSmartDoubling);
|
||||||
sd.eap$setSmartDoubling(target);
|
sd.eap$setSmartDoubling(target);
|
||||||
|
|
@ -208,4 +185,28 @@ public class GlobalToggleProviderModesC2SPacket implements CustomPacketPayload {
|
||||||
private static boolean safeIsBlocking(PatternProviderLogic logic) {
|
private static boolean safeIsBlocking(PatternProviderLogic logic) {
|
||||||
try { return logic.isBlocking(); } catch (Throwable t) { return false; }
|
try { return logic.isBlocking(); } catch (Throwable t) { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Op {
|
||||||
|
NOOP((byte) 0),
|
||||||
|
SET_TRUE((byte) 1),
|
||||||
|
SET_FALSE((byte) 2),
|
||||||
|
TOGGLE((byte) 3);
|
||||||
|
public final byte id;
|
||||||
|
|
||||||
|
Op(byte id) {this.id = id;}
|
||||||
|
|
||||||
|
static Op byId(byte id) {
|
||||||
|
return switch (id) {
|
||||||
|
case 1 -> SET_TRUE;
|
||||||
|
case 2 -> SET_FALSE;
|
||||||
|
case 3 -> TOGGLE;
|
||||||
|
default -> NOOP;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import appeng.items.tools.powered.WirelessTerminalItem;
|
||||||
import appeng.menu.locator.MenuLocators;
|
import appeng.menu.locator.MenuLocators;
|
||||||
import appeng.menu.me.crafting.CraftAmountMenu;
|
import appeng.menu.me.crafting.CraftAmountMenu;
|
||||||
import com.extendedae_plus.menu.locator.CuriosItemLocator;
|
import com.extendedae_plus.menu.locator.CuriosItemLocator;
|
||||||
import com.extendedae_plus.util.WirelessTerminalLocator;
|
import com.extendedae_plus.util.wireless.WirelessTerminalLocator;
|
||||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
|
@ -33,11 +33,6 @@ public class OpenCraftFromJeiC2SPacket implements CustomPacketPayload {
|
||||||
this.stack = stack;
|
this.stack = stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final OpenCraftFromJeiC2SPacket msg, final IPayloadContext ctx) {
|
public static void handle(final OpenCraftFromJeiC2SPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||||
|
|
@ -118,4 +113,9 @@ public class OpenCraftFromJeiC2SPacket implements CustomPacketPayload {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import appeng.items.tools.powered.WirelessCraftingTerminalItem;
|
||||||
import appeng.items.tools.powered.WirelessTerminalItem;
|
import appeng.items.tools.powered.WirelessTerminalItem;
|
||||||
import appeng.me.helpers.PlayerSource;
|
import appeng.me.helpers.PlayerSource;
|
||||||
import com.extendedae_plus.menu.locator.CuriosItemLocator;
|
import com.extendedae_plus.menu.locator.CuriosItemLocator;
|
||||||
import com.extendedae_plus.util.WirelessTerminalLocator;
|
import com.extendedae_plus.util.wireless.WirelessTerminalLocator;
|
||||||
import com.extendedae_plus.util.WirelessTerminalLocator.LocatedTerminal;
|
import com.extendedae_plus.util.wireless.WirelessTerminalLocator.LocatedTerminal;
|
||||||
import de.mari_023.ae2wtlib.api.registration.WTDefinition;
|
import de.mari_023.ae2wtlib.api.registration.WTDefinition;
|
||||||
import de.mari_023.ae2wtlib.api.terminal.WTMenuHost;
|
import de.mari_023.ae2wtlib.api.terminal.WTMenuHost;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
@ -56,11 +56,6 @@ public class PickFromWirelessC2SPacket implements CustomPacketPayload {
|
||||||
this.hitLoc = hitLoc;
|
this.hitLoc = hitLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final PickFromWirelessC2SPacket msg, final IPayloadContext ctx) {
|
public static void handle(final PickFromWirelessC2SPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||||
|
|
@ -175,4 +170,9 @@ public class PickFromWirelessC2SPacket implements CustomPacketPayload {
|
||||||
player.containerMenu.broadcastChanges();
|
player.containerMenu.broadcastChanges();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.extendedae_plus.network;
|
package com.extendedae_plus.network;
|
||||||
|
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.client.ui.ProviderSelectScreen;
|
import com.extendedae_plus.client.screen.ProviderSelectScreen;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
|
|
@ -48,17 +48,12 @@ public class ProvidersListS2CPacket implements CustomPacketPayload {
|
||||||
private final List<String> names;
|
private final List<String> names;
|
||||||
private final List<Integer> emptySlots;
|
private final List<Integer> emptySlots;
|
||||||
|
|
||||||
public ProvidersListS2CPacket(List<Long> ids, List<String> names, List<Integer> emptySlots) {
|
ProvidersListS2CPacket(List<Long> ids, List<String> names, List<Integer> emptySlots) {
|
||||||
this.ids = ids;
|
this.ids = ids;
|
||||||
this.names = names;
|
this.names = names;
|
||||||
this.emptySlots = emptySlots;
|
this.emptySlots = emptySlots;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final ProvidersListS2CPacket msg, final IPayloadContext ctx) {
|
public static void handle(final ProvidersListS2CPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> handleClient(msg));
|
ctx.enqueueWork(() -> handleClient(msg));
|
||||||
}
|
}
|
||||||
|
|
@ -70,4 +65,9 @@ public class ProvidersListS2CPacket implements CustomPacketPayload {
|
||||||
var current = mc.screen;
|
var current = mc.screen;
|
||||||
mc.setScreen(new ProviderSelectScreen(current, msg.ids, msg.names, msg.emptySlots));
|
mc.setScreen(new ProviderSelectScreen(current, msg.ids, msg.names, msg.emptySlots));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ import appeng.me.helpers.PlayerSource;
|
||||||
import appeng.menu.locator.MenuLocators;
|
import appeng.menu.locator.MenuLocators;
|
||||||
import appeng.menu.me.crafting.CraftAmountMenu;
|
import appeng.menu.me.crafting.CraftAmountMenu;
|
||||||
import com.extendedae_plus.menu.locator.CuriosItemLocator;
|
import com.extendedae_plus.menu.locator.CuriosItemLocator;
|
||||||
import com.extendedae_plus.util.WirelessTerminalLocator;
|
import com.extendedae_plus.util.wireless.WirelessTerminalLocator;
|
||||||
import com.extendedae_plus.util.WirelessTerminalLocator.LocatedTerminal;
|
import com.extendedae_plus.util.wireless.WirelessTerminalLocator.LocatedTerminal;
|
||||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
|
@ -39,11 +39,6 @@ public class PullFromJeiOrCraftC2SPacket implements CustomPacketPayload {
|
||||||
this.stack = stack;
|
this.stack = stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final PullFromJeiOrCraftC2SPacket msg, final IPayloadContext ctx) {
|
public static void handle(final PullFromJeiOrCraftC2SPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||||
|
|
@ -107,4 +102,9 @@ public class PullFromJeiOrCraftC2SPacket implements CustomPacketPayload {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import appeng.helpers.patternprovider.PatternContainer;
|
||||||
import appeng.menu.implementations.PatternAccessTermMenu;
|
import appeng.menu.implementations.PatternAccessTermMenu;
|
||||||
import appeng.menu.me.items.PatternEncodingTermMenu;
|
import appeng.menu.me.items.PatternEncodingTermMenu;
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
import com.extendedae_plus.util.uploadPattern.ExtendedAEPatternUploadUtil;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
|
@ -27,12 +27,7 @@ public class RequestProvidersListC2SPacket implements CustomPacketPayload {
|
||||||
public static final StreamCodec<FriendlyByteBuf, RequestProvidersListC2SPacket> STREAM_CODEC =
|
public static final StreamCodec<FriendlyByteBuf, RequestProvidersListC2SPacket> STREAM_CODEC =
|
||||||
StreamCodec.unit(INSTANCE);
|
StreamCodec.unit(INSTANCE);
|
||||||
|
|
||||||
public RequestProvidersListC2SPacket() {}
|
private RequestProvidersListC2SPacket() {}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final RequestProvidersListC2SPacket msg, final IPayloadContext ctx) {
|
public static void handle(final RequestProvidersListC2SPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
|
|
@ -79,4 +74,9 @@ public class RequestProvidersListC2SPacket implements CustomPacketPayload {
|
||||||
player.connection.send(new ProvidersListS2CPacket(idxIds, names, slots));
|
player.connection.send(new ProvidersListS2CPacket(idxIds, names, slots));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import appeng.api.config.Settings;
|
||||||
import appeng.api.config.YesNo;
|
import appeng.api.config.YesNo;
|
||||||
import appeng.menu.implementations.PatternProviderMenu;
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.api.AdvancedBlockingHolder;
|
import com.extendedae_plus.api.advancedBlocking.IAdvancedBlocking;
|
||||||
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor;
|
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor;
|
||||||
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor;
|
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
|
@ -30,11 +30,6 @@ public class ToggleAdvancedBlockingC2SPacket implements CustomPacketPayload {
|
||||||
|
|
||||||
private ToggleAdvancedBlockingC2SPacket() {}
|
private ToggleAdvancedBlockingC2SPacket() {}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final ToggleAdvancedBlockingC2SPacket msg, final IPayloadContext ctx) {
|
public static void handle(final ToggleAdvancedBlockingC2SPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||||
|
|
@ -42,7 +37,7 @@ public class ToggleAdvancedBlockingC2SPacket implements CustomPacketPayload {
|
||||||
if (containerMenu instanceof PatternProviderMenu menu) {
|
if (containerMenu instanceof PatternProviderMenu menu) {
|
||||||
var accessor = (PatternProviderMenuAdvancedAccessor) menu;
|
var accessor = (PatternProviderMenuAdvancedAccessor) menu;
|
||||||
var logic = accessor.eap$logic();
|
var logic = accessor.eap$logic();
|
||||||
if (logic instanceof AdvancedBlockingHolder holder) {
|
if (logic instanceof IAdvancedBlocking holder) {
|
||||||
boolean current = holder.eap$getAdvancedBlocking();
|
boolean current = holder.eap$getAdvancedBlocking();
|
||||||
boolean next = !current;
|
boolean next = !current;
|
||||||
holder.eap$setAdvancedBlocking(next);
|
holder.eap$setAdvancedBlocking(next);
|
||||||
|
|
@ -54,7 +49,7 @@ public class ToggleAdvancedBlockingC2SPacket implements CustomPacketPayload {
|
||||||
}else if (containerMenu instanceof AdvPatternProviderMenu menu){
|
}else if (containerMenu instanceof AdvPatternProviderMenu menu){
|
||||||
var accessor = (AdvPatternProviderMenuAdvancedAccessor) menu;
|
var accessor = (AdvPatternProviderMenuAdvancedAccessor) menu;
|
||||||
var logic = accessor.eap$logic();
|
var logic = accessor.eap$logic();
|
||||||
if (logic instanceof AdvancedBlockingHolder holder) {
|
if (logic instanceof IAdvancedBlocking holder) {
|
||||||
boolean current = holder.eap$getAdvancedBlocking();
|
boolean current = holder.eap$getAdvancedBlocking();
|
||||||
boolean next = !current;
|
boolean next = !current;
|
||||||
holder.eap$setAdvancedBlocking(next);
|
holder.eap$setAdvancedBlocking(next);
|
||||||
|
|
@ -66,4 +61,9 @@ public class ToggleAdvancedBlockingC2SPacket implements CustomPacketPayload {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package com.extendedae_plus.network;
|
||||||
|
|
||||||
import appeng.menu.implementations.PatternProviderMenu;
|
import appeng.menu.implementations.PatternProviderMenu;
|
||||||
import com.extendedae_plus.ExtendedAEPlus;
|
import com.extendedae_plus.ExtendedAEPlus;
|
||||||
import com.extendedae_plus.api.SmartDoublingHolder;
|
import com.extendedae_plus.api.smartDoubling.ISmartDoubling;
|
||||||
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor;
|
import com.extendedae_plus.mixin.advancedae.accessor.AdvPatternProviderMenuAdvancedAccessor;
|
||||||
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor;
|
import com.extendedae_plus.mixin.ae2.accessor.PatternProviderMenuAdvancedAccessor;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
|
@ -28,11 +28,6 @@ public class ToggleSmartDoublingC2SPacket implements CustomPacketPayload {
|
||||||
|
|
||||||
private ToggleSmartDoublingC2SPacket() {}
|
private ToggleSmartDoublingC2SPacket() {}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final ToggleSmartDoublingC2SPacket msg, final IPayloadContext ctx) {
|
public static void handle(final ToggleSmartDoublingC2SPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||||
|
|
@ -40,7 +35,7 @@ public class ToggleSmartDoublingC2SPacket implements CustomPacketPayload {
|
||||||
if (containerMenu instanceof PatternProviderMenu menu) {
|
if (containerMenu instanceof PatternProviderMenu menu) {
|
||||||
var accessor = (PatternProviderMenuAdvancedAccessor) menu;
|
var accessor = (PatternProviderMenuAdvancedAccessor) menu;
|
||||||
var logic = accessor.eap$logic();
|
var logic = accessor.eap$logic();
|
||||||
if (logic instanceof SmartDoublingHolder holder) {
|
if (logic instanceof ISmartDoubling holder) {
|
||||||
boolean current = holder.eap$getSmartDoubling();
|
boolean current = holder.eap$getSmartDoubling();
|
||||||
boolean next = !current;
|
boolean next = !current;
|
||||||
holder.eap$setSmartDoubling(next);
|
holder.eap$setSmartDoubling(next);
|
||||||
|
|
@ -49,7 +44,7 @@ public class ToggleSmartDoublingC2SPacket implements CustomPacketPayload {
|
||||||
}else if (containerMenu instanceof AdvPatternProviderMenu menu){
|
}else if (containerMenu instanceof AdvPatternProviderMenu menu){
|
||||||
var accessor = (AdvPatternProviderMenuAdvancedAccessor) menu;
|
var accessor = (AdvPatternProviderMenuAdvancedAccessor) menu;
|
||||||
var logic = accessor.eap$logic();
|
var logic = accessor.eap$logic();
|
||||||
if (logic instanceof SmartDoublingHolder holder) {
|
if (logic instanceof ISmartDoubling holder) {
|
||||||
boolean current = holder.eap$getSmartDoubling();
|
boolean current = holder.eap$getSmartDoubling();
|
||||||
boolean next = !current;
|
boolean next = !current;
|
||||||
holder.eap$setSmartDoubling(next);
|
holder.eap$setSmartDoubling(next);
|
||||||
|
|
@ -58,4 +53,9 @@ public class ToggleSmartDoublingC2SPacket implements CustomPacketPayload {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.extendedae_plus.network;
|
package com.extendedae_plus.network;
|
||||||
|
|
||||||
import appeng.menu.me.items.PatternEncodingTermMenu;
|
import appeng.menu.me.items.PatternEncodingTermMenu;
|
||||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
import com.extendedae_plus.util.uploadPattern.ExtendedAEPatternUploadUtil;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
|
@ -26,11 +26,6 @@ public class UploadEncodedPatternToProviderC2SPacket implements CustomPacketPayl
|
||||||
this.providerId = providerId;
|
this.providerId = providerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final UploadEncodedPatternToProviderC2SPacket msg, final IPayloadContext ctx) {
|
public static void handle(final UploadEncodedPatternToProviderC2SPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||||
|
|
@ -46,4 +41,9 @@ public class UploadEncodedPatternToProviderC2SPacket implements CustomPacketPayl
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.extendedae_plus.network;
|
package com.extendedae_plus.network;
|
||||||
|
|
||||||
import com.extendedae_plus.util.ExtendedAEPatternUploadUtil;
|
import com.extendedae_plus.util.uploadPattern.ExtendedAEPatternUploadUtil;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.network.codec.StreamCodec;
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
|
@ -32,15 +32,15 @@ public class UploadInventoryPatternToProviderC2SPacket implements CustomPacketPa
|
||||||
this.providerId = providerId;
|
this.providerId = providerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type<? extends CustomPacketPayload> type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handle(final UploadInventoryPatternToProviderC2SPacket msg, final IPayloadContext ctx) {
|
public static void handle(final UploadInventoryPatternToProviderC2SPacket msg, final IPayloadContext ctx) {
|
||||||
ctx.enqueueWork(() -> {
|
ctx.enqueueWork(() -> {
|
||||||
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
if (!(ctx.player() instanceof ServerPlayer player)) return;
|
||||||
ExtendedAEPatternUploadUtil.uploadPatternToProvider(player, msg.playerSlotIndex, msg.providerId);
|
ExtendedAEPatternUploadUtil.uploadPatternToProvider(player, msg.playerSlotIndex, msg.providerId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.util;
|
package com.extendedae_plus.util.entitySpeed;
|
||||||
|
|
||||||
import appeng.api.config.Actionable;
|
import appeng.api.config.Actionable;
|
||||||
import appeng.api.networking.energy.IEnergyService;
|
import appeng.api.networking.energy.IEnergyService;
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package com.extendedae_plus.util.entitySpeed;
|
package com.extendedae_plus.util.entitySpeed;
|
||||||
|
|
||||||
import appeng.api.upgrades.IUpgradeInventory;
|
import appeng.api.upgrades.IUpgradeInventory;
|
||||||
import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem;
|
|
||||||
import com.extendedae_plus.config.ModConfigs;
|
import com.extendedae_plus.config.ModConfigs;
|
||||||
|
import com.extendedae_plus.items.materials.EntitySpeedCardItem;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -47,7 +47,7 @@ public final class PowerUtils {
|
||||||
/**
|
/**
|
||||||
* 根据最高单卡倍率返回上限值。
|
* 根据最高单卡倍率返回上限值。
|
||||||
*/
|
*/
|
||||||
public static long capForHighestMultiplier(int highestMultiplier) {
|
private static long capForHighestMultiplier(int highestMultiplier) {
|
||||||
if (highestMultiplier >= 16) return 1024L;
|
if (highestMultiplier >= 16) return 1024L;
|
||||||
if (highestMultiplier >= 8) return 256L;
|
if (highestMultiplier >= 8) return 256L;
|
||||||
if (highestMultiplier >= 4) return 64L;
|
if (highestMultiplier >= 4) return 64L;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package com.extendedae_plus.util;
|
package com.extendedae_plus.util.smartDoubling;
|
||||||
|
|
||||||
import appeng.api.crafting.IPatternDetails.IInput;
|
import appeng.api.crafting.IPatternDetails.IInput;
|
||||||
import appeng.api.stacks.AEKey;
|
import appeng.api.stacks.AEKey;
|
||||||
import appeng.api.stacks.GenericStack;
|
import appeng.api.stacks.GenericStack;
|
||||||
import appeng.crafting.pattern.AEProcessingPattern;
|
import appeng.crafting.pattern.AEProcessingPattern;
|
||||||
import com.extendedae_plus.api.SmartDoublingAwarePattern;
|
import com.extendedae_plus.api.crafting.ScaledProcessingPattern;
|
||||||
|
import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern;
|
||||||
import com.extendedae_plus.config.ModConfigs;
|
import com.extendedae_plus.config.ModConfigs;
|
||||||
import com.extendedae_plus.content.ScaledProcessingPattern;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -20,7 +20,7 @@ public final class PatternScaler {
|
||||||
if (target == null) throw new IllegalArgumentException("target");
|
if (target == null) throw new IllegalArgumentException("target");
|
||||||
|
|
||||||
// 双保险:若样板标记为不允许缩放,直接放弃缩放(返回 null 表示调用方应保持原样板)
|
// 双保险:若样板标记为不允许缩放,直接放弃缩放(返回 null 表示调用方应保持原样板)
|
||||||
if (base instanceof SmartDoublingAwarePattern aware && !aware.eap$allowScaling()) {
|
if (base instanceof ISmartDoublingAwarePattern aware && !aware.eap$allowScaling()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.util;
|
package com.extendedae_plus.util.smartDoubling;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
|
|
@ -1,23 +1,21 @@
|
||||||
package com.extendedae_plus.util;
|
package com.extendedae_plus.util.uploadPattern;
|
||||||
|
|
||||||
import appeng.api.crafting.IPatternDetails;
|
import appeng.api.crafting.IPatternDetails;
|
||||||
import appeng.api.crafting.PatternDetailsHelper;
|
import appeng.api.crafting.PatternDetailsHelper;
|
||||||
import appeng.api.inventories.InternalInventory;
|
import appeng.api.inventories.InternalInventory;
|
||||||
import appeng.api.networking.IGrid;
|
import appeng.api.networking.IGrid;
|
||||||
import appeng.api.networking.IGridNode;
|
|
||||||
import appeng.core.definitions.AEItems;
|
|
||||||
import appeng.menu.AEBaseMenu;
|
|
||||||
import appeng.api.networking.security.IActionHost;
|
import appeng.api.networking.security.IActionHost;
|
||||||
|
import appeng.core.definitions.AEItems;
|
||||||
import appeng.crafting.pattern.AECraftingPattern;
|
import appeng.crafting.pattern.AECraftingPattern;
|
||||||
import appeng.crafting.pattern.AESmithingTablePattern;
|
import appeng.crafting.pattern.AESmithingTablePattern;
|
||||||
import appeng.crafting.pattern.AEStonecuttingPattern;
|
import appeng.crafting.pattern.AEStonecuttingPattern;
|
||||||
import appeng.helpers.patternprovider.PatternContainer;
|
import appeng.helpers.patternprovider.PatternContainer;
|
||||||
|
import appeng.menu.AEBaseMenu;
|
||||||
import appeng.menu.implementations.PatternAccessTermMenu;
|
import appeng.menu.implementations.PatternAccessTermMenu;
|
||||||
import appeng.menu.me.items.PatternEncodingTermMenu;
|
import appeng.menu.me.items.PatternEncodingTermMenu;
|
||||||
import appeng.util.inv.FilteredInternalInventory;
|
import appeng.util.inv.FilteredInternalInventory;
|
||||||
import appeng.util.inv.filter.IAEItemFilter;
|
import appeng.util.inv.filter.IAEItemFilter;
|
||||||
import com.extendedae_plus.mixin.ae2.accessor.PatternEncodingTermMenuAccessor;
|
import com.extendedae_plus.mixin.ae2.accessor.PatternEncodingTermMenuAccessor;
|
||||||
import com.glodblock.github.extendedae.common.tileentities.matrix.TileAssemblerMatrixBase;
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
|
@ -35,7 +33,10 @@ import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -50,6 +51,8 @@ public class ExtendedAEPatternUploadUtil {
|
||||||
// 允许使用最终搜索关键字(通常为 path 或自定义短语)作为键,例如:"assembler": "组装机"
|
// 允许使用最终搜索关键字(通常为 path 或自定义短语)作为键,例如:"assembler": "组装机"
|
||||||
private static final Map<String, String> CUSTOM_ALIASES = new ConcurrentHashMap<>();
|
private static final Map<String, String> CUSTOM_ALIASES = new ConcurrentHashMap<>();
|
||||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||||
|
// 最近一次通过 JEI 填充到编码终端的“处理配方”的中文名称(如:烧炼/高炉/烟熏...)
|
||||||
|
public static volatile String lastProcessingName = null;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
|
|
@ -122,9 +125,6 @@ public class ExtendedAEPatternUploadUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最近一次通过 JEI 填充到编码终端的“处理配方”的中文名称(如:烧炼/高炉/烟熏...)
|
|
||||||
public static volatile String lastProcessingName = null;
|
|
||||||
|
|
||||||
public static void setLastProcessingName(String name) {
|
public static void setLastProcessingName(String name) {
|
||||||
lastProcessingName = name;
|
lastProcessingName = name;
|
||||||
}
|
}
|
||||||
|
|
@ -579,7 +579,7 @@ public class ExtendedAEPatternUploadUtil {
|
||||||
* @param player 玩家
|
* @param player 玩家
|
||||||
* @return 是否为ExtendedAE扩展终端
|
* @return 是否为ExtendedAE扩展终端
|
||||||
*/
|
*/
|
||||||
public static boolean isExtendedAETerminal(ServerPlayer player) {
|
private static boolean isExtendedAETerminal(ServerPlayer player) {
|
||||||
if (player == null || player.containerMenu == null) {
|
if (player == null || player.containerMenu == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -828,22 +828,6 @@ public class ExtendedAEPatternUploadUtil {
|
||||||
// 如果玩家为null,静默忽略(用于测试环境)
|
// 如果玩家为null,静默忽略(用于测试环境)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ExtendedAE兼容的样板过滤器
|
|
||||||
* 使用AE2的PatternDetailsHelper进行样板验证
|
|
||||||
*/
|
|
||||||
private static class ExtendedAEPatternFilter implements IAEItemFilter {
|
|
||||||
@Override
|
|
||||||
public boolean allowExtract(InternalInventory inv, int slot, int amount) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean allowInsert(InternalInventory inv, int slot, ItemStack stack) {
|
|
||||||
return !stack.isEmpty() && PatternDetailsHelper.isEncodedPattern(stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取样板供应器的显示名称
|
* 获取样板供应器的显示名称
|
||||||
*
|
*
|
||||||
|
|
@ -1202,4 +1186,20 @@ public class ExtendedAEPatternUploadUtil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ExtendedAE兼容的样板过滤器
|
||||||
|
* 使用AE2的PatternDetailsHelper进行样板验证
|
||||||
|
*/
|
||||||
|
private static class ExtendedAEPatternFilter implements IAEItemFilter {
|
||||||
|
@Override
|
||||||
|
public boolean allowExtract(InternalInventory inv, int slot, int amount) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowInsert(InternalInventory inv, int slot, ItemStack stack) {
|
||||||
|
return !stack.isEmpty() && PatternDetailsHelper.isEncodedPattern(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.util;
|
package com.extendedae_plus.util.wireless;
|
||||||
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.extendedae_plus.util;
|
package com.extendedae_plus.util.wireless;
|
||||||
|
|
||||||
import appeng.items.tools.powered.WirelessCraftingTerminalItem;
|
import appeng.items.tools.powered.WirelessCraftingTerminalItem;
|
||||||
import appeng.items.tools.powered.WirelessTerminalItem;
|
import appeng.items.tools.powered.WirelessTerminalItem;
|
||||||
|
|
@ -21,51 +21,6 @@ import java.util.function.Consumer;
|
||||||
public final class WirelessTerminalLocator {
|
public final class WirelessTerminalLocator {
|
||||||
private WirelessTerminalLocator() {}
|
private WirelessTerminalLocator() {}
|
||||||
|
|
||||||
public static final class LocatedTerminal {
|
|
||||||
public final ItemStack stack;
|
|
||||||
private final Consumer<ItemStack> setter;
|
|
||||||
// 在玩家 Inventory 中的槽位索引(0..size-1)。若未知则为 -1。
|
|
||||||
private final int slotIndex;
|
|
||||||
// 若终端在玩家手上,则记录手别;否则为 null。
|
|
||||||
private final net.minecraft.world.InteractionHand hand;
|
|
||||||
// 若终端位于 Curios,则记录其槽位组 ID 与组内索引;否则 slotId 为 null,index 为 -1。
|
|
||||||
private final String curiosSlotId;
|
|
||||||
private final int curiosIndex;
|
|
||||||
|
|
||||||
public LocatedTerminal(ItemStack stack, Consumer<ItemStack> setter) {
|
|
||||||
this(stack, setter, -1, null, null, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocatedTerminal(ItemStack stack, Consumer<ItemStack> setter, int slotIndex) {
|
|
||||||
this(stack, setter, slotIndex, null, null, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocatedTerminal(ItemStack stack, Consumer<ItemStack> setter, int slotIndex, net.minecraft.world.InteractionHand hand) {
|
|
||||||
this(stack, setter, slotIndex, hand, null, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocatedTerminal(ItemStack stack, Consumer<ItemStack> setter, int slotIndex, net.minecraft.world.InteractionHand hand, String curiosSlotId, int curiosIndex) {
|
|
||||||
this.stack = stack;
|
|
||||||
this.setter = setter;
|
|
||||||
this.slotIndex = slotIndex;
|
|
||||||
this.hand = hand;
|
|
||||||
this.curiosSlotId = curiosSlotId;
|
|
||||||
this.curiosIndex = curiosIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void set(ItemStack newStack) { this.setter.accept(newStack); }
|
|
||||||
public void commit() { this.setter.accept(this.stack); }
|
|
||||||
public boolean isEmpty() { return this.stack == null || this.stack.isEmpty(); }
|
|
||||||
/** 若返回 -1,说明不是从原版 Inventory 槽位中找到(比如 Curios)。 */
|
|
||||||
public int getSlotIndex() { return this.slotIndex; }
|
|
||||||
/** 若不为 null,说明终端在玩家手上。 */
|
|
||||||
public net.minecraft.world.InteractionHand getHand() { return this.hand; }
|
|
||||||
/** 若不为 null,说明终端位于 Curios 指定槽位组。 */
|
|
||||||
public String getCuriosSlotId() { return this.curiosSlotId; }
|
|
||||||
/** Curios 组内索引,未知时为 -1。 */
|
|
||||||
public int getCuriosIndex() { return this.curiosIndex; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LocatedTerminal find(Player player) {
|
public static LocatedTerminal find(Player player) {
|
||||||
if (player == null) return new LocatedTerminal(ItemStack.EMPTY, s -> {});
|
if (player == null) return new LocatedTerminal(ItemStack.EMPTY, s -> {});
|
||||||
|
|
||||||
|
|
@ -118,4 +73,49 @@ public final class WirelessTerminalLocator {
|
||||||
|
|
||||||
return new LocatedTerminal(ItemStack.EMPTY, s -> {}, -1, null);
|
return new LocatedTerminal(ItemStack.EMPTY, s -> {}, -1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class LocatedTerminal {
|
||||||
|
public final ItemStack stack;
|
||||||
|
private final Consumer<ItemStack> setter;
|
||||||
|
// 在玩家 Inventory 中的槽位索引(0..size-1)。若未知则为 -1。
|
||||||
|
private final int slotIndex;
|
||||||
|
// 若终端在玩家手上,则记录手别;否则为 null。
|
||||||
|
private final net.minecraft.world.InteractionHand hand;
|
||||||
|
// 若终端位于 Curios,则记录其槽位组 ID 与组内索引;否则 slotId 为 null,index 为 -1。
|
||||||
|
private final String curiosSlotId;
|
||||||
|
private final int curiosIndex;
|
||||||
|
|
||||||
|
LocatedTerminal(ItemStack stack, Consumer<ItemStack> setter) {
|
||||||
|
this(stack, setter, -1, null, null, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocatedTerminal(ItemStack stack, Consumer<ItemStack> setter, int slotIndex) {
|
||||||
|
this(stack, setter, slotIndex, null, null, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocatedTerminal(ItemStack stack, Consumer<ItemStack> setter, int slotIndex, net.minecraft.world.InteractionHand hand) {
|
||||||
|
this(stack, setter, slotIndex, hand, null, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocatedTerminal(ItemStack stack, Consumer<ItemStack> setter, int slotIndex, net.minecraft.world.InteractionHand hand, String curiosSlotId, int curiosIndex) {
|
||||||
|
this.stack = stack;
|
||||||
|
this.setter = setter;
|
||||||
|
this.slotIndex = slotIndex;
|
||||||
|
this.hand = hand;
|
||||||
|
this.curiosSlotId = curiosSlotId;
|
||||||
|
this.curiosIndex = curiosIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(ItemStack newStack) { this.setter.accept(newStack); }
|
||||||
|
public void commit() { this.setter.accept(this.stack); }
|
||||||
|
public boolean isEmpty() { return this.stack == null || this.stack.isEmpty(); }
|
||||||
|
/** 若返回 -1,说明不是从原版 Inventory 槽位中找到(比如 Curios)。 */
|
||||||
|
public int getSlotIndex() { return this.slotIndex; }
|
||||||
|
/** 若不为 null,说明终端在玩家手上。 */
|
||||||
|
public net.minecraft.world.InteractionHand getHand() { return this.hand; }
|
||||||
|
/** 若不为 null,说明终端位于 Curios 指定槽位组。 */
|
||||||
|
public String getCuriosSlotId() { return this.curiosSlotId; }
|
||||||
|
/** Curios 组内索引,未知时为 -1。 */
|
||||||
|
public int getCuriosIndex() { return this.curiosIndex; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user