样板终端恢复&主副切换按钮
This commit is contained in:
parent
28f9ff09d9
commit
d1e323a6a4
|
|
@ -9,6 +9,7 @@ import net.minecraft.network.chat.Component;
|
|||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class ScaledTextureButton extends Button {
|
||||
private final OnPress delegateOnPress;
|
||||
private final ResourceLocation texture;
|
||||
private final int textureWidth;
|
||||
private final int textureHeight;
|
||||
|
|
@ -22,7 +23,9 @@ public class ScaledTextureButton extends Button {
|
|||
int srcX, int srcY, int srcWidth, int srcHeight, float scale,
|
||||
Component tooltipText, OnPress onPress) {
|
||||
super(0, 0, Math.round(srcWidth * scale), Math.round(srcHeight * scale),
|
||||
Component.empty(), onPress, DEFAULT_NARRATION);
|
||||
Component.empty(), btn -> {
|
||||
}, DEFAULT_NARRATION);
|
||||
this.delegateOnPress = onPress;
|
||||
this.texture = texture;
|
||||
this.textureWidth = textureWidth;
|
||||
this.textureHeight = textureHeight;
|
||||
|
|
@ -41,6 +44,12 @@ public class ScaledTextureButton extends Button {
|
|||
this.active = visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPress() {
|
||||
this.delegateOnPress.onPress(this);
|
||||
this.setFocused(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
|
||||
if (!this.visible) {
|
||||
|
|
@ -51,19 +60,11 @@ public class ScaledTextureButton extends Button {
|
|||
this.height = Math.round(this.srcHeight * this.scale);
|
||||
|
||||
int yOffset = this.isHovered() ? 1 : 0;
|
||||
Icon bgIcon = isHovered() ? Icon.TOOLBAR_BUTTON_BACKGROUND_HOVER
|
||||
: isFocused() ? Icon.TOOLBAR_BUTTON_BACKGROUND_FOCUS : Icon.TOOLBAR_BUTTON_BACKGROUND;
|
||||
Icon bgIcon = isHovered() ? Icon.TOOLBAR_BUTTON_BACKGROUND_HOVER : Icon.TOOLBAR_BUTTON_BACKGROUND;
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.enableBlend();
|
||||
|
||||
if (isFocused()) {
|
||||
guiGraphics.fill(getX() - 1, getY() - 1, getX() + width + 1, getY(), 0xFFFFFFFF);
|
||||
guiGraphics.fill(getX() - 1, getY(), getX(), getY() + height, 0xFFFFFFFF);
|
||||
guiGraphics.fill(getX() + width, getY(), getX() + width + 1, getY() + height, 0xFFFFFFFF);
|
||||
guiGraphics.fill(getX() - 1, getY() + height, getX() + width + 1, getY() + height + 1, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
var pose = guiGraphics.pose();
|
||||
pose.pushPose();
|
||||
pose.translate(getX(), getY() + yOffset, 0.0F);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@ public abstract class PatternEncodingTermScaleButtonsMixin<T extends AEBaseMenu>
|
|||
@Unique
|
||||
private static final ResourceLocation EAP$SCALE_BUTTON_TEXTURE =
|
||||
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "textures/gui/beizeng.png");
|
||||
@Unique
|
||||
private static final ResourceLocation EAP$SWAP_OUTPUT_TEXTURE =
|
||||
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "textures/gui/zhu_fu_qie_huan.png");
|
||||
@Unique
|
||||
private static final ResourceLocation EAP$RESTORE_RATIO_TEXTURE =
|
||||
ResourceLocation.fromNamespaceAndPath(ExtendedAEPlus.MODID, "textures/gui/huanyuan.png");
|
||||
|
||||
@Unique
|
||||
private ScaledTextureButton eap$mul2Button;
|
||||
|
|
@ -40,6 +46,10 @@ public abstract class PatternEncodingTermScaleButtonsMixin<T extends AEBaseMenu>
|
|||
private ScaledTextureButton eap$div3Button;
|
||||
@Unique
|
||||
private ScaledTextureButton eap$div5Button;
|
||||
@Unique
|
||||
private ScaledTextureButton eap$swapOutputsButton;
|
||||
@Unique
|
||||
private ScaledTextureButton eap$restoreRatioButton;
|
||||
|
||||
@Inject(method = "init", at = @At("TAIL"), remap = false)
|
||||
private void eap$initScaleButtons(CallbackInfo ci) {
|
||||
|
|
@ -60,6 +70,16 @@ public abstract class PatternEncodingTermScaleButtonsMixin<T extends AEBaseMenu>
|
|||
ScaleEncodingPatternC2SPacket.Operation.DIV3);
|
||||
this.eap$div5Button = eap$createScaleButton(32, 16, "/5",
|
||||
ScaleEncodingPatternC2SPacket.Operation.DIV5);
|
||||
this.eap$swapOutputsButton = eap$createStandaloneButton(
|
||||
EAP$SWAP_OUTPUT_TEXTURE,
|
||||
"主副切换",
|
||||
ScaleEncodingPatternC2SPacket.Operation.SWAP_OUTPUTS
|
||||
);
|
||||
this.eap$restoreRatioButton = eap$createStandaloneButton(
|
||||
EAP$RESTORE_RATIO_TEXTURE,
|
||||
"恢复比例",
|
||||
ScaleEncodingPatternC2SPacket.Operation.RESTORE_RATIO
|
||||
);
|
||||
}
|
||||
|
||||
eap$ensureAdded(this.eap$mul2Button);
|
||||
|
|
@ -68,6 +88,8 @@ public abstract class PatternEncodingTermScaleButtonsMixin<T extends AEBaseMenu>
|
|||
eap$ensureAdded(this.eap$div2Button);
|
||||
eap$ensureAdded(this.eap$div3Button);
|
||||
eap$ensureAdded(this.eap$div5Button);
|
||||
eap$ensureAdded(this.eap$swapOutputsButton);
|
||||
eap$ensureAdded(this.eap$restoreRatioButton);
|
||||
}
|
||||
|
||||
@Inject(method = "containerTick", at = @At("TAIL"), remap = false)
|
||||
|
|
@ -85,6 +107,8 @@ public abstract class PatternEncodingTermScaleButtonsMixin<T extends AEBaseMenu>
|
|||
eap$ensureAdded(this.eap$div2Button);
|
||||
eap$ensureAdded(this.eap$div3Button);
|
||||
eap$ensureAdded(this.eap$div5Button);
|
||||
eap$ensureAdded(this.eap$swapOutputsButton);
|
||||
eap$ensureAdded(this.eap$restoreRatioButton);
|
||||
|
||||
boolean visible = screen.getMenu().getMode() == EncodingMode.PROCESSING;
|
||||
this.eap$mul2Button.setVisibility(visible);
|
||||
|
|
@ -93,6 +117,8 @@ public abstract class PatternEncodingTermScaleButtonsMixin<T extends AEBaseMenu>
|
|||
this.eap$div2Button.setVisibility(visible);
|
||||
this.eap$div3Button.setVisibility(visible);
|
||||
this.eap$div5Button.setVisibility(visible);
|
||||
this.eap$swapOutputsButton.setVisibility(visible);
|
||||
this.eap$restoreRatioButton.setVisibility(visible);
|
||||
|
||||
if (!visible) {
|
||||
return;
|
||||
|
|
@ -108,6 +134,8 @@ public abstract class PatternEncodingTermScaleButtonsMixin<T extends AEBaseMenu>
|
|||
eap$placeButton(this.eap$mul2Button, "cheng_2", bounds);
|
||||
eap$placeButton(this.eap$mul3Button, "cheng_3", bounds);
|
||||
eap$placeButton(this.eap$mul5Button, "cheng_5", bounds);
|
||||
eap$placeButton(this.eap$swapOutputsButton, "zhu_fu_qie_huan", bounds);
|
||||
eap$placeButton(this.eap$restoreRatioButton, "huan_yuan_mo_ren", bounds);
|
||||
}
|
||||
|
||||
@Unique
|
||||
|
|
@ -127,6 +155,23 @@ public abstract class PatternEncodingTermScaleButtonsMixin<T extends AEBaseMenu>
|
|||
);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private ScaledTextureButton eap$createStandaloneButton(ResourceLocation texture, String tooltipText,
|
||||
ScaleEncodingPatternC2SPacket.Operation op) {
|
||||
return new ScaledTextureButton(
|
||||
texture,
|
||||
16,
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16,
|
||||
0.375f,
|
||||
Component.literal(tooltipText),
|
||||
btn -> PacketDistributor.sendToServer(new ScaleEncodingPatternC2SPacket(op))
|
||||
);
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void eap$ensureAdded(ScaledTextureButton button) {
|
||||
var accessor = (ScreenAccessor) (Object) this;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.extendedae_plus.network;
|
|||
|
||||
import appeng.api.stacks.GenericStack;
|
||||
import appeng.menu.me.items.PatternEncodingTermMenu;
|
||||
import appeng.menu.slot.FakeSlot;
|
||||
import appeng.parts.encoding.EncodingMode;
|
||||
import appeng.util.ConfigInventory;
|
||||
import com.extendedae_plus.ExtendedAEPlus;
|
||||
|
|
@ -15,7 +16,7 @@ import net.neoforged.neoforge.network.handling.IPayloadContext;
|
|||
|
||||
public class ScaleEncodingPatternC2SPacket implements CustomPacketPayload {
|
||||
public enum Operation {
|
||||
MUL2, DIV2, MUL3, DIV3, MUL5, DIV5
|
||||
MUL2, DIV2, MUL3, DIV3, MUL5, DIV5, SWAP_OUTPUTS, RESTORE_RATIO
|
||||
}
|
||||
|
||||
public static final Type<ScaleEncodingPatternC2SPacket> TYPE = new Type<>(
|
||||
|
|
@ -49,10 +50,32 @@ public class ScaleEncodingPatternC2SPacket implements CustomPacketPayload {
|
|||
return;
|
||||
}
|
||||
|
||||
if (msg.op == Operation.SWAP_OUTPUTS) {
|
||||
rotateProcessingOutputs(menu);
|
||||
menu.broadcastChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.op == Operation.RESTORE_RATIO) {
|
||||
var accessor = (PatternEncodingTermMenuAccessor) (Object) menu;
|
||||
long gcd = computeSharedGcd(accessor.eap$getEncodedInputsInv(), accessor.eap$getEncodedOutputsInv());
|
||||
if (gcd <= 1L) {
|
||||
return;
|
||||
}
|
||||
|
||||
var reducedOutputs = reduceInventory(accessor.eap$getEncodedOutputsInv(), gcd);
|
||||
var reducedInputs = reduceInventory(accessor.eap$getEncodedInputsInv(), gcd);
|
||||
applyScaled(accessor.eap$getEncodedOutputsInv(), reducedOutputs);
|
||||
applyScaled(accessor.eap$getEncodedInputsInv(), reducedInputs);
|
||||
menu.broadcastChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
int scale = switch (msg.op) {
|
||||
case MUL2, DIV2 -> 2;
|
||||
case MUL3, DIV3 -> 3;
|
||||
case MUL5, DIV5 -> 5;
|
||||
default -> 1;
|
||||
};
|
||||
boolean divide = switch (msg.op) {
|
||||
case DIV2, DIV3, DIV5 -> true;
|
||||
|
|
@ -110,4 +133,85 @@ public class ScaleEncodingPatternC2SPacket implements CustomPacketPayload {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static GenericStack[] reduceInventory(ConfigInventory inventory, long gcd) {
|
||||
var result = new GenericStack[inventory.size()];
|
||||
for (int slot = 0; slot < inventory.size(); slot++) {
|
||||
GenericStack stack = inventory.getStack(slot);
|
||||
if (stack == null) {
|
||||
continue;
|
||||
}
|
||||
result[slot] = new GenericStack(stack.what(), stack.amount() / gcd);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static long computeSharedGcd(ConfigInventory inputs, ConfigInventory outputs) {
|
||||
long gcd = 0L;
|
||||
gcd = updateGcd(gcd, inputs);
|
||||
gcd = updateGcd(gcd, outputs);
|
||||
return gcd;
|
||||
}
|
||||
|
||||
private static long updateGcd(long currentGcd, ConfigInventory inventory) {
|
||||
long gcd = currentGcd;
|
||||
for (int slot = 0; slot < inventory.size(); slot++) {
|
||||
GenericStack stack = inventory.getStack(slot);
|
||||
if (stack == null || stack.amount() <= 0L) {
|
||||
continue;
|
||||
}
|
||||
gcd = gcd == 0L ? stack.amount() : gcd(gcd, stack.amount());
|
||||
if (gcd == 1L) {
|
||||
return 1L;
|
||||
}
|
||||
}
|
||||
return gcd;
|
||||
}
|
||||
|
||||
private static long gcd(long a, long b) {
|
||||
long left = Math.abs(a);
|
||||
long right = Math.abs(b);
|
||||
while (right != 0L) {
|
||||
long temp = left % right;
|
||||
left = right;
|
||||
right = temp;
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
private static void rotateProcessingOutputs(PatternEncodingTermMenu menu) {
|
||||
FakeSlot[] outputSlots = menu.getProcessingOutputSlots();
|
||||
int nonEmptyCount = 0;
|
||||
for (FakeSlot slot : outputSlots) {
|
||||
if (!slot.getItem().isEmpty()) {
|
||||
nonEmptyCount++;
|
||||
}
|
||||
}
|
||||
if (nonEmptyCount < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newOutputs = new net.minecraft.world.item.ItemStack[outputSlots.length];
|
||||
for (int i = 0; i < outputSlots.length; i++) {
|
||||
newOutputs[i] = outputSlots[i].getItem().copy();
|
||||
}
|
||||
|
||||
for (int i = 0; i < outputSlots.length; i++) {
|
||||
if (outputSlots[i].getItem().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 1; j < outputSlots.length; j++) {
|
||||
var nextItem = outputSlots[(i + j) % outputSlots.length].getItem();
|
||||
if (!nextItem.isEmpty()) {
|
||||
newOutputs[i] = nextItem.copy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < newOutputs.length; i++) {
|
||||
outputSlots[i].set(newOutputs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user