调整AEBaseScreenMixin中的部分内容及部分类的名字;扩展样板供应器界面代码调整
This commit is contained in:
parent
f068f00e7d
commit
de9cb29b6b
|
|
@ -3,7 +3,7 @@ package com.extendedae_plus.api;
|
|||
/**
|
||||
* 由 {@code GuiExPatternProviderMixin} 实现,用于从通用的 Screen Mixin 中更新按钮布局。
|
||||
*/
|
||||
public interface IExPatternButtonsAccessor {
|
||||
public interface IExPatternButton {
|
||||
/**
|
||||
* 在每帧调用以维护扩展样板供应器右侧按钮的可见性、重注册(窗口尺寸变化)与定位。
|
||||
*/
|
||||
|
|
@ -3,6 +3,8 @@ package com.extendedae_plus.api;
|
|||
/**
|
||||
* 由 GuiExPatternProviderMixin 实现,用于在客户端侧提供当前页号,避免反射读取 AE2 内部字段失败。
|
||||
*/
|
||||
public interface IExPatternPageAccessor {
|
||||
public interface IExPatternPage {
|
||||
int eap$getCurrentPage();
|
||||
|
||||
int eap$getMaxPageLocal();
|
||||
}
|
||||
|
|
@ -11,9 +11,8 @@ import appeng.client.gui.me.crafting.CraftingCPUScreen;
|
|||
import appeng.client.gui.style.PaletteColor;
|
||||
import appeng.client.gui.style.ScreenStyle;
|
||||
import appeng.client.gui.style.Text;
|
||||
import appeng.client.gui.style.TextAlignment;
|
||||
import appeng.menu.slot.AppEngSlot;
|
||||
import com.extendedae_plus.api.IExPatternPageAccessor;
|
||||
import com.extendedae_plus.api.IExPatternPage;
|
||||
import com.extendedae_plus.content.ClientPatternHighlightStore;
|
||||
import com.extendedae_plus.init.ModNetwork;
|
||||
import com.extendedae_plus.mixin.accessor.AbstractContainerScreenAccessor;
|
||||
|
|
@ -26,6 +25,7 @@ import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.Rect2i;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.contents.TranslatableContents;
|
||||
|
|
@ -40,63 +40,45 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
|
||||
@Mixin(AEBaseScreen.class)
|
||||
public abstract class AEBaseScreenMixin {
|
||||
|
||||
/**
|
||||
* 在 AEBaseScreen 的 mouseClicked 入口拦截 CraftingCPUScreen 的 Shift+左键,
|
||||
* 读取鼠标下的 AEKey 并发送 CraftingMonitorJumpC2SPacket。
|
||||
* 在 AEBaseScreen 的 mouseClicked 入口拦截 CraftingCPUScreen 的 Shift+点击操作。
|
||||
* 左键:发送 CraftingMonitorJumpC2SPacket(跳转至样板所在界面)。
|
||||
* 右键:发送 CraftingMonitorOpenProviderC2SPacket(打开样板供应器UI)。
|
||||
*/
|
||||
@Inject(method = "mouseClicked", at = @At("HEAD"), cancellable = true)
|
||||
private void eap$craftingCpuShiftLeftClick(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) {
|
||||
private void eap$craftingCpuShiftClick(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) {
|
||||
// 仅处理 CraftingCPUScreen 实例
|
||||
Object self = this;
|
||||
if (!(self instanceof CraftingCPUScreen<?> screen)) {
|
||||
return;
|
||||
}
|
||||
// 仅在 Shift + 左键 时触发
|
||||
if (button != 0 || !net.minecraft.client.gui.screens.Screen.hasShiftDown()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
StackWithBounds hovered = screen.getStackUnderMouse(mouseX, mouseY);
|
||||
if (hovered == null || hovered.stack() == null) {
|
||||
return;
|
||||
}
|
||||
AEKey key = hovered.stack().what();
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
ModNetwork.CHANNEL.sendToServer(new CraftingMonitorJumpC2SPacket(key));
|
||||
cir.setReturnValue(true);
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 AEBaseScreen 的 mouseClicked 入口拦截 CraftingCPUScreen 的 Shift+右键,
|
||||
* 读取鼠标下的 AEKey 并发送 CraftingMonitorOpenProviderC2SPacket(打开样板供应器UI)。
|
||||
*/
|
||||
@Inject(method = "mouseClicked", at = @At("HEAD"), cancellable = true)
|
||||
private void eap$craftingCpuShiftRightClick(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) {
|
||||
// 仅处理 CraftingCPUScreen 实例
|
||||
Object self = this;
|
||||
if (!(self instanceof CraftingCPUScreen<?> screen)) {
|
||||
return;
|
||||
}
|
||||
// 仅在 Shift + 右键 时触发
|
||||
if (button != 1 || !net.minecraft.client.gui.screens.Screen.hasShiftDown()) {
|
||||
// 仅在按下 Shift 且为左右键时触发
|
||||
if (!Screen.hasShiftDown() || (button != 0 && button != 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
StackWithBounds hovered = screen.getStackUnderMouse(mouseX, mouseY);
|
||||
if (hovered == null || hovered.stack() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AEKey key = hovered.stack().what();
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
ModNetwork.CHANNEL.sendToServer(new CraftingMonitorOpenProviderC2SPacket(key));
|
||||
|
||||
// 左键发送跳转包,右键发送打开供应器包
|
||||
if (button == 0) {
|
||||
ModNetwork.CHANNEL.sendToServer(new CraftingMonitorJumpC2SPacket(key));
|
||||
} else {
|
||||
ModNetwork.CHANNEL.sendToServer(new CraftingMonitorOpenProviderC2SPacket(key));
|
||||
}
|
||||
|
||||
cir.setReturnValue(true);
|
||||
} catch (Throwable ignored) {}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -138,11 +120,14 @@ public abstract class AEBaseScreenMixin {
|
|||
if (key != null && ClientPatternHighlightStore.hasHighlight(key)) {
|
||||
try {
|
||||
GuiUtil.drawSlotRainbowHighlight(guiGraphics, s.x, s.y);
|
||||
} catch (Throwable ignored) {}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignore) {}
|
||||
} catch (Throwable ignore) {}
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
// 在 AEBaseScreen.drawText 完成某个文本绘制后,若该文本为“样板”标签,则紧接着绘制页码。
|
||||
|
|
@ -152,121 +137,64 @@ public abstract class AEBaseScreenMixin {
|
|||
@Nullable TextOverride override,
|
||||
CallbackInfo ci) {
|
||||
Object self = this;
|
||||
if (!(self instanceof GuiExPatternProvider)) {
|
||||
if (!(self instanceof GuiExPatternProvider)) return;
|
||||
|
||||
// 判断是否是“样板”标题
|
||||
Component content = text.getText();
|
||||
if (!"gui.ae2.Patterns".equals(content.getContents() instanceof TranslatableContents tc ? tc.getKey() : null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 解析最终用于显示的标签内容
|
||||
Component content = text.getText();
|
||||
if (override != null && override.getContent() != null) {
|
||||
content = override.getContent().copy().withStyle(content.getStyle());
|
||||
}
|
||||
|
||||
// 计算“样板”文本起点与宽度,按对齐方式与缩放修正 x/y
|
||||
int imageWidth = ((AbstractContainerScreenAccessor<?>) this).eap$getImageWidth();
|
||||
int imageHeight = ((AbstractContainerScreenAccessor<?>) this).eap$getImageHeight();
|
||||
|
||||
Rect2i bounds = new Rect2i(0, 0, imageWidth, imageHeight);
|
||||
Point pos = text.getPosition().resolve(bounds);
|
||||
|
||||
float scale = text.getScale();
|
||||
|
||||
Font font = ((ScreenAccessor) this).eap$getFont();
|
||||
// 只关心第一行(标题类文本无换行或 maxWidth<=0)
|
||||
var contentLine = (text.getMaxWidth() <= 0)
|
||||
? content.getVisualOrderText()
|
||||
: font.split(content, text.getMaxWidth()).get(0);
|
||||
int lineWidth = font.width(contentLine);
|
||||
|
||||
int x = pos.getX();
|
||||
int y = pos.getY();
|
||||
// 对齐修正
|
||||
var align = text.getAlign();
|
||||
if (align == TextAlignment.CENTER) {
|
||||
int textPx = Math.round(lineWidth * scale);
|
||||
x -= textPx / 2;
|
||||
} else if (align == TextAlignment.RIGHT) {
|
||||
int textPx = Math.round(lineWidth * scale);
|
||||
x -= textPx;
|
||||
}
|
||||
|
||||
// 判断是否为“样板”组标题(多语言兼容且避免标题)
|
||||
boolean isPatterns = false;
|
||||
// 1) 基于翻译键
|
||||
var contents = content.getContents();
|
||||
if (contents instanceof TranslatableContents tc) {
|
||||
String key = tc.getKey();
|
||||
if (key != null && key.endsWith(".patterns")) {
|
||||
isPatterns = true;
|
||||
}
|
||||
}
|
||||
// 2) 基于已知本地化键的字符串解析
|
||||
if (!isPatterns) {
|
||||
String label = content.getString();
|
||||
if (label != null) {
|
||||
if (label.equals(Component.translatable("gui.pattern_provider.patterns").getString()))
|
||||
isPatterns = true;
|
||||
else if (label.equals(Component.translatable("gui.extendedae.patterns").getString()))
|
||||
isPatterns = true;
|
||||
else if (label.equals(Component.translatable("gui.ae2.patterns").getString())) isPatterns = true;
|
||||
}
|
||||
}
|
||||
// 3) 容错:中文“样板”且在标题下方(放宽到 y>=14)或文本正好等于“样板”
|
||||
if (!isPatterns) {
|
||||
String s = content.getString();
|
||||
if (s != null && ("样板".equals(s) || (s.contains("样板") && y >= 14))) {
|
||||
isPatterns = true;
|
||||
}
|
||||
}
|
||||
if (!isPatterns) return;
|
||||
|
||||
// ---- 获取页码 ----
|
||||
int cur = 1;
|
||||
int max = 1;
|
||||
if (self instanceof IExPatternPageAccessor accessor) {
|
||||
if (self instanceof IExPatternPage accessor) {
|
||||
cur = Math.max(0, accessor.eap$getCurrentPage()) + 1;
|
||||
}
|
||||
try {
|
||||
var fMax = self.getClass().getDeclaredField("eap$maxPageLocal");
|
||||
fMax.setAccessible(true);
|
||||
Object v = fMax.get(self);
|
||||
if (v instanceof Integer i) {
|
||||
max = Math.max(1, i);
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
max = Math.max(max, accessor.eap$getMaxPageLocal());
|
||||
}
|
||||
|
||||
String pageText = "第" + cur + "页" + "/" + max + "页";
|
||||
// ---- 构造翻译文本 ----
|
||||
Component pageText = Component.translatable("gui.extendedae.pattern_page", cur, max);
|
||||
|
||||
ScreenStyle style = ((AEBaseScreenAccessor<?>) this).eap$getStyle();
|
||||
// ---- 计算绘制坐标 ----
|
||||
AbstractContainerScreenAccessor<?> screen = (AbstractContainerScreenAccessor<?>) this;
|
||||
int imageWidth = screen.eap$getImageWidth();
|
||||
int imageHeight = screen.eap$getImageHeight();
|
||||
Point pos = text.getPosition().resolve(
|
||||
new Rect2i(0, 0, imageWidth, imageHeight)
|
||||
);
|
||||
|
||||
Font font = ((ScreenAccessor) this).eap$getFont();
|
||||
float scale = text.getScale();
|
||||
int lineWidth = font.width(content.getVisualOrderText());
|
||||
|
||||
int x = pos.getX() + lineWidth + 4; // 右侧偏移4像素
|
||||
int y = pos.getY();
|
||||
|
||||
// ---- 绘制 ----
|
||||
int color = 0xFFFFFFFF;
|
||||
ScreenStyle style = ((AEBaseScreenAccessor<?>) this).eap$getStyle();
|
||||
if (style != null) {
|
||||
try {
|
||||
color = style.getColor(PaletteColor.DEFAULT_TEXT_COLOR).toARGB();
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
int padding = 4;
|
||||
if (scale == 1.0f) {
|
||||
guiGraphics.drawString(font, pageText, x + lineWidth + padding, y, color, false);
|
||||
} else {
|
||||
guiGraphics.pose().pushPose();
|
||||
guiGraphics.pose().translate(x, y, 1);
|
||||
guiGraphics.pose().scale(scale, scale, 1);
|
||||
guiGraphics.drawString(font, pageText, lineWidth + padding, 0, color, false);
|
||||
guiGraphics.pose().popPose();
|
||||
color = style.getColor(PaletteColor.DEFAULT_TEXT_COLOR).toARGB();
|
||||
}
|
||||
|
||||
guiGraphics.pose().pushPose();
|
||||
guiGraphics.pose().translate(x, y, 1);
|
||||
if (scale != 1.0f) guiGraphics.pose().scale(scale, scale, 1);
|
||||
guiGraphics.drawString(font, pageText, 0, 0, color, false);
|
||||
guiGraphics.pose().popPose();
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
@Shadow(remap = false)
|
||||
protected void setTextContent(String id, Component content) {};
|
||||
protected void setTextContent(String id, Component content) {}
|
||||
|
||||
@Inject(method = "updateBeforeRender", at = @At("RETURN"), remap = false)
|
||||
private void onUpdateBeforeRender(CallbackInfo ci) {
|
||||
try {
|
||||
AEBaseScreen<?> self = (AEBaseScreen<?>) (Object) this;
|
||||
if (self instanceof PatternProviderScreen screen){
|
||||
if (self instanceof PatternProviderScreen screen) {
|
||||
Component t = screen.getTitle();
|
||||
if (t != null && !t.getString().isEmpty()) {
|
||||
this.setTextContent(AEBaseScreen.TEXT_ID_DIALOG_TITLE, t);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import appeng.client.gui.implementations.PatternProviderScreen;
|
|||
import appeng.client.gui.style.ScreenStyle;
|
||||
import appeng.client.gui.widgets.SettingToggleButton;
|
||||
import appeng.menu.implementations.PatternProviderMenu;
|
||||
import com.extendedae_plus.api.IExPatternButtonsAccessor;
|
||||
import com.extendedae_plus.api.IExPatternButton;
|
||||
import com.extendedae_plus.api.IPatternProviderMenuAdvancedSync;
|
||||
import com.extendedae_plus.api.smartDoubling.IPatternProviderMenuDoublingSync;
|
||||
import com.extendedae_plus.init.ModNetwork;
|
||||
|
|
@ -204,7 +204,7 @@ public abstract class PatternProviderScreenMixin<C extends PatternProviderMenu>
|
|||
private void eap$updateExGuiLayout() {
|
||||
if ((Object) this instanceof GuiExPatternProvider) {
|
||||
try {
|
||||
((IExPatternButtonsAccessor) this).eap$updateButtonsLayout();
|
||||
((IExPatternButton) this).eap$updateButtonsLayout();
|
||||
} catch (Throwable t) {
|
||||
EAP$LOGGER.debug("[EAP] updateButtonsLayout skipped: {}", t.toString());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,52 +2,31 @@ package com.extendedae_plus.mixin.ae2.client.gui;
|
|||
|
||||
import appeng.client.Point;
|
||||
import appeng.client.gui.layout.SlotGridLayout;
|
||||
import com.extendedae_plus.api.IExPatternPageAccessor;
|
||||
import com.extendedae_plus.api.IExPatternPage;
|
||||
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@Mixin(SlotGridLayout.class)
|
||||
public abstract class SlotGridLayoutMixin {
|
||||
|
||||
@Unique
|
||||
private static final int SLOTS_PER_PAGE = 36;
|
||||
|
||||
@Inject(method = "getRowBreakPosition", at = @At("HEAD"), cancellable = true, remap = false)
|
||||
private static void onGetRowBreakPosition(int x, int y, int semanticIdx, int cols, CallbackInfoReturnable<Point> cir) {
|
||||
// 仅在 9 列布局 且 当前屏幕为 扩展样板供应器 时处理
|
||||
if (cols != 9) {
|
||||
return;
|
||||
}
|
||||
// 仅在 9 列布局 且 当前屏幕为 扩展样板供应器时处理
|
||||
if (cols != 9) return;
|
||||
|
||||
var screen = Minecraft.getInstance().screen;
|
||||
if (!(screen instanceof com.glodblock.github.extendedae.client.gui.GuiExPatternProvider)) {
|
||||
return;
|
||||
}
|
||||
if (!(screen instanceof GuiExPatternProvider gui)) return;
|
||||
|
||||
// 读取实际当前页码:优先从 GUI accessor,其次反射容器,失败则为 0
|
||||
int currentPage = 0;
|
||||
try {
|
||||
if (screen instanceof IExPatternPageAccessor accessor) {
|
||||
currentPage = accessor.eap$getCurrentPage();
|
||||
} else {
|
||||
var menu = ((com.glodblock.github.extendedae.client.gui.GuiExPatternProvider) screen).getMenu();
|
||||
Field fieldPage = eap$findFieldRecursive(menu.getClass(), "page");
|
||||
if (fieldPage != null) {
|
||||
fieldPage.setAccessible(true);
|
||||
currentPage = (Integer) fieldPage.get(menu);
|
||||
}
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
// 当前页
|
||||
int currentPage = (gui instanceof IExPatternPage accessor) ?
|
||||
accessor.eap$getCurrentPage() :
|
||||
0;
|
||||
|
||||
// 该槽位属于第几页
|
||||
int slotPage = semanticIdx / SLOTS_PER_PAGE;
|
||||
int slotPage = semanticIdx / 36;
|
||||
if (slotPage != currentPage) {
|
||||
// 非当前页:将其移出视野,避免渲染与鼠标命中
|
||||
cir.setReturnValue(new Point(-10000, -10000));
|
||||
|
|
@ -56,7 +35,7 @@ public abstract class SlotGridLayoutMixin {
|
|||
}
|
||||
|
||||
// 当前页中的位置(0..35)
|
||||
int slotInPage = semanticIdx % SLOTS_PER_PAGE;
|
||||
int slotInPage = semanticIdx % 36;
|
||||
int row = slotInPage / 9; // 0-3
|
||||
int col = slotInPage % 9; // 0-8
|
||||
|
||||
|
|
@ -67,17 +46,5 @@ public abstract class SlotGridLayoutMixin {
|
|||
cir.setReturnValue(new Point(targetX, targetY));
|
||||
cir.cancel();
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5,8 +5,8 @@ import appeng.client.gui.implementations.PatternProviderScreen;
|
|||
import appeng.client.gui.style.ScreenStyle;
|
||||
import appeng.menu.SlotSemantics;
|
||||
import com.extendedae_plus.ae.client.gui.NewIcon;
|
||||
import com.extendedae_plus.api.IExPatternButtonsAccessor;
|
||||
import com.extendedae_plus.api.IExPatternPageAccessor;
|
||||
import com.extendedae_plus.api.IExPatternButton;
|
||||
import com.extendedae_plus.api.IExPatternPage;
|
||||
import com.extendedae_plus.config.ModConfig;
|
||||
import com.glodblock.github.extendedae.client.button.ActionEPPButton;
|
||||
import com.glodblock.github.extendedae.client.gui.GuiExPatternProvider;
|
||||
|
|
@ -24,10 +24,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static com.extendedae_plus.util.Logger.EAP$LOGGER;
|
||||
|
||||
@Mixin(GuiExPatternProvider.class)
|
||||
public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<ContainerExPatternProvider> implements IExPatternButtonsAccessor, IExPatternPageAccessor {
|
||||
public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<ContainerExPatternProvider> implements IExPatternButton, IExPatternPage {
|
||||
|
||||
@Unique
|
||||
ScreenStyle eap$screenStyle;
|
||||
|
|
@ -239,6 +237,11 @@ public abstract class GuiExPatternProviderMixin extends PatternProviderScreen<Co
|
|||
return getCurrentPage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int eap$getMaxPageLocal() {
|
||||
return this.eap$maxPageLocal;
|
||||
}
|
||||
|
||||
// 页码文本绘制移交给 AEBaseScreenMixin.renderLabels 尾部执行
|
||||
|
||||
// 注意:不再注入 Screen#init,避免混入在某些映射情况下失败导致 TransformerError
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ import static guideme.compiler.tags.MdxAttrs.getRequiredItemAndId;
|
|||
public abstract class ItemLinkCompilerMixin {
|
||||
@Inject(method = "compile", at = @At("HEAD"), cancellable = true)
|
||||
private void onCompile(PageCompiler compiler, LytFlowParent parent, MdxJsxElementFields el, CallbackInfo ci) {
|
||||
System.out.println("加载guideme.compiler.tags.ItemLinkCompilerMixin.onCompile");
|
||||
var itemAndId = this.getRequiredItemStackAndId(compiler, parent, el);
|
||||
if (itemAndId == null) {
|
||||
ci.cancel();
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"gui.extendedae_plus.global.toggle_smart_doubling": "Toggle Smart Doubling",
|
||||
"gui.extendedae_plus.global.all_on": "All On",
|
||||
"gui.extendedae_plus.global.all_off": "All Off",
|
||||
"gui.extendedae.pattern_page": "Page %s/%s",
|
||||
|
||||
"itemGroup.extendedae_plus.main": "ExtendedAE Plus",
|
||||
"item.extendedae_plus.wireless_transceiver": "Wireless Transceiver",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"gui.extendedae_plus.global.toggle_smart_doubling": "切换智能翻倍",
|
||||
"gui.extendedae_plus.global.all_on": "全部开启",
|
||||
"gui.extendedae_plus.global.all_off": "全部关闭",
|
||||
"gui.extendedae.pattern_page": "第%s页/%s页",
|
||||
|
||||
"itemGroup.extendedae_plus.main": "扩展AE Plus",
|
||||
"item.extendedae_plus.wireless_transceiver": "无线收发器",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user