重构实体加速器界面代码;参考ae2结构构建eap按钮相关注册类替换原按钮使用逻辑;优化import

This commit is contained in:
C-H716 2025-11-24 02:13:17 +08:00
parent 99a492f4c0
commit 8e87508b62
29 changed files with 575 additions and 278 deletions

View File

@ -1,11 +1,13 @@
package com.extendedae_plus.ae.menu;
import appeng.api.config.YesNo;
import appeng.api.util.IConfigManager;
import appeng.core.definitions.AEItems;
import appeng.menu.guisync.GuiSync;
import appeng.menu.implementations.UpgradeableMenu;
import appeng.menu.slot.OptionalFakeSlot;
import com.extendedae_plus.ae.parts.EntitySpeedTickerPart;
import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen;
import com.extendedae_plus.api.config.EAPSettings;
import com.extendedae_plus.config.ModConfigs;
import com.extendedae_plus.init.ModItems;
import com.extendedae_plus.init.ModMenuTypes;
@ -21,14 +23,21 @@ import net.minecraft.world.level.block.entity.BlockEntity;
* 实体加速器菜单负责管理客户端与服务端的数据同步处理加速卡能量卡和目标方块的状态
*/
public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart> {
@GuiSync(716) public boolean accelerateEnabled = true; // 是否启用加速
@GuiSync(717) public int entitySpeedCardCount; // 已安装的实体加速卡数量
@GuiSync(718) public int energyCardCount; // 已安装的能量卡数量
@GuiSync(719) public int effectiveSpeed = 1; // 当前生效的加速倍率
@GuiSync(720) public double multiplier = 1.0; // 目标方块的配置倍率
@GuiSync(721) public boolean targetBlacklisted = false; // 目标方块是否在黑名单中
@GuiSync(722) public boolean networkEnergySufficient = true; // 网络能量是否充足
@GuiSync(716) public YesNo accelerate; // 是否启用加速
@GuiSync(717) public YesNo redstoneControl; // 是否启用红石控制
private int entitySpeedCardCount; // 已安装的实体加速卡数量
@GuiSync(719) public int energyCardCount; // 已安装的能量卡数量
@GuiSync(720) public int effectiveSpeed = 1; // 当前生效的加速倍率
@GuiSync(721) public double multiplier = 1.0; // 目标方块的配置倍率
@GuiSync(722) public boolean targetBlacklisted = false; // 目标方块是否在黑名单中
@GuiSync(723) public YesNo networkEnergySufficient; // 网络能量是否充足
protected final EntitySpeedTickerPart logic;
@Override
protected void loadSettingsFromHost(IConfigManager cm) {
// 不需要模糊模式
}
/**
* 构造函数初始化菜单并绑定部件
* @param id 菜单ID
@ -37,39 +46,7 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
*/
public EntitySpeedTickerMenu(int id, Inventory ip, EntitySpeedTickerPart host) {
super(ModMenuTypes.ENTITY_TICKER_MENU.get(), id, ip, host);
if (host != null) {
host.menu = this; // 绑定菜单到部件
this.accelerateEnabled = host.getAccelerateEnabled(); // 同步初始开关状态
}
}
/**
* 获取加速开关状态
* @return 是否启用加速
*/
public boolean getAccelerateEnabled() {
return this.accelerateEnabled;
}
/**
* 设置加速开关状态并同步到部件
* @param enabled 是否启用加速
*/
public void setAccelerateEnabled(boolean enabled) {
this.accelerateEnabled = enabled;
if (getHost() != null) {
getHost().setAccelerateEnabled(enabled); // 同步到部件
}
broadcastChanges(); // 广播状态变化
}
/**
* 更新网络能量充足状态并广播到客户端
* @param sufficient 是否能量充足
*/
public void setNetworkEnergySufficient(boolean sufficient) {
this.networkEnergySufficient = sufficient;
broadcastChanges();
this.logic = host;
}
/**
@ -81,7 +58,7 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
updateCardCounts(); // 更新卡数量
updateTargetStatus(); // 更新目标方块的黑名单和倍率
updateEffectiveSpeed(); // 计算生效速度
updateNetworkEnergyStatus(); // 同步能量状态
// updateNetworkEnergyStatus(); // 同步能量状态
if (isClientSide()) {
refreshClientGui(); // 客户端刷新界面
}
@ -106,14 +83,21 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
*/
@Override
public void broadcastChanges() {
for (Object o : this.slots) {
if (o instanceof OptionalFakeSlot fs && !fs.isSlotEnabled() && !fs.getDisplayStack().isEmpty()) {
fs.clearStack(); // 清理未启用槽位的显示
}
if (isServerSide()) {
this.accelerate = logic.getConfigManager().getSetting(EAPSettings.ACCELERATE);
this.redstoneControl = logic.getConfigManager().getSetting(EAPSettings.REDSTONE_CONTROL);
this.networkEnergySufficient = logic.isNetworkEnergySufficient() ? YesNo.YES : YesNo.NO;
}
standardDetectAndSendChanges();
super.broadcastChanges();
}
public YesNo getAccelerate() {
return this.accelerate;
}
public YesNo getRedstoneControl() {
return this.redstoneControl;
}
/**
* 更新加速卡和能量卡的数量
*/
@ -144,15 +128,6 @@ public class EntitySpeedTickerMenu extends UpgradeableMenu<EntitySpeedTickerPart
this.effectiveSpeed = targetBlacklisted ? 0 : (int) PowerUtils.computeProductWithCap(getUpgrades(), 8);
}
/**
* 同步网络能量状态仅服务端
*/
private void updateNetworkEnergyStatus() {
if (!isClientSide() && getHost() != null) {
this.networkEnergySufficient = getHost().isNetworkEnergySufficient();
}
}
/**
* 客户端刷新界面
*/

View File

@ -1,7 +1,10 @@
package com.extendedae_plus.ae.parts;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.config.Setting;
import appeng.api.config.YesNo;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergyService;
@ -14,6 +17,7 @@ import appeng.api.parts.IPartItem;
import appeng.api.parts.IPartModel;
import appeng.api.storage.MEStorage;
import appeng.api.upgrades.IUpgradeableObject;
import appeng.api.util.IConfigManager;
import appeng.core.definitions.AEItems;
import appeng.items.parts.PartModels;
import appeng.menu.MenuOpener;
@ -22,6 +26,7 @@ import appeng.parts.PartModel;
import appeng.parts.automation.UpgradeablePart;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu;
import com.extendedae_plus.api.config.EAPSettings;
import com.extendedae_plus.config.ModConfigs;
import com.extendedae_plus.init.ModItems;
import com.extendedae_plus.init.ModMenuTypes;
@ -65,13 +70,13 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
MODELS_HAS_CHANNEL = new PartModel(MODEL_BASE, ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "part/entity_speed_ticker_has_channel"));
}
private final IConfigManager configManager;
public EntitySpeedTickerMenu menu; // 当前打开的菜单实例
private boolean accelerateEnabled = true; // 是否启用加速
private boolean networkEnergySufficient = true; // 网络能量是否充足
private YesNo networkEnergySufficient; // 网络能量是否充足
private YesNo redstoneState = YesNo.UNDECIDED;
/**
* 构造函数初始化部件并设置网络节点属性
*
* @param partItem 部件物品
*/
public EntitySpeedTickerPart(IPartItem<?> partItem) {
@ -80,51 +85,40 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
.setFlags(GridFlags.REQUIRE_CHANNEL)
.setIdlePowerUsage(1)
.addService(IGridTickable.class, this);
configManager = IConfigManager.builder(this::configChanged)
.registerSetting(EAPSettings.ACCELERATE, YesNo.NO)
.registerSetting(EAPSettings.REDSTONE_CONTROL, YesNo.YES)
.build();
}
public boolean getAccelerateEnabled() {
return this.accelerateEnabled;
private void configChanged(IConfigManager manager, Setting<?> setting) {
this.saveChanges();
}
public void saveChanges() {
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;
}
/**
* 设置加速开关状态并通知菜单
* @param enabled 是否启用加速
*/
public void setAccelerateEnabled(boolean enabled) {
this.accelerateEnabled = enabled;
if (menu != null) {
menu.setAccelerateEnabled(enabled);
}
return this.networkEnergySufficient == YesNo.YES;
}
/**
* 更新网络能量充足状态并通知菜单
*
* @param sufficient 是否能量充足
*/
private void updateNetworkEnergySufficient(boolean sufficient) {
this.networkEnergySufficient = sufficient;
if (menu != null) {
menu.setNetworkEnergySufficient(sufficient);
}
}
/**
* 获取当前状态的渲染模型
* @return 当前状态的模型
*/
@Override
public IPartModel getStaticModels() {
if (this.isActive() && this.isPowered()) {
return MODELS_HAS_CHANNEL;
} else if (this.isPowered()) {
return MODELS_ON;
} else {
return MODELS_OFF;
}
private void setNetworkEnergySufficient(boolean sufficient) {
this.networkEnergySufficient = sufficient ? YesNo.YES : YesNo.NO;
saveChanges();
}
/**
@ -142,6 +136,22 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
return true;
}
/**
* 获取当前状态的渲染模型
*
* @return 当前状态的模型
*/
@Override
public IPartModel getStaticModels() {
if (this.isActive() && this.isPowered()) {
return MODELS_HAS_CHANNEL;
} else if (this.isPowered()) {
return MODELS_ON;
} else {
return MODELS_OFF;
}
}
/**
* 定义部件的碰撞箱用于物理碰撞和渲染
*
@ -165,17 +175,6 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
return new TickingRequest(1, 1, false);
}
/**
* 当升级卡数量发生变化时调用通知菜单更新
*/
@Override
public void upgradesChanged() {
if (this.menu != null) {
// 使用 AE2 风格当升级发生变化时让菜单广播变化/数据会被同步客户端会基于槽内容重新计算并刷新界面
this.menu.broadcastChanges();
}
}
/**
* 网络定时回调每次 tick 时调用
*
@ -186,7 +185,13 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
@Override
public TickRateModulation tickingRequest(IGridNode iGridNode, int ticksSinceLastCall) {
// 如果部件的加速开关被关闭则不进行加速提前返回
if (!this.getAccelerateEnabled()) {
if (!isAccelerate()) {
return TickRateModulation.IDLE;
}
// 检查红石控制
if (isRedstoneControl() && !getRedstoneState()) {
// 如果启用了红石控制且没有红石信号则不执行加速
return TickRateModulation.IDLE;
}
@ -201,8 +206,9 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
/**
* 对目标方块实体执行加速 tick 操作
*
* @param blockEntity 目标方块实体
* @param <T> 方块实体类型
* @param <T> 方块实体类型
*/
private <T extends BlockEntity> void ticker(@NotNull T blockEntity) {
if (!isValidForTicking()) {
@ -234,6 +240,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
/**
* 检查网络节点是否有效
*
* @return 是否可以执行 tick
*/
private boolean isValidForTicking() {
@ -242,6 +249,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
/**
* 获取目标方块实体的 ticker
*
* @param blockEntity 目标方块实体
* @return ticker null
*/
@ -252,6 +260,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
/**
* 计算加速倍率
*
* @return 生效的加速倍率
*/
private int calculateSpeed() {
@ -262,7 +271,8 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
/**
* 计算所需能量
* @param speed 加速倍率
*
* @param speed 加速倍率
* @param blockId 目标方块ID
* @return 所需能量
*/
@ -274,6 +284,7 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
/**
* 提取网络能量并更新状态优先从 AE2 网络提取 AE 能量不足时从磁盘提取 FE 能量
*
* @param requiredPower 所需能量AE 单位
* @return 是否成功提取足够能量
*/
@ -296,10 +307,10 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
if (simulated >= requiredPower) {
double extracted = energyService.extractAEPower(requiredPower, Actionable.MODULATE, PowerMultiplier.CONFIG);
boolean sufficient = extracted >= requiredPower;
updateNetworkEnergySufficient(sufficient);
setNetworkEnergySufficient(sufficient);
return sufficient;
}
updateNetworkEnergySufficient(false);
setNetworkEnergySufficient(false);
// 如果 appflux 存在且优先 AE 能量尝试提取 FE 能量作为备用
if (appFluxLoaded && !preferDiskEnergy) {
@ -321,21 +332,22 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
long feRequired = (long) requiredPower << 1; // 1 AE = 2 FE
long feExtracted = (long) extractMethod.invoke(null, energyService, storage, feRequired, source);
if (feExtracted >= feRequired) {
updateNetworkEnergySufficient(true);
setNetworkEnergySufficient(true);
return true;
}
} catch (Exception e) {
// 如果反射失败视为 FE 不可用
}
updateNetworkEnergySufficient(false);
setNetworkEnergySufficient(false);
return false;
}
/**
* 执行加速 tick 操作
*
* @param blockEntity 目标方块实体
* @param ticker 方块实体 ticker
* @param speed 加速倍率
* @param ticker 方块实体 ticker
* @param speed 加速倍率
*/
private <T extends BlockEntity> void performTicks(T blockEntity,
BlockEntityTicker<T> ticker,
@ -395,4 +407,36 @@ public class EntitySpeedTickerPart extends UpgradeablePart implements IGridTicka
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;
}
}
}

View File

@ -1,90 +1,71 @@
package com.extendedae_plus.ae.screen;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.client.gui.Icon;
import appeng.client.gui.implementations.UpgradeableScreen;
import appeng.client.gui.style.ScreenStyle;
import appeng.client.gui.widgets.CommonButtons;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.util.Platform;
import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu;
import com.extendedae_plus.network.ToggleEntityTickerC2SPacket;
import com.extendedae_plus.api.config.EAPSettings;
import com.extendedae_plus.client.gui.widgets.EAPServerSettingToggleButton;
import com.extendedae_plus.client.gui.widgets.EAPSettingToggleButton;
import com.extendedae_plus.util.entitySpeed.PowerUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EntitySpeedTickerScreen<C extends EntitySpeedTickerMenu> extends UpgradeableScreen<C> {
private boolean eap$entitySpeedTickerEnabled = false; // 本地缓存的加速开关状态
private final SettingToggleButton<YesNo> eap$entitySpeedTickerToggle; // 加速开关按钮
public class EntitySpeedTickerScreen extends UpgradeableScreen<EntitySpeedTickerMenu> {
private final EAPSettingToggleButton<YesNo> accelerateButton; // 加速开关按钮
private final EAPSettingToggleButton<YesNo> redstoneControlButton; // 加速开关按钮
/**
* 构造函数初始化界面和控件
* @param menu 实体加速器菜单
*
* @param menu 实体加速器菜单
* @param playerInventory 玩家背包
* @param title 界面标题
* @param style 界面样式
* @param title 界面标题
* @param style 界面样式
*/
public EntitySpeedTickerScreen(EntitySpeedTickerMenu menu, Inventory playerInventory, Component title, ScreenStyle style) {
super((C) menu, playerInventory, title, style);
public EntitySpeedTickerScreen(EntitySpeedTickerMenu menu,
Inventory playerInventory,
Component title,
ScreenStyle style) {
super(menu, playerInventory, title, style);
this.addToLeftToolbar(CommonButtons.togglePowerUnit()); // 添加功率单位切换按钮
this.eap$entitySpeedTickerEnabled = menu.getAccelerateEnabled();
// 初始化加速开关按钮
eap$entitySpeedTickerToggle = new SettingToggleButton<>(
Settings.BLOCKING_MODE,
this.eap$entitySpeedTickerEnabled ? YesNo.YES : YesNo.NO,
(btn, backwards) -> {
// 不做本地切换点击仅发送自定义C2S显示由@GuiSync回传
var conn = Minecraft.getInstance().getConnection();
if (conn != null) conn.send(ToggleEntityTickerC2SPacket.INSTANCE);
}
) {
@Override
public List<Component> getTooltipMessage() {
if (menu.targetBlacklisted) {
return List.of(
Component.literal("实体加速"),
Component.literal("已禁用(目标在黑名单)")
);
}
boolean enabled = eap$entitySpeedTickerEnabled;
return List.of(
Component.literal("实体加速"),
enabled ? Component.literal("已启用: 将加速目标方块实体的tick") :
Component.literal("已关闭: 不会对目标方块实体进行加速")
);
}
this.accelerateButton = new EAPServerSettingToggleButton<>(EAPSettings.ACCELERATE, YesNo.NO);
this.addToLeftToolbar(this.accelerateButton);
@Override
protected Icon getIcon() {
if (menu.targetBlacklisted) return Icon.INVALID;
return this.getCurrentValue() == YesNo.YES ? Icon.VALID : Icon.INVALID;
}
};
eap$entitySpeedTickerToggle.set(this.eap$entitySpeedTickerEnabled ? YesNo.YES : YesNo.NO);
this.addToLeftToolbar(eap$entitySpeedTickerToggle);
this.redstoneControlButton = new EAPServerSettingToggleButton<>(EAPSettings.REDSTONE_CONTROL, YesNo.NO);
this.addToLeftToolbar(this.redstoneControlButton);
}
@Override
protected void updateBeforeRender() {
super.updateBeforeRender();
if (eap$entitySpeedTickerToggle != null && menu != null) {
eap$entitySpeedTickerEnabled = menu.getAccelerateEnabled();
// 如果目标在黑名单禁用按钮并显示关闭状态
eap$entitySpeedTickerToggle.set(menu.targetBlacklisted ? YesNo.NO : (eap$entitySpeedTickerEnabled ? YesNo.YES : YesNo.NO));
eap$entitySpeedTickerToggle.active = !menu.targetBlacklisted;
// 如果目标在黑名单禁用按钮并显示关闭状态
if (this.menu.targetBlacklisted) {
this.accelerateButton.active = false;
this.accelerateButton.set(YesNo.UNDECIDED);
} else {
this.accelerateButton.set(this.menu.getAccelerate());
}
textData();
this.redstoneControlButton.set(this.menu.getRedstoneControl());
this.textData();
}
@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() {
textData();
this.textData();
}
/**
@ -92,7 +73,7 @@ public class EntitySpeedTickerScreen<C extends EntitySpeedTickerMenu> extends Up
*/
private void textData() {
Map<String, Component> textContents = new HashMap<>();
if (getMenu().targetBlacklisted) {
if (this.getMenu().targetBlacklisted) {
// 黑名单禁用时的默认显示
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));
@ -101,13 +82,13 @@ public class EntitySpeedTickerScreen<C extends EntitySpeedTickerMenu> extends Up
textContents.put("multiplier", Component.translatable("screen.extendedae_plus.entity_speed_ticker.multiplier", String.format("%.2fx", 0.0)));
} else {
// 正常状态下显示实际数据
int energyCardCount = getMenu().energyCardCount;
double multiplier = getMenu().multiplier;
int effectiveSpeed = getMenu().effectiveSpeed;
int energyCardCount = this.getMenu().energyCardCount;
double multiplier = this.getMenu().multiplier;
int effectiveSpeed = this.getMenu().effectiveSpeed;
double finalPower = PowerUtils.computeFinalPowerForProduct(effectiveSpeed, energyCardCount);
double remainingRatio = PowerUtils.getRemainingRatio(energyCardCount);
textContents.put("enable", getMenu().networkEnergySufficient ? null :
textContents.put("enable", this.getMenu().networkEnergySufficient == YesNo.YES ? null :
Component.translatable("screen.extendedae_plus.entity_speed_ticker.warning_network_energy_insufficient"));
textContents.put("speed", Component.translatable("screen.extendedae_plus.entity_speed_ticker.speed", effectiveSpeed));
textContents.put("energy", Component.translatable("screen.extendedae_plus.entity_speed_ticker.energy", Platform.formatPower(finalPower, false)));

View File

@ -0,0 +1,42 @@
package com.extendedae_plus.api.config;
import appeng.api.config.Setting;
import appeng.api.config.YesNo;
import com.google.common.base.Preconditions;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
public final class EAPSettings {
private static final Map<String, Setting<?>> SETTINGS = new HashMap<>();
public static final Setting<YesNo> ACCELERATE = register("accelerate", YesNo.NO, YesNo.YES);
public static final Setting<YesNo> REDSTONE_CONTROL = register("redstoneControl", YesNo.NO, YesNo.YES);
private EAPSettings() {
}
private synchronized static <T extends Enum<T>> Setting<T> register(String name, Class<T> enumClass) {
Preconditions.checkState(!SETTINGS.containsKey(name));
var setting = new Setting<>(name, enumClass);
SETTINGS.put(name, setting);
return setting;
}
@SafeVarargs
private synchronized static <T extends Enum<T>> Setting<T> register(String name, T firstOption, T... moreOptions) {
Preconditions.checkState(!SETTINGS.containsKey(name));
var setting = new Setting<T>(name, firstOption.getDeclaringClass(), EnumSet.of(firstOption, moreOptions));
SETTINGS.put(name, setting);
return setting;
}
public static Setting<?> getOrThrow(String name) {
var setting = SETTINGS.get(name);
if (setting == null) {
throw new IllegalArgumentException("Unknown setting '" + name + "'");
}
return setting;
}
}

View File

@ -4,7 +4,6 @@ import appeng.client.render.crafting.CraftingCubeModel;
import appeng.init.client.InitScreens;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.ae.definitions.upgrades.EntitySpeedCardItem;
import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu;
import com.extendedae_plus.ae.screen.EntitySpeedTickerScreen;
import com.extendedae_plus.client.render.crafting.EPlusCraftingCubeModelProvider;
import com.extendedae_plus.content.crafting.EPlusCraftingUnitType;
@ -77,6 +76,6 @@ public final class ClientProxy {
/**
* 注册由 AE2 InitScreens 所需的屏幕资源映射用于内置 JSON 屏幕注册
*/
InitScreens.register(event, ModMenuTypes.ENTITY_TICKER_MENU.get(), EntitySpeedTickerScreen<EntitySpeedTickerMenu>::new, "/screens/entity_speed_ticker.json");
InitScreens.register(event, ModMenuTypes.ENTITY_TICKER_MENU.get(), EntitySpeedTickerScreen::new, "/screens/entity_speed_ticker.json");
}
}

View File

@ -0,0 +1,18 @@
package com.extendedae_plus.client.gui.widgets;
import appeng.api.config.Setting;
import appeng.core.network.ServerboundPacket;
import com.extendedae_plus.network.packet.EAPConfigButtonPacket;
import net.neoforged.neoforge.network.PacketDistributor;
public class EAPServerSettingToggleButton<T extends Enum<T>> extends EAPSettingToggleButton<T> {
public EAPServerSettingToggleButton(Setting<T> setting, T val) {
super(setting, val, EAPServerSettingToggleButton::sendToServer);
}
private static <T extends Enum<T>> void sendToServer(EAPSettingToggleButton<T> button, boolean backwards) {
ServerboundPacket message = new EAPConfigButtonPacket(button.getSetting(), backwards);
PacketDistributor.sendToServer(message);
}
}

View File

@ -0,0 +1,197 @@
package com.extendedae_plus.client.gui.widgets;
import appeng.api.config.Setting;
import appeng.api.config.YesNo;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.Icon;
import appeng.client.gui.widgets.IconButton;
import appeng.core.localization.ButtonToolTips;
import appeng.core.localization.LocalizationEnum;
import appeng.util.EnumCycler;
import com.extendedae_plus.api.config.EAPSettings;
import com.extendedae_plus.common.definitions.EAPText;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Predicate;
public class EAPSettingToggleButton<T extends Enum<T>> extends IconButton {
private static Map<EnumPair<?>, ButtonAppearance> appearances;
private final Setting<T> buttonSetting;
private final IHandler<EAPSettingToggleButton<T>> onPress;
private final EnumSet<T> validValues;
private T currentValue;
public EAPSettingToggleButton(Setting<T> setting, T val,
IHandler<EAPSettingToggleButton<T>> onPress) {
this(setting, val, t -> true, onPress);
}
public EAPSettingToggleButton(Setting<T> setting, T val, Predicate<T> isValidValue,
IHandler<EAPSettingToggleButton<T>> onPress) {
super(EAPSettingToggleButton::onPress);
this.onPress = onPress;
EnumSet<T> validValues = EnumSet.allOf(val.getDeclaringClass());
validValues.removeIf(isValidValue.negate());
validValues.removeIf(s -> !setting.getValues().contains(s));
this.validValues = validValues;
this.buttonSetting = setting;
this.currentValue = val;
if (appearances == null) {
appearances = new HashMap<>();
registerApp(Icon.VALID, EAPSettings.ACCELERATE, YesNo.YES,
EAPText.Accelerate,
EAPText.AccelerateEnabled);
registerApp(Icon.INVALID, EAPSettings.ACCELERATE, YesNo.NO,
EAPText.Accelerate,
EAPText.AccelerateDisabled);
registerApp(Icon.INVALID, EAPSettings.ACCELERATE, YesNo.UNDECIDED,
EAPText.Accelerate,
EAPText.AccelerateBlacklisted);
registerApp(Icon.REDSTONE_LOW, EAPSettings.REDSTONE_CONTROL, YesNo.YES,
EAPText.RedstoneControl,
EAPText.RedstoneControlEnabled);
registerApp(Icon.REDSTONE_IGNORE, EAPSettings.REDSTONE_CONTROL, YesNo.NO,
EAPText.RedstoneControl,
EAPText.RedstoneControlDisabled);
}
}
private static void onPress(Button btn) {
if (btn instanceof EAPSettingToggleButton) {
((EAPSettingToggleButton<?>) btn).triggerPress();
}
}
private static <T extends Enum<T>> void registerApp(Icon icon, Setting<T> setting, T val,
LocalizationEnum title, Component... tooltipLines) {
var lines = new ArrayList<Component>();
lines.add(title.text());
Collections.addAll(lines, tooltipLines);
appearances.put(
new EnumPair<>(setting, val),
new ButtonAppearance(icon, null, lines));
}
private static <T extends Enum<T>> void registerApp(ItemLike item, Setting<T> setting, T val,
LocalizationEnum title, Component... tooltipLines) {
var lines = new ArrayList<Component>();
lines.add(title.text());
Collections.addAll(lines, tooltipLines);
appearances.put(
new EnumPair<>(setting, val),
new ButtonAppearance(null, item.asItem(), lines));
}
private static <T extends Enum<T>> void registerApp(Icon icon, Setting<T> setting, T val,
LocalizationEnum title, LocalizationEnum hint) {
registerApp(icon, setting, val, title, hint.text());
}
private void triggerPress() {
boolean backwards = false;
Screen currentScreen = Minecraft.getInstance().screen;
if (currentScreen instanceof AEBaseScreen) {
backwards = ((AEBaseScreen<?>) currentScreen).isHandlingRightClick();
}
onPress.handle(this, backwards);
}
@Nullable
private ButtonAppearance getApperance() {
if (this.buttonSetting != null && this.currentValue != null) {
return appearances.get(new EnumPair<>(this.buttonSetting, this.currentValue));
}
return null;
}
@Override
protected Icon getIcon() {
var app = getApperance();
if (app != null && app.icon != null) {
return app.icon;
}
return Icon.TOOLBAR_BUTTON_BACKGROUND;
}
@Override
protected Item getItemOverlay() {
var app = getApperance();
if (app != null && app.item != null) {
return app.item;
}
return null;
}
@Override
public List<Component> getTooltipMessage() {
if (this.buttonSetting == null || this.currentValue == null) {
return Collections.emptyList();
}
var buttonAppearance = appearances.get(new EnumPair<>(this.buttonSetting, this.currentValue));
if (buttonAppearance == null) {
return Collections.singletonList(ButtonToolTips.NoSuchMessage.text());
}
return buttonAppearance.tooltipLines;
}
public Setting<T> getSetting() {
return this.buttonSetting;
}
public T getCurrentValue() {
return this.currentValue;
}
public void set(T e) {
if (this.currentValue != e) {
this.currentValue = e;
}
}
public T getNextValue(boolean backwards) {
return EnumCycler.rotateEnum(currentValue, backwards, validValues);
}
@FunctionalInterface
public interface IHandler<T extends EAPSettingToggleButton<?>> {
void handle(T button, boolean backwards);
}
private record EnumPair<T extends Enum<T>>(Setting<T> setting, T value) {
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
final EnumPair<?> other = (EnumPair<?>) obj;
return other.setting == this.setting && other.value == this.value;
}
@Override
public int hashCode() {
return this.setting.hashCode() ^ this.value.hashCode();
}
}
private record ButtonAppearance(@Nullable Icon icon, @Nullable Item item, List<Component> tooltipLines) {
}
}

View File

@ -0,0 +1,41 @@
package com.extendedae_plus.common.definitions;
import appeng.core.localization.LocalizationEnum;
public enum EAPText implements LocalizationEnum {
Accelerate("Entity Acceleration", Type.TOOLTIP),
AccelerateEnabled("Accelerate target block entity ticks", Type.TOOLTIP),
AccelerateDisabled("Do not accelerate target block entities", Type.TOOLTIP),
AccelerateBlacklisted("Target is blacklisted", Type.TOOLTIP),
RedstoneControl("Redstone control", Type.TOOLTIP),
RedstoneControlEnabled("Control acceleration with redstone signal", Type.TOOLTIP),
RedstoneControlDisabled("Ignore redstone signals", Type.TOOLTIP);
private final String englishText;
private final Type type;
EAPText(String englishText, Type type) {
this.englishText = englishText;
this.type = type;
}
public String getEnglishText() {
return this.englishText;
}
public String getTranslationKey() {
return String.format("%s.%s.%s", this.type.root, "extendedae_plus", this.name());
}
private enum Type {
GUI("gui"),
TOOLTIP("gui.tooltips");
private final String root;
Type(String root) {
this.root = root;
}
}
}

View File

@ -1,8 +1,6 @@
package com.extendedae_plus.compat;
import appeng.client.gui.implementations.PatternProviderScreen;
import appeng.client.gui.widgets.UpgradesPanel;
import com.extendedae_plus.util.ExtendedAELogger;
/**
* AppliedFlux 兼容性处理工具类

View File

@ -2,13 +2,13 @@ package com.extendedae_plus.init;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.network.*;
import com.extendedae_plus.network.packet.EAPConfigButtonPacket;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
public class ModNetwork {
// Mod 构造中通过 modEventBus.addListener(ModNetwork::registerPayloadHandlers) 注册
public static void registerPayloadHandlers(final RegisterPayloadHandlersEvent event) {
var registrar = event.registrar(ExtendedAEPlus.MODID);
registrar.playToServer(ToggleEntityTickerC2SPacket.TYPE, ToggleEntityTickerC2SPacket.STREAM_CODEC, ToggleEntityTickerC2SPacket::handle);
registrar.playToServer(ToggleAdvancedBlockingC2SPacket.TYPE, ToggleAdvancedBlockingC2SPacket.STREAM_CODEC, ToggleAdvancedBlockingC2SPacket::handle);
registrar.playToServer(ToggleSmartDoublingC2SPacket.TYPE, ToggleSmartDoublingC2SPacket.STREAM_CODEC, ToggleSmartDoublingC2SPacket::handle);
registrar.playToServer(ScalePatternsC2SPacket.TYPE, ScalePatternsC2SPacket.STREAM_CODEC, ScalePatternsC2SPacket::handle);
@ -42,5 +42,7 @@ public class ModNetwork {
registrar.playToServer(com.extendedae_plus.network.SetWirelessFrequencyC2SPacket.TYPE,
com.extendedae_plus.network.SetWirelessFrequencyC2SPacket.STREAM_CODEC,
com.extendedae_plus.network.SetWirelessFrequencyC2SPacket::handle);
registrar.playToServer(EAPConfigButtonPacket.TYPE, EAPConfigButtonPacket.STREAM_CODEC, EAPConfigButtonPacket::handleOnServer);
}
}

View File

@ -11,12 +11,12 @@ import appeng.client.gui.style.WidgetStyle;
import appeng.client.gui.widgets.ToolboxPanel;
import appeng.client.gui.widgets.UpgradesPanel;
import appeng.core.localization.GuiText;
import appeng.menu.SlotSemantics;
import appeng.menu.implementations.PatternProviderMenu;
import appeng.helpers.patternprovider.PatternProviderLogicHost;
import appeng.menu.AEBaseMenu;
import com.extendedae_plus.compat.UpgradeSlotCompat;
import appeng.menu.SlotSemantics;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.compat.AppliedFluxCompat;
import com.extendedae_plus.compat.UpgradeSlotCompat;
import com.extendedae_plus.util.IStyleAccessor;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;

View File

@ -1,7 +1,7 @@
package com.extendedae_plus.mixin.ae2.compat;
import appeng.api.networking.IManagedGridNode;
import appeng.api.networking.IGridConnection;
import appeng.api.networking.IManagedGridNode;
import appeng.api.networking.security.IActionSource;
import appeng.api.upgrades.IUpgradeInventory;
import appeng.api.upgrades.IUpgradeableObject;
@ -9,13 +9,13 @@ import appeng.api.upgrades.UpgradeInventories;
import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.helpers.patternprovider.PatternProviderLogicHost;
import com.extendedae_plus.ae.items.ChannelCardItem;
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import com.extendedae_plus.bridge.CompatUpgradeProvider;
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import com.extendedae_plus.compat.UpgradeSlotCompat;
import com.extendedae_plus.init.ModItems;
import com.extendedae_plus.util.ExtendedAELogger;
import com.extendedae_plus.wireless.WirelessSlaveLink;
import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Final;

View File

@ -8,8 +8,6 @@ import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import com.extendedae_plus.init.ModItems;
import com.extendedae_plus.wireless.WirelessSlaveLink;
import com.extendedae_plus.wireless.endpoint.InterfaceNodeEndpointImpl;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

View File

@ -7,14 +7,10 @@ import appeng.helpers.InterfaceLogic;
import appeng.helpers.InterfaceLogicHost;
import com.extendedae_plus.bridge.CompatUpgradeProvider;
import com.extendedae_plus.compat.UpgradeSlotCompat;
import net.neoforged.fml.ModList;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.world.item.Item;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Unique;
import net.neoforged.fml.ModList;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

View File

@ -2,7 +2,6 @@ package com.extendedae_plus.mixin.ae2.helpers;
import appeng.api.networking.IManagedGridNode;
import appeng.api.upgrades.IUpgradeInventory;
import appeng.api.upgrades.IUpgradeableObject;
import appeng.api.upgrades.UpgradeInventories;
import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.helpers.patternprovider.PatternProviderLogicHost;
@ -19,8 +18,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
/**

View File

@ -1,10 +1,9 @@
package com.extendedae_plus.mixin.ae2.menu;
import appeng.api.upgrades.IUpgradeInventory;
import appeng.menu.AEBaseMenu;
import appeng.menu.SlotSemantics;
import appeng.menu.implementations.PatternProviderMenu;
import appeng.api.upgrades.IUpgradeInventory;
import com.extendedae_plus.util.ExtendedAELogger;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;

View File

@ -5,9 +5,6 @@ import appeng.menu.AEBaseMenu;
import appeng.menu.ToolboxMenu;
import appeng.menu.implementations.InterfaceMenu;
import com.extendedae_plus.bridge.IUpgradableMenu;
import com.extendedae_plus.compat.UpgradeSlotCompat;
import com.extendedae_plus.bridge.CompatUpgradeProvider;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType;
import org.spongepowered.asm.mixin.Mixin;

View File

@ -1,15 +1,11 @@
package com.extendedae_plus.mixin.ae2.menu;
import appeng.helpers.patternprovider.PatternProviderLogic;
import appeng.helpers.patternprovider.PatternProviderLogicHost;
import appeng.menu.AEBaseMenu;
import appeng.menu.guisync.GuiSync;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.api.AdvancedBlockingHolder;
import com.extendedae_plus.api.PatternProviderMenuAdvancedSync;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;

View File

@ -6,8 +6,6 @@ import appeng.menu.guisync.GuiSync;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.api.PatternProviderMenuDoublingSync;
import com.extendedae_plus.api.SmartDoublingHolder;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.world.entity.player.Inventory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;

View File

@ -5,11 +5,9 @@ import appeng.helpers.patternprovider.PatternProviderLogicHost;
import appeng.menu.AEBaseMenu;
import appeng.menu.ToolboxMenu;
import appeng.menu.implementations.PatternProviderMenu;
import com.extendedae_plus.bridge.CompatUpgradeProvider;
import com.extendedae_plus.bridge.IUpgradableMenu;
import com.extendedae_plus.compat.UpgradeSlotCompat;
import com.extendedae_plus.bridge.CompatUpgradeProvider;
import appeng.api.upgrades.IUpgradeInventory;
import appeng.api.upgrades.IUpgradeableObject;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType;
import org.spongepowered.asm.mixin.Final;
@ -19,7 +17,6 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.extendedae_plus.util.ExtendedAELogger;
@Mixin(value = PatternProviderMenu.class, priority = 2000, remap = false)
public abstract class PatternProviderMenuUpgradesMixin extends AEBaseMenu implements IUpgradableMenu {

View File

@ -3,16 +3,14 @@ package com.extendedae_plus.mixin.ae2.parts.automation;
import appeng.api.networking.security.IActionHost;
import appeng.api.upgrades.IUpgradeInventory;
import appeng.api.upgrades.IUpgradeableObject;
import appeng.helpers.InterfaceLogicHost;
import appeng.parts.automation.IOBusPart;
import net.minecraft.nbt.CompoundTag;
import com.extendedae_plus.util.ExtendedAELogger;
import com.extendedae_plus.ae.items.ChannelCardItem;
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import com.extendedae_plus.init.ModItems;
import com.extendedae_plus.util.ExtendedAELogger;
import com.extendedae_plus.wireless.WirelessSlaveLink;
import com.extendedae_plus.wireless.endpoint.GenericNodeEndpointImpl;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.nbt.CompoundTag;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;

View File

@ -5,14 +5,13 @@ import appeng.api.networking.security.IActionHost;
import appeng.api.upgrades.IUpgradeInventory;
import appeng.api.upgrades.IUpgradeableObject;
import appeng.parts.storagebus.StorageBusPart;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import com.extendedae_plus.util.ExtendedAELogger;
import com.extendedae_plus.ae.items.ChannelCardItem;
import com.extendedae_plus.bridge.InterfaceWirelessLinkBridge;
import com.extendedae_plus.init.ModItems;
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 org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;

View File

@ -7,14 +7,13 @@ import appeng.menu.SlotSemantics;
import appeng.menu.slot.AppEngSlot;
import com.extendedae_plus.NewIcon;
import com.extendedae_plus.api.ExPatternButtonsAccessor;
import com.extendedae_plus.api.ExPatternPageAccessor;
import com.extendedae_plus.config.ModConfigs;
import com.extendedae_plus.network.ScalePatternsC2SPacket;
import com.glodblock.github.extendedae.client.button.ActionEPPButton;
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
import com.glodblock.github.extendedae.container.ContainerExPatternProvider;
import net.minecraft.network.chat.Component;
import net.minecraft.client.Minecraft;
import com.extendedae_plus.network.ScalePatternsC2SPacket;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;

View File

@ -1,50 +0,0 @@
package com.extendedae_plus.network;
import com.extendedae_plus.ExtendedAEPlus;
import com.extendedae_plus.ae.menu.EntitySpeedTickerMenu;
import com.extendedae_plus.ae.parts.EntitySpeedTickerPart;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.network.handling.IPayloadContext;
/**
* C2S: Toggle the accelerateEnabled flag on the EntitySpeedTickerPart bound to the open menu.
*/
public class ToggleEntityTickerC2SPacket implements CustomPacketPayload {
public static final CustomPacketPayload.Type<ToggleEntityTickerC2SPacket> TYPE = new CustomPacketPayload.Type<>(
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "toggle_entity_ticker"));
public static final ToggleEntityTickerC2SPacket INSTANCE = new ToggleEntityTickerC2SPacket();
public static final StreamCodec<FriendlyByteBuf, ToggleEntityTickerC2SPacket> STREAM_CODEC =
StreamCodec.unit(INSTANCE);
private ToggleEntityTickerC2SPacket() {}
@Override
public CustomPacketPayload.Type<? extends CustomPacketPayload> type() {
return TYPE;
}
public static void handle(final ToggleEntityTickerC2SPacket msg, final IPayloadContext ctx) {
ctx.enqueueWork(() -> {
if (!(ctx.player() instanceof ServerPlayer player)) return;
if (!(player.containerMenu instanceof EntitySpeedTickerMenu menu)) return;
EntitySpeedTickerPart part = menu.getHost();
if (part == null) return;
// 切换部件上的状态并把新状态同步到菜单字段随后广播以通知客户端
boolean current = part.getAccelerateEnabled();
boolean next = !current;
part.setAccelerateEnabled(next);
// 确保菜单上的字段也被更新这样 @GuiSync 会把状态发回客户端
menu.setAccelerateEnabled(next);
menu.broadcastChanges();
});
}
}

View File

@ -0,0 +1,60 @@
package com.extendedae_plus.network.packet;
import appeng.api.config.Setting;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.core.network.CustomAppEngPayload;
import appeng.core.network.ServerboundPacket;
import appeng.menu.AEBaseMenu;
import appeng.util.EnumCycler;
import com.extendedae_plus.api.config.EAPSettings;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.server.level.ServerPlayer;
import org.jetbrains.annotations.NotNull;
public record EAPConfigButtonPacket(Setting<?> option, boolean rotationDirection) implements ServerboundPacket {
public static final StreamCodec<RegistryFriendlyByteBuf, EAPConfigButtonPacket> STREAM_CODEC = StreamCodec.ofMember(
EAPConfigButtonPacket::write,
EAPConfigButtonPacket::decode);
public static final Type<EAPConfigButtonPacket> TYPE = CustomAppEngPayload.createType("eap_config_button");
@Override
public @NotNull Type<EAPConfigButtonPacket> type() {
return TYPE;
}
public static EAPConfigButtonPacket decode(RegistryFriendlyByteBuf stream) {
var option = EAPSettings.getOrThrow(stream.readUtf());
var rotationDirection = stream.readBoolean();
return new EAPConfigButtonPacket(option, rotationDirection);
}
public void write(RegistryFriendlyByteBuf data) {
data.writeUtf(option.getName());
data.writeBoolean(rotationDirection);
}
@Override
public void handleOnServer(ServerPlayer player) {
if (player.containerMenu instanceof AEBaseMenu baseMenu) {
if (baseMenu.getTarget() instanceof IConfigurableObject configurableObject) {
var cm = configurableObject.getConfigManager();
if (cm.hasSetting(option)) {
cycleSetting(cm, option);
} else {
ExtendedAELogger.LOGGER.info("Ignoring unsupported setting {} sent by client on {}", option, baseMenu.getTarget());
}
}
}
}
private <T extends Enum<T>> void cycleSetting(IConfigManager cm, Setting<T> setting) {
var currentValue = cm.getSetting(setting);
var nextValue = EnumCycler.rotateEnum(currentValue, rotationDirection, setting.getValues());
cm.putSetting(setting, nextValue);
}
}

View File

@ -4,15 +4,13 @@ import appeng.api.crafting.IPatternDetails.IInput;
import appeng.api.stacks.AEKey;
import appeng.api.stacks.GenericStack;
import appeng.crafting.pattern.AEProcessingPattern;
import com.extendedae_plus.content.ScaledProcessingPattern;
import com.extendedae_plus.api.SmartDoublingAwarePattern;
import com.extendedae_plus.config.ModConfigs;
import com.extendedae_plus.content.ScaledProcessingPattern;
import java.util.ArrayList;
import java.util.List;
import static com.extendedae_plus.util.ExtendedAELogger.LOGGER;
public final class PatternScaler {
private PatternScaler() {
}

View File

@ -5,7 +5,6 @@ import appeng.api.networking.IGridConnection;
import appeng.api.networking.IGridNode;
import appeng.me.service.helpers.ConnectionWrapper;
import com.extendedae_plus.config.ModConfigs;
import com.extendedae_plus.util.ExtendedAELogger;
import net.minecraft.server.level.ServerLevel;
import org.jetbrains.annotations.Nullable;

View File

@ -129,5 +129,13 @@
"group.pattern_provider.name": "Pattern Provider",
"group.storage.name": "Storage Bus",
"group.entity_ticker.name": "Entity Ticker"
"group.entity_ticker.name": "Entity Ticker",
"gui.tooltips.extendedae_plus.Accelerate": "Entity Acceleration",
"gui.tooltips.extendedae_plus.AccelerateEnabled": "Target is blacklisted",
"gui.tooltips.extendedae_plus.AccelerateDisabled": "Accelerate target block entity ticks",
"gui.tooltips.extendedae_plus.AccelerateBlacklisted": "Do not accelerate target block entities",
"gui.tooltips.extendedae_plus.RedstoneControl": "Redstone Control",
"gui.tooltips.extendedae_plus.RedstoneControlEnabled": "Control acceleration with redstone signal",
"gui.tooltips.extendedae_plus.RedstoneControlDisabled": "Ignore redstone signals"
}

View File

@ -119,15 +119,24 @@
"extendedae_plus.tooltip.frequency": "频率: %d",
"extendedae_plus.tooltip.master_mode": "模式: %s",
"extendedae_plus.tooltip.locked": "状态: %s",
"gui.extendedae_plus.frequency_input.title": "设置频率",
"gui.extendedae_plus.frequency_input.field": "频率",
"gui.extendedae_plus.frequency_input.confirm": "确认",
"gui.extendedae_plus.frequency_input.cancel": "取消",
"extendedae_plus.wireless.locked": "已锁定收发器",
"extendedae_plus.wireless.unlocked": "已解锁收发器",
"group.pattern_provider.name": "样板供应器",
"group.storage.name": "存储总线",
"group.entity_ticker.name": "实体加速器"
"group.entity_ticker.name": "实体加速器",
"gui.tooltips.extendedae_plus.Accelerate": "实体加速",
"gui.tooltips.extendedae_plus.AccelerateEnabled": "加速目标方块实体的tick",
"gui.tooltips.extendedae_plus.AccelerateDisabled": "不加速目标方块实体",
"gui.tooltips.extendedae_plus.AccelerateBlacklisted": "目标在黑名单中",
"gui.tooltips.extendedae_plus.RedstoneControl": "红石控制",
"gui.tooltips.extendedae_plus.RedstoneControlEnabled": "使用红石信号控制加速",
"gui.tooltips.extendedae_plus.RedstoneControlDisabled": "忽略红石信号"
}