Merge remote-tracking branch 'origin/develop/1.21.1' into 1.21.1
# Conflicts: # src/main/java/com/extendedae_plus/mixin/ExtendedAEPlusMixinPlugin.java # src/main/java/com/extendedae_plus/mixin/advancedae/compat/PatternProviderLogicVirtualCompletionMixin.java # src/main/java/com/extendedae_plus/mixin/ae2/compat/PatternProviderLogicCompatMixin.java
This commit is contained in:
commit
0a820c734b
|
|
@ -5,30 +5,24 @@
|
||||||
# Find more information on toml format here: https://github.com/toml-lang/toml
|
# Find more information on toml format here: https://github.com/toml-lang/toml
|
||||||
|
|
||||||
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
|
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
|
||||||
modLoader="javafml" #mandatory
|
modLoader = "javafml" #mandatory
|
||||||
|
|
||||||
# A version range to match for said mod loader - for regular FML @Mod it will be the FML version. This is currently 2.
|
# A version range to match for said mod loader - for regular FML @Mod it will be the FML version. This is currently 2.
|
||||||
loaderVersion="[1,)" #mandatory
|
loaderVersion = "[1,)" #mandatory
|
||||||
|
|
||||||
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
|
# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties.
|
||||||
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
|
# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here.
|
||||||
license="All Rights Reserved"
|
license = "LGPL-3.0-or-later"
|
||||||
|
|
||||||
# A URL to refer people to when problems occur with this mod
|
# A URL to refer people to when problems occur with this mod
|
||||||
#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional
|
|
||||||
|
|
||||||
# A list of mods - how many allowed here is determined by the individual mod loader
|
# A list of mods - how many allowed here is determined by the individual mod loader
|
||||||
[[mods]] #mandatory
|
[[mods]]
|
||||||
|
modId = "extendedae_plus"
|
||||||
# The modid of the mod
|
version = "1.21.1-1.4.3"
|
||||||
modId="extendedae_plus" #mandatory
|
displayName = "ExtendedAE-Plus"
|
||||||
|
issueTrackerURL = "https://github.com/GaLicn/ExtendedAE_Plus/issues"
|
||||||
# The version number of the mod
|
displayURL = "https://github.com/GaLicn/ExtendedAE_Plus"
|
||||||
version="1.21.1-1.4.3" #mandatory
|
|
||||||
|
|
||||||
# A display name for the mod
|
|
||||||
displayName="ExtendedAE-Plus" #mandatory
|
|
||||||
|
|
||||||
# A URL to query for updates for this mod. See the JSON update specification https://docs.neoforged.net/docs/misc/updatechecker/
|
# A URL to query for updates for this mod. See the JSON update specification https://docs.neoforged.net/docs/misc/updatechecker/
|
||||||
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
|
#updateJSONURL="https://change.me.example.invalid/updates.json" #optional
|
||||||
|
|
||||||
|
|
@ -42,15 +36,14 @@ displayName="ExtendedAE-Plus" #mandatory
|
||||||
#credits="" #optional
|
#credits="" #optional
|
||||||
|
|
||||||
# A text field displayed in the mod UI
|
# A text field displayed in the mod UI
|
||||||
authors="YourNameHere, OtherNameHere" #optional
|
authors = "GaLi, C-H716" #optional
|
||||||
|
|
||||||
# The description text for the mod (multi line!) (#mandatory)
|
# The description text for the mod (multi line!) (#mandatory)
|
||||||
description='''Example mod description.
|
description = '''Add more practical features and auxiliary operations to the Applied Energistics 2 mod'''
|
||||||
Newline characters can be used and will be replaced properly.'''
|
|
||||||
|
|
||||||
# The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded.
|
# The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded.
|
||||||
[[mixins]]
|
[[mixins]]
|
||||||
config="extendedae_plus.mixins.json"
|
config = "extendedae_plus.mixins.json"
|
||||||
|
|
||||||
# The [[accessTransformers]] block allows you to declare where your AT file is.
|
# The [[accessTransformers]] block allows you to declare where your AT file is.
|
||||||
# If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg
|
# If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg
|
||||||
|
|
@ -61,40 +54,40 @@ config="extendedae_plus.mixins.json"
|
||||||
|
|
||||||
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
|
||||||
[[dependencies.extendedae_plus]] #optional
|
[[dependencies.extendedae_plus]] #optional
|
||||||
# the modid of the dependency
|
# the modid of the dependency
|
||||||
modId="neoforge" #mandatory
|
modId = "neoforge" #mandatory
|
||||||
# The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive).
|
# The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive).
|
||||||
# 'required' requires the mod to exist, 'optional' does not
|
# 'required' requires the mod to exist, 'optional' does not
|
||||||
# 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning
|
# 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning
|
||||||
type="required" #mandatory
|
type = "required" #mandatory
|
||||||
# Optional field describing why the dependency is required or why it is incompatible
|
# Optional field describing why the dependency is required or why it is incompatible
|
||||||
# reason="..."
|
# reason="..."
|
||||||
# The version range of the dependency
|
# The version range of the dependency
|
||||||
versionRange="[21.1.1,)" #mandatory
|
versionRange = "[21.1.1,)" #mandatory
|
||||||
# An ordering relationship for the dependency.
|
# An ordering relationship for the dependency.
|
||||||
# BEFORE - This mod is loaded BEFORE the dependency
|
# BEFORE - This mod is loaded BEFORE the dependency
|
||||||
# AFTER - This mod is loaded AFTER the dependency
|
# AFTER - This mod is loaded AFTER the dependency
|
||||||
ordering="NONE"
|
ordering = "NONE"
|
||||||
# Side this dependency is applied on - BOTH, CLIENT, or SERVER
|
# Side this dependency is applied on - BOTH, CLIENT, or SERVER
|
||||||
side="BOTH"
|
side = "BOTH"
|
||||||
|
|
||||||
# Here's another dependency
|
# Here's another dependency
|
||||||
[[dependencies.extendedae_plus]]
|
[[dependencies.extendedae_plus]]
|
||||||
modId="minecraft"
|
modId = "minecraft"
|
||||||
type="required"
|
type = "required"
|
||||||
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
||||||
versionRange="[1.21.1]"
|
versionRange = "[1.21.1]"
|
||||||
ordering="NONE"
|
ordering = "NONE"
|
||||||
side="BOTH"
|
side = "BOTH"
|
||||||
|
|
||||||
# Require ExtendedAE (ExtendedAE-1.21-2.2.21-neoforge) to be present
|
# Require ExtendedAE (ExtendedAE-1.21-2.2.21-neoforge) to be present
|
||||||
[[dependencies.extendedae_plus]]
|
[[dependencies.extendedae_plus]]
|
||||||
modId="extendedae"
|
modId = "extendedae"
|
||||||
type="required"
|
type = "required"
|
||||||
# Use a permissive range to tolerate upstream version string variations (e.g. 1.21-2.2.21-neoforge)
|
# Use a permissive range to tolerate upstream version string variations (e.g. 1.21-2.2.21-neoforge)
|
||||||
versionRange="*"
|
versionRange = "*"
|
||||||
ordering="AFTER"
|
ordering = "AFTER"
|
||||||
side="BOTH"
|
side = "BOTH"
|
||||||
|
|
||||||
# Features are specific properties of the game environment, that you may want to declare you require. This example declares
|
# Features are specific properties of the game environment, that you may want to declare you require. This example declares
|
||||||
# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't
|
# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ mod_id=extendedae_plus
|
||||||
# The human-readable display name for the mod.
|
# The human-readable display name for the mod.
|
||||||
mod_name=ExtendedAE-Plus
|
mod_name=ExtendedAE-Plus
|
||||||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||||
mod_license=All Rights Reserved
|
mod_license=LGPL-3.0-or-later
|
||||||
# The mod version. See https://semver.org/
|
# The mod version. See https://semver.org/
|
||||||
mod_version=1.21.1-1.4.3
|
mod_version=1.21.1-1.4.3
|
||||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||||
|
|
@ -38,9 +38,9 @@ mod_version=1.21.1-1.4.3
|
||||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
mod_group_id=com.extendedae_plus
|
mod_group_id=com.extendedae_plus
|
||||||
# The authors of the mod. This is a simple text string that is used for display purposes in the mod list.
|
# The authors of the mod. This is a simple text string that is used for display purposes in the mod list.
|
||||||
mod_authors=YourNameHere, OtherNameHere
|
mod_authors=GaLi, C-H716
|
||||||
# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list.
|
# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list.
|
||||||
mod_description=Example mod description.\nNewline characters can be used and will be replaced properly.
|
mod_description=Add more practical features and auxiliary operations to the Applied Energistics 2 mod
|
||||||
|
|
||||||
## UI item explorer selection (emi | rei | jei)
|
## UI item explorer selection (emi | rei | jei)
|
||||||
# Default to 'emi' per request; you can override by running with -Puse_Xei=rei or -Puse_Xei=jei
|
# Default to 'emi' per request; you can override by running with -Puse_Xei=rei or -Puse_Xei=jei
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,12 @@ import com.extendedae_plus.ae.parts.EntitySpeedTickerPart;
|
||||||
import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen;
|
import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen;
|
||||||
import com.extendedae_plus.api.config.EAPSettings;
|
import com.extendedae_plus.api.config.EAPSettings;
|
||||||
import com.extendedae_plus.config.ModConfigs;
|
import com.extendedae_plus.config.ModConfigs;
|
||||||
import com.extendedae_plus.init.ModItems;
|
|
||||||
import com.extendedae_plus.init.ModMenuTypes;
|
import com.extendedae_plus.init.ModMenuTypes;
|
||||||
import com.extendedae_plus.util.entitySpeed.ConfigParsingUtils;
|
import com.extendedae_plus.util.entitySpeed.ConfigParsingUtils;
|
||||||
import com.extendedae_plus.util.entitySpeed.PowerUtils;
|
import com.extendedae_plus.util.entitySpeed.PowerUtils;
|
||||||
import it.unimi.dsi.fastutil.shorts.ShortSet;
|
import it.unimi.dsi.fastutil.shorts.ShortSet;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.inventory.Slot;
|
import net.minecraft.world.inventory.Slot;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
@ -23,25 +23,20 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
* 实体加速器菜单,负责管理客户端与服务端的数据同步,处理加速卡、能量卡和目标方块的状态。
|
* 实体加速器菜单,负责管理客户端与服务端的数据同步,处理加速卡、能量卡和目标方块的状态。
|
||||||
*/
|
*/
|
||||||
public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart> {
|
public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart> {
|
||||||
@GuiSync(716) public YesNo accelerate; // 是否启用加速
|
private final EntitySpeedTickerPart logic;
|
||||||
@GuiSync(717) public YesNo redstoneControl; // 是否启用红石控制
|
@GuiSync(716) public int energyCardCount; // 已安装的能量卡数量
|
||||||
private int entitySpeedCardCount; // 已安装的实体加速卡数量
|
@GuiSync(717) public int effectiveSpeed = 1; // 当前生效的加速倍率
|
||||||
@GuiSync(719) public int energyCardCount; // 已安装的能量卡数量
|
@GuiSync(718) public double multiplier = 1.0; // 目标方块的配置倍率
|
||||||
@GuiSync(720) public int effectiveSpeed = 1; // 当前生效的加速倍率
|
@GuiSync(719) public boolean targetBlacklisted = false; // 目标方块是否在黑名单中
|
||||||
@GuiSync(721) public double multiplier = 1.0; // 目标方块的配置倍率
|
@GuiSync(720) public YesNo networkEnergySufficient; // 网络能量是否充足
|
||||||
@GuiSync(722) public boolean targetBlacklisted = false; // 目标方块是否在黑名单中
|
@GuiSync(721) private YesNo accelerate; // 是否启用加速
|
||||||
@GuiSync(723) public YesNo networkEnergySufficient; // 网络能量是否充足
|
@GuiSync(722) private YesNo redstoneControl; // 是否启用红石控制
|
||||||
|
|
||||||
protected final EntitySpeedTickerPart logic;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void loadSettingsFromHost(IConfigManager cm) {
|
|
||||||
// 不需要模糊模式
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 构造函数,初始化菜单并绑定部件。
|
* 构造函数,初始化菜单并绑定部件。
|
||||||
* @param id 菜单ID
|
*
|
||||||
* @param ip 玩家背包
|
* @param id 菜单ID
|
||||||
|
* @param ip 玩家背包
|
||||||
* @param host 关联的实体加速器部件
|
* @param host 关联的实体加速器部件
|
||||||
*/
|
*/
|
||||||
public EntitySpeedTickerMenu(int id, Inventory ip, EntitySpeedTickerPart host) {
|
public EntitySpeedTickerMenu(int id, Inventory ip, EntitySpeedTickerPart host) {
|
||||||
|
|
@ -49,32 +44,34 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
|
||||||
this.logic = host;
|
this.logic = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// 服务端 → 客户端同步时触发(包括第一次打开 GUI)
|
||||||
* 服务端数据同步到客户端时调用,更新卡数量、目标状态和生效速度。
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void onServerDataSync(ShortSet updatedFields) {
|
public void onServerDataSync(ShortSet updatedFields) {
|
||||||
super.onServerDataSync(updatedFields);
|
super.onServerDataSync(updatedFields);
|
||||||
updateCardCounts(); // 更新卡数量
|
|
||||||
updateTargetStatus(); // 更新目标方块的黑名单和倍率
|
// 客户端只更新「可能变化」的显示相关字段
|
||||||
updateEffectiveSpeed(); // 计算生效速度
|
// 顺序必须和 broadcastChanges 里一致!
|
||||||
// updateNetworkEnergyStatus(); // 同步能量状态
|
this.updateTargetStatus(); // multiplier + targetBlacklisted
|
||||||
if (isClientSide()) {
|
this.updateEffectiveSpeed(); // 依赖上面两个字段
|
||||||
refreshClientGui(); // 客户端刷新界面
|
|
||||||
|
if (this.isClientSide()) {
|
||||||
|
this.refreshClientGui();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当槽位内容变化时调用,客户端更新卡数量和生效速度。
|
* 当槽位内容变化时调用,客户端更新卡数量和生效速度。
|
||||||
|
*
|
||||||
* @param slot 发生变化的槽位
|
* @param slot 发生变化的槽位
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onSlotChange(Slot slot) {
|
public void onSlotChange(Slot slot) {
|
||||||
super.onSlotChange(slot);
|
super.onSlotChange(slot);
|
||||||
if (isClientSide()) {
|
if (this.isClientSide()) {
|
||||||
updateCardCounts();
|
// 升级卡变化时,energyCardCount 已经由 AE2 自动同步
|
||||||
updateEffectiveSpeed();
|
// 重新计算生效速度并刷新 UI
|
||||||
refreshClientGui();
|
this.updateEffectiveSpeed();
|
||||||
|
this.refreshClientGui();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,14 +80,27 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void broadcastChanges() {
|
public void broadcastChanges() {
|
||||||
if (isServerSide()) {
|
if (this.isServerSide()) {
|
||||||
this.accelerate = logic.getConfigManager().getSetting(EAPSettings.ACCELERATE);
|
// 1. 先更新配置类(开关、红石、能量充足)
|
||||||
this.redstoneControl = logic.getConfigManager().getSetting(EAPSettings.REDSTONE_CONTROL);
|
this.accelerate = this.logic.getConfigManager().getSetting(EAPSettings.ACCELERATE);
|
||||||
this.networkEnergySufficient = logic.isNetworkEnergySufficient() ? YesNo.YES : YesNo.NO;
|
this.redstoneControl = this.logic.getConfigManager().getSetting(EAPSettings.REDSTONE_CONTROL);
|
||||||
|
this.networkEnergySufficient = this.logic.isNetworkEnergySufficient() ? YesNo.YES : YesNo.NO;
|
||||||
|
|
||||||
|
// 2. 再更新升级卡数量
|
||||||
|
this.energyCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD);
|
||||||
|
|
||||||
|
// 3. 最后更新目标状态 + 生效速度
|
||||||
|
this.updateTargetStatus();
|
||||||
|
this.updateEffectiveSpeed();
|
||||||
}
|
}
|
||||||
super.broadcastChanges();
|
super.broadcastChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void loadSettingsFromHost(IConfigManager cm) {
|
||||||
|
// 不需要模糊模式
|
||||||
|
}
|
||||||
|
|
||||||
public YesNo getAccelerate() {
|
public YesNo getAccelerate() {
|
||||||
return this.accelerate;
|
return this.accelerate;
|
||||||
}
|
}
|
||||||
|
|
@ -98,25 +108,18 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
|
||||||
public YesNo getRedstoneControl() {
|
public YesNo getRedstoneControl() {
|
||||||
return this.redstoneControl;
|
return this.redstoneControl;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 更新加速卡和能量卡的数量。
|
|
||||||
*/
|
|
||||||
private void updateCardCounts() {
|
|
||||||
this.entitySpeedCardCount = this.getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get());
|
|
||||||
this.energyCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新目标方块的黑名单状态和倍率。
|
* 更新目标方块的黑名单状态和倍率。
|
||||||
*/
|
*/
|
||||||
private void updateTargetStatus() {
|
private void updateTargetStatus() {
|
||||||
BlockEntity target = getTargetBlockEntity();
|
BlockEntity target = this.getTargetBlockEntity();
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
this.multiplier = 1.0;
|
this.multiplier = 1.0;
|
||||||
this.targetBlacklisted = false;
|
this.targetBlacklisted = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String blockId = net.minecraft.core.registries.BuiltInRegistries.BLOCK.getKey(target.getBlockState().getBlock()).toString();
|
String blockId = BuiltInRegistries.BLOCK.getKey(target.getBlockState().getBlock()).toString();
|
||||||
this.multiplier = ConfigParsingUtils.getMultiplierForBlock(blockId, ModConfigs.ENTITY_TICKER_MULTIPLIERS.get());
|
this.multiplier = ConfigParsingUtils.getMultiplierForBlock(blockId, ModConfigs.ENTITY_TICKER_MULTIPLIERS.get());
|
||||||
this.targetBlacklisted = ConfigParsingUtils.isBlockBlacklisted(blockId, ModConfigs.ENTITY_TICKER_BLACK_LIST.get());
|
this.targetBlacklisted = ConfigParsingUtils.isBlockBlacklisted(blockId, ModConfigs.ENTITY_TICKER_BLACK_LIST.get());
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +128,8 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
|
||||||
* 计算生效速度(考虑黑名单和卡数量)。
|
* 计算生效速度(考虑黑名单和卡数量)。
|
||||||
*/
|
*/
|
||||||
private void updateEffectiveSpeed() {
|
private void updateEffectiveSpeed() {
|
||||||
this.effectiveSpeed = targetBlacklisted ? 0 : (int) PowerUtils.computeProductWithCap(getUpgrades(), 8);
|
this.effectiveSpeed =
|
||||||
|
this.targetBlacklisted ? 0 : (int) PowerUtils.computeProductWithCap(this.getUpgrades(), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -139,12 +143,13 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取目标方块实体。
|
* 获取目标方块实体。
|
||||||
|
*
|
||||||
* @return 目标方块实体或 null
|
* @return 目标方块实体或 null
|
||||||
*/
|
*/
|
||||||
private BlockEntity getTargetBlockEntity() {
|
private BlockEntity getTargetBlockEntity() {
|
||||||
return getHost() != null ?
|
return this.getHost() != null ?
|
||||||
getHost().getLevel().getBlockEntity(
|
this.getHost().getLevel().getBlockEntity(
|
||||||
getHost().getBlockEntity().getBlockPos().relative(getHost().getSide())
|
this.getHost().getBlockEntity().getBlockPos().relative(this.getHost().getSide())
|
||||||
) : null;
|
) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ import appeng.api.parts.IPartModel;
|
||||||
import appeng.api.storage.MEStorage;
|
import appeng.api.storage.MEStorage;
|
||||||
import appeng.api.upgrades.IUpgradeableObject;
|
import appeng.api.upgrades.IUpgradeableObject;
|
||||||
import appeng.api.util.IConfigManager;
|
import appeng.api.util.IConfigManager;
|
||||||
|
import appeng.api.util.IConfigManagerBuilder;
|
||||||
import appeng.core.definitions.AEItems;
|
import appeng.core.definitions.AEItems;
|
||||||
import appeng.items.parts.PartModels;
|
import appeng.items.parts.PartModels;
|
||||||
import appeng.menu.MenuOpener;
|
import appeng.menu.MenuOpener;
|
||||||
|
|
@ -30,8 +31,10 @@ import com.extendedae_plus.api.config.EAPSettings;
|
||||||
import com.extendedae_plus.config.ModConfigs;
|
import com.extendedae_plus.config.ModConfigs;
|
||||||
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.util.ExtendedAELogger;
|
||||||
import com.extendedae_plus.util.entitySpeed.ConfigParsingUtils;
|
import com.extendedae_plus.util.entitySpeed.ConfigParsingUtils;
|
||||||
import com.extendedae_plus.util.entitySpeed.PowerUtils;
|
import com.extendedae_plus.util.entitySpeed.PowerUtils;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
@ -39,6 +42,7 @@ import net.minecraft.world.MenuProvider;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
|
@ -55,14 +59,14 @@ import java.lang.reflect.Method;
|
||||||
* 功能受<a href="https://github.com/GilbertzRivi/crazyae2addons">Crazy AE2 Addons</a>启发
|
* 功能受<a href="https://github.com/GilbertzRivi/crazyae2addons">Crazy AE2 Addons</a>启发
|
||||||
*/
|
*/
|
||||||
public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTickable, MenuProvider, IUpgradeableObject {
|
public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTickable, MenuProvider, IUpgradeableObject {
|
||||||
public static final ResourceLocation MODEL_BASE = ResourceLocation.fromNamespaceAndPath(
|
private static final ResourceLocation MODEL_BASE = ResourceLocation.fromNamespaceAndPath(
|
||||||
ExtendedAEPlus.MODID, "part/entity_speed_ticker_part");
|
ExtendedAEPlus.MODID, "part/entity_speed_ticker_part");
|
||||||
@PartModels
|
@PartModels
|
||||||
public static final PartModel MODELS_OFF;
|
private static final PartModel MODELS_OFF;
|
||||||
@PartModels
|
@PartModels
|
||||||
public static final PartModel MODELS_ON;
|
private static final PartModel MODELS_ON;
|
||||||
@PartModels
|
@PartModels
|
||||||
public static final PartModel MODELS_HAS_CHANNEL;
|
private static final PartModel MODELS_HAS_CHANNEL;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
MODELS_OFF = new PartModel(MODEL_BASE, ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "part/entity_speed_ticker_off"));
|
MODELS_OFF = new PartModel(MODEL_BASE, ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "part/entity_speed_ticker_off"));
|
||||||
|
|
@ -70,10 +74,9 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
MODELS_HAS_CHANNEL = new PartModel(MODEL_BASE, ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "part/entity_speed_ticker_has_channel"));
|
MODELS_HAS_CHANNEL = new PartModel(MODEL_BASE, ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "part/entity_speed_ticker_has_channel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final IConfigManager configManager;
|
|
||||||
public EntitySpeedTickerMenu menu; // 当前打开的菜单实例
|
public EntitySpeedTickerMenu menu; // 当前打开的菜单实例
|
||||||
private YesNo networkEnergySufficient; // 网络能量是否充足
|
private YesNo networkEnergySufficient = YesNo.YES; // 网络能量是否充足
|
||||||
private YesNo redstoneState = YesNo.UNDECIDED;
|
|
||||||
/**
|
/**
|
||||||
* 构造函数,初始化部件并设置网络节点属性。
|
* 构造函数,初始化部件并设置网络节点属性。
|
||||||
*
|
*
|
||||||
|
|
@ -85,40 +88,66 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
.setFlags(GridFlags.REQUIRE_CHANNEL)
|
.setFlags(GridFlags.REQUIRE_CHANNEL)
|
||||||
.setIdlePowerUsage(1)
|
.setIdlePowerUsage(1)
|
||||||
.addService(IGridTickable.class, this);
|
.addService(IGridTickable.class, this);
|
||||||
configManager = IConfigManager.builder(this::configChanged)
|
|
||||||
.registerSetting(EAPSettings.ACCELERATE, YesNo.NO)
|
|
||||||
.registerSetting(EAPSettings.REDSTONE_CONTROL, YesNo.YES)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configChanged(IConfigManager manager, Setting<?> setting) {
|
@Override
|
||||||
this.saveChanges();
|
protected void registerSettings(IConfigManagerBuilder builder) {
|
||||||
}
|
super.registerSettings(builder);
|
||||||
|
builder.registerSetting(EAPSettings.ACCELERATE, YesNo.YES); // 默认开启加速
|
||||||
public void saveChanges() {
|
builder.registerSetting(EAPSettings.REDSTONE_CONTROL, YesNo.NO); // 默认忽略红石信号
|
||||||
getHost().markForSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAccelerate() {
|
|
||||||
return this.configManager.getSetting(EAPSettings.ACCELERATE) == YesNo.YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRedstoneControl() {
|
|
||||||
return this.configManager.getSetting(EAPSettings.REDSTONE_CONTROL) == YesNo.YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNetworkEnergySufficient() {
|
|
||||||
return this.networkEnergySufficient == YesNo.YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新网络能量充足状态并通知菜单。
|
* 获取可用的升级卡槽数量
|
||||||
*
|
*
|
||||||
* @param sufficient 是否能量充足
|
* @return 升级卡槽数量
|
||||||
*/
|
*/
|
||||||
private void setNetworkEnergySufficient(boolean sufficient) {
|
@Override
|
||||||
this.networkEnergySufficient = sufficient ? YesNo.YES : YesNo.NO;
|
protected int getUpgradeSlots() {
|
||||||
saveChanges();
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断当前是否应该休眠
|
||||||
|
@Override
|
||||||
|
protected boolean isSleeping() {
|
||||||
|
// 主开关没开 → 休眠
|
||||||
|
if (this.getConfigManager().getSetting(EAPSettings.ACCELERATE) != YesNo.YES) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 没开红石控制 → 一直工作
|
||||||
|
if (this.getConfigManager().getSetting(EAPSettings.REDSTONE_CONTROL) != YesNo.YES) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开启了红石控制 → 必须有红石信号才工作
|
||||||
|
return !this.getHost().hasRedstone(); // 没信号 → 休眠
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSettingChanged(IConfigManager manager, Setting<?> setting) {
|
||||||
|
// 每次玩家在 GUI 里点任何按钮(包括加速开关、红石控制开关)都会进来这里
|
||||||
|
this.getMainNode().ifPresent((grid, node) -> {
|
||||||
|
if (this.isSleeping()) {
|
||||||
|
grid.getTickManager().sleepDevice(node);
|
||||||
|
} else {
|
||||||
|
grid.getTickManager().wakeDevice(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNeighborChanged(BlockGetter level, BlockPos pos, BlockPos neighbor) {
|
||||||
|
// 只关心红石控制开启的情况下
|
||||||
|
if (this.getConfigManager().getSetting(EAPSettings.REDSTONE_CONTROL) == YesNo.YES) {
|
||||||
|
this.getMainNode().ifPresent((grid, node) -> {
|
||||||
|
if (this.getHost().hasRedstone()) {
|
||||||
|
grid.getTickManager().wakeDevice(node); // 有信号 → 立刻唤醒
|
||||||
|
} else {
|
||||||
|
grid.getTickManager().sleepDevice(node); // 没信号 → 立刻休眠
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -130,7 +159,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final boolean onUseWithoutItem(Player player, Vec3 pos) {
|
public final boolean onUseWithoutItem(Player player, Vec3 pos) {
|
||||||
if (!isClientSide()) {
|
if (!this.isClientSide()) {
|
||||||
MenuOpener.open(ModMenuTypes.ENTITY_TICKER_MENU.get(), player, MenuLocators.forPart(this));
|
MenuOpener.open(ModMenuTypes.ENTITY_TICKER_MENU.get(), player, MenuLocators.forPart(this));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -159,8 +188,30 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void getBoxes(IPartCollisionHelper bch) {
|
public void getBoxes(IPartCollisionHelper bch) {
|
||||||
bch.addBox(2, 2, 14, 14, 14, 16);
|
bch.addBox(3, 3, 14, 13, 13, 16);
|
||||||
bch.addBox(5, 5, 12, 11, 11, 14);
|
bch.addBox(5, 5, 11, 11, 11, 14);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveChanges() {
|
||||||
|
this.getHost().markForSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAccelerate() {
|
||||||
|
return this.getConfigManager().getSetting(EAPSettings.ACCELERATE) == YesNo.YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNetworkEnergySufficient() {
|
||||||
|
return this.networkEnergySufficient == YesNo.YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新网络能量充足状态并通知菜单。
|
||||||
|
*
|
||||||
|
* @param sufficient 是否能量充足
|
||||||
|
*/
|
||||||
|
private void setNetworkEnergySufficient(boolean sufficient) {
|
||||||
|
this.networkEnergySufficient = sufficient ? YesNo.YES : YesNo.NO;
|
||||||
|
this.saveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -172,7 +223,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
@Override
|
@Override
|
||||||
public TickingRequest getTickingRequest(IGridNode iGridNode) {
|
public TickingRequest getTickingRequest(IGridNode iGridNode) {
|
||||||
// 每 1 tick 执行一次
|
// 每 1 tick 执行一次
|
||||||
return new TickingRequest(1, 1, false);
|
return new TickingRequest(1, 1, this.isSleeping());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -184,23 +235,24 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TickRateModulation tickingRequest(IGridNode iGridNode, int ticksSinceLastCall) {
|
public TickRateModulation tickingRequest(IGridNode iGridNode, int ticksSinceLastCall) {
|
||||||
// 如果部件的加速开关被关闭,则不进行加速(提前返回)
|
if (!this.isAccelerate()) {
|
||||||
if (!isAccelerate()) {
|
|
||||||
return TickRateModulation.IDLE;
|
return TickRateModulation.IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查红石控制
|
if (this.isSleeping()) {
|
||||||
if (isRedstoneControl() && !getRedstoneState()) {
|
return TickRateModulation.SLEEP;
|
||||||
// 如果启用了红石控制且没有红石信号,则不执行加速
|
|
||||||
return TickRateModulation.IDLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取目标方块实体(本部件朝向的方块)
|
// 获取目标方块实体(本部件朝向的方块)
|
||||||
BlockEntity target = getLevel().getBlockEntity(getBlockEntity().getBlockPos().relative(getSide()));
|
BlockEntity target = this.getLevel().getBlockEntity(
|
||||||
|
this.getBlockEntity().getBlockPos().relative(this.getSide())
|
||||||
|
);
|
||||||
// 仅在目标存在且部件处于激活状态时执行加速
|
// 仅在目标存在且部件处于激活状态时执行加速
|
||||||
if (target != null && isActive()) {
|
if (target == null || !this.isActive()) {
|
||||||
ticker(target);
|
return TickRateModulation.IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.ticker(target);
|
||||||
return TickRateModulation.IDLE;
|
return TickRateModulation.IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,7 +263,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
* @param <T> 方块实体类型
|
* @param <T> 方块实体类型
|
||||||
*/
|
*/
|
||||||
private <T extends BlockEntity> void ticker(@NotNull T blockEntity) {
|
private <T extends BlockEntity> void ticker(@NotNull T blockEntity) {
|
||||||
if (!isValidForTicking()) {
|
if (!this.isValidForTicking()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,22 +272,22 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockEntityTicker<T> ticker = getTicker(blockEntity);
|
BlockEntityTicker<T> ticker = this.getTicker(blockEntity);
|
||||||
if (ticker == null) {
|
if (ticker == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int speed = calculateSpeed();
|
int speed = this.calculateSpeed();
|
||||||
if (speed <= 0) {
|
if (speed <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double requiredPower = calculateRequiredPower(speed, blockId);
|
double requiredPower = this.calculateRequiredPower(speed, blockId);
|
||||||
if (!extractPower(requiredPower)) {
|
if (!this.extractPower(requiredPower)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
performTicks(blockEntity, ticker, speed);
|
this.performTicks(blockEntity, ticker, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -244,7 +296,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
* @return 是否可以执行 tick
|
* @return 是否可以执行 tick
|
||||||
*/
|
*/
|
||||||
private boolean isValidForTicking() {
|
private boolean isValidForTicking() {
|
||||||
return getGridNode() != null && getMainNode() != null && getMainNode().getGrid() != null;
|
return this.getGridNode() != null && this.getMainNode() != null && this.getMainNode().getGrid() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -254,8 +306,8 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
* @return ticker 或 null
|
* @return ticker 或 null
|
||||||
*/
|
*/
|
||||||
private <T extends BlockEntity> BlockEntityTicker<T> getTicker(T blockEntity) {
|
private <T extends BlockEntity> BlockEntityTicker<T> getTicker(T blockEntity) {
|
||||||
return getLevel().getBlockState(blockEntity.getBlockPos())
|
return this.getLevel().getBlockState(blockEntity.getBlockPos())
|
||||||
.getTicker(getLevel(), (BlockEntityType<T>) blockEntity.getType());
|
.getTicker(this.getLevel(), (BlockEntityType<T>) blockEntity.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -264,9 +316,9 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
* @return 生效的加速倍率
|
* @return 生效的加速倍率
|
||||||
*/
|
*/
|
||||||
private int calculateSpeed() {
|
private int calculateSpeed() {
|
||||||
int entitySpeedCardCount = getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get());
|
int entitySpeedCardCount = this.getUpgrades().getInstalledUpgrades(ModItems.ENTITY_SPEED_CARD.get());
|
||||||
if (entitySpeedCardCount <= 0) return 0;
|
if (entitySpeedCardCount <= 0) return 0;
|
||||||
return (int) PowerUtils.computeProductWithCap(getUpgrades(), 8);
|
return (int) PowerUtils.computeProductWithCap(this.getUpgrades(), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -277,7 +329,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
* @return 所需能量
|
* @return 所需能量
|
||||||
*/
|
*/
|
||||||
private double calculateRequiredPower(int speed, String blockId) {
|
private double calculateRequiredPower(int speed, String blockId) {
|
||||||
int energyCardCount = getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD);
|
int energyCardCount = this.getUpgrades().getInstalledUpgrades(AEItems.ENERGY_CARD);
|
||||||
double multiplier = ConfigParsingUtils.getMultiplierForBlock(blockId, ModConfigs.ENTITY_TICKER_MULTIPLIERS.get());
|
double multiplier = ConfigParsingUtils.getMultiplierForBlock(blockId, ModConfigs.ENTITY_TICKER_MULTIPLIERS.get());
|
||||||
return PowerUtils.computeFinalPowerForProduct(speed, energyCardCount) * multiplier;
|
return PowerUtils.computeFinalPowerForProduct(speed, energyCardCount) * multiplier;
|
||||||
}
|
}
|
||||||
|
|
@ -289,15 +341,15 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
* @return 是否成功提取足够能量
|
* @return 是否成功提取足够能量
|
||||||
*/
|
*/
|
||||||
private boolean extractPower(double requiredPower) {
|
private boolean extractPower(double requiredPower) {
|
||||||
IEnergyService energyService = getMainNode().getGrid().getEnergyService();
|
IEnergyService energyService = this.getMainNode().getGrid().getEnergyService();
|
||||||
MEStorage storage = getMainNode().getGrid().getStorageService().getInventory();
|
MEStorage storage = this.getMainNode().getGrid().getStorageService().getInventory();
|
||||||
IActionSource source = IActionSource.ofMachine(this);
|
IActionSource source = IActionSource.ofMachine(this);
|
||||||
boolean appFluxLoaded = ModList.get().isLoaded("appflux");
|
boolean appFluxLoaded = ModList.get().isLoaded("appflux");
|
||||||
boolean preferDiskEnergy = appFluxLoaded && ModConfigs.PRIORITIZE_DISK_ENERGY.get();
|
boolean preferDiskEnergy = appFluxLoaded && ModConfigs.PRIORITIZE_DISK_ENERGY.get();
|
||||||
|
|
||||||
// 如果 appflux 存在且优先磁盘能量,尝试提取 FE 能量
|
// 如果 appflux 存在且优先磁盘能量,尝试提取 FE 能量
|
||||||
if (appFluxLoaded && preferDiskEnergy) {
|
if (appFluxLoaded && preferDiskEnergy) {
|
||||||
if (tryExtractFE(energyService, storage, requiredPower, source)) {
|
if (this.tryExtractFE(energyService, storage, requiredPower, source)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -307,21 +359,21 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
if (simulated >= requiredPower) {
|
if (simulated >= requiredPower) {
|
||||||
double extracted = energyService.extractAEPower(requiredPower, Actionable.MODULATE, PowerMultiplier.CONFIG);
|
double extracted = energyService.extractAEPower(requiredPower, Actionable.MODULATE, PowerMultiplier.CONFIG);
|
||||||
boolean sufficient = extracted >= requiredPower;
|
boolean sufficient = extracted >= requiredPower;
|
||||||
setNetworkEnergySufficient(sufficient);
|
this.setNetworkEnergySufficient(sufficient);
|
||||||
return sufficient;
|
return sufficient;
|
||||||
}
|
}
|
||||||
setNetworkEnergySufficient(false);
|
this.setNetworkEnergySufficient(false);
|
||||||
|
|
||||||
// 如果 appflux 存在且优先 AE 能量,尝试提取 FE 能量作为备用
|
// 如果 appflux 存在且优先 AE 能量,尝试提取 FE 能量作为备用
|
||||||
if (appFluxLoaded && !preferDiskEnergy) {
|
if (appFluxLoaded && !preferDiskEnergy) {
|
||||||
return tryExtractFE(energyService, storage, requiredPower, source);
|
return this.tryExtractFE(energyService, storage, requiredPower, source);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
@ -332,13 +384,13 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
long feRequired = (long) requiredPower << 1; // 1 AE = 2 FE
|
long feRequired = (long) requiredPower << 1; // 1 AE = 2 FE
|
||||||
long feExtracted = (long) extractMethod.invoke(null, energyService, storage, feRequired, source);
|
long feExtracted = (long) extractMethod.invoke(null, energyService, storage, feRequired, source);
|
||||||
if (feExtracted >= feRequired) {
|
if (feExtracted >= feRequired) {
|
||||||
setNetworkEnergySufficient(true);
|
this.setNetworkEnergySufficient(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 如果反射失败,视为 FE 不可用
|
// 如果反射失败,视为 FE 不可用
|
||||||
}
|
}
|
||||||
setNetworkEnergySufficient(false);
|
this.setNetworkEnergySufficient(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -354,12 +406,41 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
int speed) {
|
int speed) {
|
||||||
// 执行 speed-1 次额外 tick(原生 tick 已包含 1 次)
|
// 执行 speed-1 次额外 tick(原生 tick 已包含 1 次)
|
||||||
for (int i = 0; i < speed - 1; i++) {
|
for (int i = 0; i < speed - 1; i++) {
|
||||||
ticker.tick(
|
try {
|
||||||
blockEntity.getLevel(),
|
ticker.tick(
|
||||||
blockEntity.getBlockPos(),
|
blockEntity.getLevel(),
|
||||||
blockEntity.getBlockState(),
|
blockEntity.getBlockPos(),
|
||||||
blockEntity
|
blockEntity.getBlockState(),
|
||||||
);
|
blockEntity
|
||||||
|
);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// 捕获随机数生成器的多线程访问异常
|
||||||
|
// 这通常发生在某些模组(如 Thermal)的机器使用随机数时
|
||||||
|
// 由于加速导致在同一tick内多次访问随机数生成器而触发 ThreadingDetector
|
||||||
|
if (e.getMessage() != null && e.getMessage().contains("LegacyRandomSource")) {
|
||||||
|
// 记录警告并停止当前加速循环,避免崩溃
|
||||||
|
ExtendedAELogger.LOGGER.warn(
|
||||||
|
"检测到方块实体 {} 在位置 {} 的随机数访问冲突,已停止本次加速以避免崩溃。" +
|
||||||
|
"建议将此方块类型添加到配置黑名单中。",
|
||||||
|
blockEntity.getType().toString(),
|
||||||
|
blockEntity.getBlockPos()
|
||||||
|
);
|
||||||
|
break; // 停止后续的加速 tick
|
||||||
|
} else {
|
||||||
|
// 如果是其他类型的 IllegalStateException,继续抛出
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 捕获其他可能的异常,防止崩溃
|
||||||
|
ExtendedAELogger.LOGGER.error(
|
||||||
|
"在加速方块实体 {} 位置 {} 时发生错误: {}",
|
||||||
|
blockEntity.getType().toString(),
|
||||||
|
blockEntity.getBlockPos(),
|
||||||
|
e.getMessage(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
break; // 停止后续的加速 tick
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -397,46 +478,4 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
|
||||||
@NotNull Player player) {
|
@NotNull Player player) {
|
||||||
return new EntitySpeedTickerMenu(containerId, playerInventory, this);
|
return new EntitySpeedTickerMenu(containerId, playerInventory, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取可用的升级卡槽数量
|
|
||||||
*
|
|
||||||
* @return 升级卡槽数量
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected int getUpgradeSlots() {
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当升级卡数量发生变化时调用,通知菜单更新
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void upgradesChanged() {
|
|
||||||
if (this.menu != null) {
|
|
||||||
// 使用 AE2 风格:当升级发生变化时让菜单广播变化(槽/数据会被同步),客户端会基于槽内容重新计算并刷新界面
|
|
||||||
this.menu.broadcastChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IConfigManager getConfigManager() {
|
|
||||||
return this.configManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取红石信号状态
|
|
||||||
private boolean getRedstoneState() {
|
|
||||||
// 每次调用都更新红石状态,确保及时性
|
|
||||||
updateRedstoneState();
|
|
||||||
return redstoneState == YesNo.YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新红石信号状态
|
|
||||||
private void updateRedstoneState() {
|
|
||||||
var be = this.getHost().getBlockEntity();
|
|
||||||
if (be != null && be.getLevel() != null) {
|
|
||||||
redstoneState = be.getLevel().hasNeighborSignal(be.getBlockPos())
|
|
||||||
? YesNo.YES
|
|
||||||
: YesNo.NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -11,16 +11,13 @@ import com.extendedae_plus.api.config.EAPSettings;
|
||||||
import com.extendedae_plus.client.gui.widgets.EAPServerSettingToggleButton;
|
import com.extendedae_plus.client.gui.widgets.EAPServerSettingToggleButton;
|
||||||
import com.extendedae_plus.client.gui.widgets.EAPSettingToggleButton;
|
import com.extendedae_plus.client.gui.widgets.EAPSettingToggleButton;
|
||||||
import com.extendedae_plus.util.entitySpeed.PowerUtils;
|
import com.extendedae_plus.util.entitySpeed.PowerUtils;
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
|
||||||
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 java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class EntitySpeedTickerScreen extends UpgradeableScreen<EntitySpeedTickerMenu> {
|
public class EntitySpeedTickerScreen extends UpgradeableScreen<EntitySpeedTickerMenu> {
|
||||||
private final EAPSettingToggleButton<YesNo> accelerateButton; // 加速开关按钮
|
private final EAPSettingToggleButton<YesNo> accelerateButton; // 加速开关按钮
|
||||||
private final EAPSettingToggleButton<YesNo> redstoneControlButton; // 加速开关按钮
|
private final EAPSettingToggleButton<YesNo> redstoneControlButton; // 加速开关按钮
|
||||||
|
private final TextUpdater textUpdater = new TextUpdater();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造函数,初始化界面和控件。
|
* 构造函数,初始化界面和控件。
|
||||||
|
|
@ -37,7 +34,7 @@ public class EntitySpeedTickerScreen extends UpgradeableScreen<EntitySpeedTicker
|
||||||
super(menu, playerInventory, title, style);
|
super(menu, playerInventory, title, style);
|
||||||
this.addToLeftToolbar(CommonButtons.togglePowerUnit()); // 添加功率单位切换按钮
|
this.addToLeftToolbar(CommonButtons.togglePowerUnit()); // 添加功率单位切换按钮
|
||||||
|
|
||||||
this.accelerateButton = new EAPServerSettingToggleButton<>(EAPSettings.ACCELERATE, YesNo.NO);
|
this.accelerateButton = new EAPServerSettingToggleButton<>(EAPSettings.ACCELERATE, YesNo.YES);
|
||||||
this.addToLeftToolbar(this.accelerateButton);
|
this.addToLeftToolbar(this.accelerateButton);
|
||||||
|
|
||||||
this.redstoneControlButton = new EAPServerSettingToggleButton<>(EAPSettings.REDSTONE_CONTROL, YesNo.NO);
|
this.redstoneControlButton = new EAPServerSettingToggleButton<>(EAPSettings.REDSTONE_CONTROL, YesNo.NO);
|
||||||
|
|
@ -54,47 +51,55 @@ public class EntitySpeedTickerScreen extends UpgradeableScreen<EntitySpeedTicker
|
||||||
} else {
|
} else {
|
||||||
this.accelerateButton.set(this.menu.getAccelerate());
|
this.accelerateButton.set(this.menu.getAccelerate());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.redstoneControlButton.set(this.menu.getRedstoneControl());
|
this.redstoneControlButton.set(this.menu.getRedstoneControl());
|
||||||
this.textData();
|
// 文本更新统一处理
|
||||||
}
|
this.textUpdater.update();
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drawBG(GuiGraphics guiGraphics, int offsetX, int offsetY, int mouseX, int mouseY, float partialTicks) {
|
|
||||||
super.drawBG(guiGraphics, offsetX, offsetY, mouseX, mouseY, partialTicks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshGui() {
|
public void refreshGui() {
|
||||||
this.textData();
|
this.textUpdater.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private class TextUpdater {
|
||||||
* 更新界面文本内容,包括加速状态、速度、能耗和倍率。
|
void update() {
|
||||||
*/
|
if (EntitySpeedTickerScreen.this.menu.targetBlacklisted) {
|
||||||
private void textData() {
|
this.updateBlacklist();
|
||||||
Map<String, Component> textContents = new HashMap<>();
|
} else {
|
||||||
if (this.getMenu().targetBlacklisted) {
|
this.updateNormal();
|
||||||
// 黑名单禁用时的默认显示
|
}
|
||||||
textContents.put("enable", Component.translatable("screen.extendedae_plus.entity_speed_ticker.enable"));
|
}
|
||||||
textContents.put("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", 0));
|
|
||||||
textContents.put("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(0.0, false)));
|
private void updateBlacklist() {
|
||||||
textContents.put("power_ratio", Component.translatable("screen.extendedae_plus.entity_speed_ticker.power_ratio", PowerUtils.formatPercentage(0.0)));
|
this.set("enable", this.translatable("enable"));
|
||||||
textContents.put("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", 0.0)));
|
this.set("speed", this.translatable("speed", 0));
|
||||||
} else {
|
this.set("energy", this.translatable("energy", Platform.formatPower(0, false)));
|
||||||
// 正常状态下显示实际数据
|
this.set("power_ratio", this.translatable("power_ratio", PowerUtils.formatPercentage(0.0)));
|
||||||
int energyCardCount = this.getMenu().energyCardCount;
|
this.set("multiplier", this.translatable("multiplier", "0.00x"));
|
||||||
double multiplier = this.getMenu().multiplier;
|
}
|
||||||
int effectiveSpeed = this.getMenu().effectiveSpeed;
|
|
||||||
double finalPower = PowerUtils.computeFinalPowerForProduct(effectiveSpeed, energyCardCount);
|
private void updateNormal() {
|
||||||
double remainingRatio = PowerUtils.getRemainingRatio(energyCardCount);
|
int energyCardCount = EntitySpeedTickerScreen.this.menu.energyCardCount;
|
||||||
|
double multiplier = EntitySpeedTickerScreen.this.menu.multiplier;
|
||||||
textContents.put("enable", this.getMenu().networkEnergySufficient == YesNo.YES ? null :
|
int effectiveSpeed = EntitySpeedTickerScreen.this.menu.effectiveSpeed;
|
||||||
Component.translatable("screen.extendedae_plus.entity_speed_ticker.warning_network_energy_insufficient"));
|
double finalPower = PowerUtils.computeFinalPowerForProduct(effectiveSpeed, energyCardCount);
|
||||||
textContents.put("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", effectiveSpeed));
|
double powerRatio = PowerUtils.getRemainingRatio(energyCardCount);
|
||||||
textContents.put("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(finalPower, false)));
|
|
||||||
textContents.put("power_ratio", Component.translatable("screen.extendedae_plus.entity_speed_ticker.power_ratio", PowerUtils.formatPercentage(remainingRatio)));
|
this.set("enable", EntitySpeedTickerScreen.this.menu.networkEnergySufficient == YesNo.YES
|
||||||
textContents.put("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", multiplier)));
|
? null
|
||||||
|
: this.translatable("warning_network_energy_insufficient"));
|
||||||
|
|
||||||
|
this.set("speed", this.translatable("speed", effectiveSpeed));
|
||||||
|
this.set("energy", this.translatable("energy", Platform.formatPower(finalPower, false)));
|
||||||
|
this.set("power_ratio", this.translatable("power_ratio", PowerUtils.formatPercentage(powerRatio)));
|
||||||
|
this.set("multiplier", this.translatable("multiplier", String.format("%.2fx", multiplier)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Component translatable(String key, Object... args) {
|
||||||
|
return Component.translatable("screen.extendedae_plus.entity_speed_ticker." + key, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void set(String id, Component c) {
|
||||||
|
EntitySpeedTickerScreen.this.setTextContent(id, c);
|
||||||
}
|
}
|
||||||
textContents.forEach(this::setTextContent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
@ -8,52 +8,54 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ExtendedAEPlusMixinPlugin implements IMixinConfigPlugin {
|
public class ExtendedAEPlusMixinPlugin implements IMixinConfigPlugin {
|
||||||
private static boolean isClassPresent(String className) {
|
private static boolean isClassPresent(String className) {
|
||||||
try {
|
try {
|
||||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||||
Class.forName(className, false, cl);
|
Class.forName(className, false, cl);
|
||||||
return true;
|
return true;
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isJeiPresent() {
|
private static boolean isJeiPresent() {
|
||||||
return isClassPresent("mezz.jei.api.IModPlugin");
|
return isClassPresent("mezz.jei.api.IModPlugin");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isAdvancedAePresent() {
|
private static boolean isAdvancedAePresent() {
|
||||||
return isClassPresent("net.pedroksl.advanced_ae.AdvancedAE");
|
return isClassPresent("net.pedroksl.advanced_ae.AdvancedAE");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad(String mixinPackage) { }
|
public void onLoad(String mixinPackage) { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRefMapperConfig() { return null; }
|
public String getRefMapperConfig() { return null; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||||
if (!isJeiPresent()) {
|
if (!isJeiPresent()) {
|
||||||
// Disable all JEI package mixins and any mixins that reference JEI-only helpers
|
// Disable all JEI package mixins and any mixins that reference JEI-only helpers
|
||||||
if (mixinClassName.startsWith("com.extendedae_plus.mixin.jei")) return false;
|
if (mixinClassName.startsWith("com.extendedae_plus.mixin.jei")) return false;
|
||||||
if (mixinClassName.equals("com.extendedae_plus.mixin.ae2.menu.CraftConfirmMenuGoBackMixin")) return false;
|
if (mixinClassName.equals("com.extendedae_plus.mixin.ae2.menu.CraftConfirmMenuGoBackMixin")) return false;
|
||||||
}
|
}
|
||||||
if (!isAdvancedAePresent()) {
|
if (!isAdvancedAePresent()) {
|
||||||
if (mixinClassName.equals("com.extendedae_plus.mixin.advancedae.compat.PatternProviderLogicVirtualCompletionMixin")) {
|
if (mixinClassName.equals("com.extendedae_plus.mixin.advancedae.compat.PatternProviderLogicVirtualCompletionMixin")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public List<String> getMixins() { return null; }
|
|
||||||
|
@Override
|
||||||
|
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getMixins() {return null;}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { }
|
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { }
|
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { }
|
||||||
|
|
||||||
@Override
|
|
||||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { }
|
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public abstract class PatternProviderLogicVirtualCompletionMixin {
|
||||||
|
|
||||||
@Inject(method = "pushPattern", at = @At("RETURN"))
|
@Inject(method = "pushPattern", at = @At("RETURN"))
|
||||||
private void eap$advancedaeVirtualCompletion(IPatternDetails patternDetails, KeyCounter[] inputHolder,
|
private void eap$advancedaeVirtualCompletion(IPatternDetails patternDetails, KeyCounter[] inputHolder,
|
||||||
CallbackInfoReturnable<Boolean> cir) {
|
CallbackInfoReturnable<Boolean> cir) {
|
||||||
if (!cir.getReturnValueZ()) {
|
if (!cir.getReturnValueZ()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,12 +4,11 @@ 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;
|
||||||
import com.glodblock.github.extendedae.client.button.ActionEPPButton;
|
import com.glodblock.github.extendedae.client.button.ActionEPPButton;
|
||||||
import com.mojang.logging.LogUtils;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.world.inventory.Slot;
|
import net.minecraft.world.inventory.Slot;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
@ -41,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();
|
||||||
|
|
@ -177,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;
|
||||||
|
|
@ -192,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();
|
||||||
|
|
@ -220,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 + imageWidth + 1;
|
int bx = leftPos - this.eap$divideBy2Button.getWidth() - 1;
|
||||||
int by = topPos + 70;
|
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) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,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,18 +12,17 @@ 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.PatternProviderLogicVirtualCompatBridge;
|
import com.extendedae_plus.compat.PatternProviderLogicVirtualCompatBridge;
|
||||||
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
import com.extendedae_plus.compat.UpgradeSlotCompat;
|
||||||
import com.extendedae_plus.init.ModItems;
|
import com.extendedae_plus.init.ModItems;
|
||||||
|
import com.extendedae_plus.items.materials.ChannelCardItem;
|
||||||
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;
|
||||||
|
|
@ -91,7 +90,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);
|
||||||
|
|
@ -102,10 +101,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);
|
||||||
}
|
}
|
||||||
|
|
@ -147,10 +146,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);
|
||||||
}
|
}
|
||||||
|
|
@ -183,11 +182,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) {
|
||||||
|
|
@ -200,22 +199,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,7 +332,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 升级槽,回退到兼容槽");
|
||||||
|
|
@ -245,20 +348,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,23 +378,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) {}
|
||||||
|
|
@ -303,140 +409,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -471,14 +479,13 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -531,7 +538,6 @@ public abstract class PatternProviderLogicCompatMixin implements CompatUpgradePr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -549,8 +555,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);
|
||||||
}
|
}
|
||||||
|
|
@ -562,14 +568,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;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user