Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5da5315a5b | |||
| f3c44c64c2 | |||
| b8f48407cd | |||
| 489b0f635e | |||
| e6fb553a53 | |||
| cacd824db3 | |||
| 876bb52087 | |||
| 1b4969c8e7 | |||
| f2427ee347 | |||
| 4aa9c92a68 | |||
| 971a9d22e8 | |||
| b5a90357c0 | |||
| 76efe6026d | |||
| 4e03cbd356 | |||
| 9005db6f1c | |||
| 58afe755b8 | |||
| f368f9dac2 | |||
| e5b45d51cc | |||
| 5a1d5356d1 | |||
| 1759f92164 | |||
| e50c13e570 |
@@ -2,7 +2,8 @@ name: 'Build PRs'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -106,6 +106,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
private Stopwatch dbl_clickTimer = Stopwatch.createStarted();
|
||||
private ItemStack dbl_whichItem = ItemStack.EMPTY;
|
||||
private Slot bl_clicked;
|
||||
private boolean handlingRightClick;
|
||||
protected final List<CustomSlotWidget> guiSlots = new ArrayList<>();
|
||||
|
||||
public AEBaseScreen(T container, PlayerInventory playerInventory, Text title) {
|
||||
@@ -284,12 +285,18 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
|
||||
this.drag_click.clear();
|
||||
|
||||
// Forward right-clicks as-if they were left-clicks
|
||||
if (btn == 1) {
|
||||
for (final Object o : this.buttons) {
|
||||
final AbstractButtonWidget widget = (AbstractButtonWidget) o;
|
||||
if (widget.isMouseOver(xCoord, yCoord)) {
|
||||
return super.mouseClicked(xCoord, yCoord, 0);
|
||||
handlingRightClick = true;
|
||||
try {
|
||||
for (final Object o : this.buttons) {
|
||||
final AbstractButtonWidget widget = (AbstractButtonWidget) o;
|
||||
if (widget.isMouseOver(xCoord, yCoord)) {
|
||||
return super.mouseClicked(xCoord, yCoord, 0);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
handlingRightClick = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,15 +643,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
}
|
||||
|
||||
protected Text getGuiDisplayName(final Text in) {
|
||||
return this.hasCustomInventoryName() ? new LiteralText(this.getInventoryName()) : in;
|
||||
}
|
||||
|
||||
private boolean hasCustomInventoryName() {
|
||||
return this.handler.getCustomName() != null;
|
||||
}
|
||||
|
||||
private String getInventoryName() {
|
||||
return this.handler.getCustomName();
|
||||
return title.getString().isEmpty() ? in : title;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -824,6 +823,14 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true while the current event being handled is a click of the right
|
||||
* mouse button.
|
||||
*/
|
||||
public boolean isHandlingRightClick() {
|
||||
return handlingRightClick;
|
||||
}
|
||||
|
||||
public List<Rectangle> getExclusionZones() {
|
||||
return Lists.newArrayList(new Rectangle(x, y, backgroundWidth, backgroundHeight));
|
||||
}
|
||||
|
||||
@@ -46,22 +46,28 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT, value -> {
|
||||
});
|
||||
this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT);
|
||||
this.amountToCraft.setValue(1);
|
||||
this.amountToCraft.setTextFieldBounds(62, 57, 50);
|
||||
this.amountToCraft.setMinValue(1);
|
||||
this.amountToCraft.setHideValidationIcon(true);
|
||||
this.amountToCraft.addButtons(children::add, this::addButton);
|
||||
|
||||
this.next = this
|
||||
.addButton(new ButtonWidget(this.x + 128, this.y + 51, 38, 20, GuiText.Next.text(), this::confirm));
|
||||
this.amountToCraft.setOnConfirm(() -> this.confirm(this.next));
|
||||
|
||||
subGui.addBackButton(this::addButton, 154, 0);
|
||||
|
||||
changeFocus(true);
|
||||
}
|
||||
|
||||
private void confirm(ButtonWidget button) {
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new CraftRequestPacket((int) this.amountToCraft.getValue(), hasShiftDown()));
|
||||
int amount = this.amountToCraft.getIntValue().orElse(0);
|
||||
if (amount <= 0) {
|
||||
return;
|
||||
}
|
||||
NetworkHandler.instance().sendToServer(new CraftRequestPacket(amount, hasShiftDown()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,23 +83,9 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
|
||||
this.bindTexture("guis/craft_amt.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
|
||||
this.next.active = this.amountToCraft.getValue() > 0;
|
||||
this.next.active = this.amountToCraft.getIntValue().orElse(0) > 0;
|
||||
|
||||
this.amountToCraft.render(matrices, offsetX, offsetY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
|
||||
if (keyCode == 28) {
|
||||
this.next.onPress();
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
return "guis/craftAmt.png";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.util.List;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
@@ -73,10 +75,6 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
this.setScrollBar(scrollbar);
|
||||
}
|
||||
|
||||
boolean isAutoStart() {
|
||||
return this.handler.isAutoStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
@@ -87,7 +85,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
this.addButton(this.start);
|
||||
|
||||
this.selectCPU = new ButtonWidget(this.x + (219 - 180) / 2, this.y + this.backgroundHeight - 68, 180, 20,
|
||||
GuiText.CraftingCPU.withSuffix(": ").append(GuiText.Automatic.text()), btn -> selectNextCpu());
|
||||
getNextCpuButtonLabel(), btn -> selectNextCpu());
|
||||
this.selectCPU.active = false;
|
||||
this.addButton(this.selectCPU);
|
||||
|
||||
@@ -135,22 +133,22 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
}
|
||||
|
||||
private void updateCPUButtonText() {
|
||||
Text btnTextText = GuiText.CraftingCPU.withSuffix(": ").append(GuiText.Automatic.text());
|
||||
if (this.handler.getSelectedCpu() >= 0)// && status.selectedCpu < status.cpus.size() )
|
||||
{
|
||||
if (this.handler.getName() != null) {
|
||||
final String name = this.handler.getName().asTruncatedString(20);
|
||||
btnTextText = GuiText.CraftingCPU.withSuffix(": " + name);
|
||||
} else {
|
||||
btnTextText = GuiText.CraftingCPU.withSuffix(": #" + this.handler.getSelectedCpu());
|
||||
}
|
||||
}
|
||||
this.selectCPU.setMessage(getNextCpuButtonLabel());
|
||||
}
|
||||
|
||||
private Text getNextCpuButtonLabel() {
|
||||
if (this.handler.hasNoCPU()) {
|
||||
btnTextText = GuiText.NoCraftingCPUs.text();
|
||||
return GuiText.NoCraftingCPUs.text();
|
||||
}
|
||||
|
||||
this.selectCPU.setMessage(btnTextText);
|
||||
Text cpuName;
|
||||
if (this.handler.cpuName == null) {
|
||||
cpuName = GuiText.Automatic.text();
|
||||
} else {
|
||||
cpuName = this.handler.cpuName;
|
||||
}
|
||||
|
||||
return GuiText.CraftingCPU.withSuffix(": ").append(cpuName);
|
||||
}
|
||||
|
||||
private boolean isSimulation() {
|
||||
@@ -442,7 +440,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
|
||||
if (!this.checkHotbarKeys(keyCode, scanCode)) {
|
||||
if (keyCode == 28) {
|
||||
if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) {
|
||||
this.start();
|
||||
return true;
|
||||
}
|
||||
@@ -451,7 +449,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
}
|
||||
|
||||
private void selectNextCpu() {
|
||||
final boolean backwards = getClient().mouse.wasRightButtonClicked();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
|
||||
}
|
||||
|
||||
|
||||
@@ -44,12 +44,12 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
super.init();
|
||||
|
||||
this.selectCPU = new ButtonWidget(this.x + 8, this.y + this.backgroundHeight - 25, 150, 20,
|
||||
GuiText.CraftingCPU.withSuffix(": ").append(GuiText.NoCraftingCPUs.text()), btn -> selectNextCpu());
|
||||
getNextCpuButtonLabel(), btn -> selectNextCpu());
|
||||
this.addButton(this.selectCPU);
|
||||
|
||||
subGui.addBackButton(btn -> {
|
||||
addButton(btn);
|
||||
btn.setHideEdge(13);
|
||||
btn.setHideEdge(true);
|
||||
}, 213, -4);
|
||||
}
|
||||
|
||||
@@ -60,23 +60,14 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
}
|
||||
|
||||
private void updateCPUButtonText() {
|
||||
Text btnTextText = GuiText.NoCraftingJobs.text();
|
||||
|
||||
if (this.handler.selectedCpu >= 0)// && status.selectedCpu < status.cpus.size() )
|
||||
{
|
||||
if (this.handler.myName != null) {
|
||||
final String name = this.handler.myName.asTruncatedString(20);
|
||||
btnTextText = GuiText.CPUs.withSuffix(": " + name);
|
||||
} else {
|
||||
btnTextText = GuiText.CPUs.withSuffix(": #" + this.handler.selectedCpu);
|
||||
}
|
||||
}
|
||||
this.selectCPU.setMessage(getNextCpuButtonLabel());
|
||||
}
|
||||
|
||||
private Text getNextCpuButtonLabel() {
|
||||
if (this.handler.noCPU) {
|
||||
btnTextText = GuiText.NoCraftingJobs.text();
|
||||
return GuiText.NoCraftingJobs.text();
|
||||
}
|
||||
|
||||
this.selectCPU.setMessage(btnTextText);
|
||||
return GuiText.CraftingCPU.withSuffix(": ").append(handler.cpuName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,9 +75,8 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
return in; // the cup name is on the button
|
||||
}
|
||||
|
||||
// FIXME: Extract to separate class? Shared with GuiCraftConfirm
|
||||
private void selectNextCpu() {
|
||||
final boolean backwards = client.mouse.wasRightButtonClicked();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class InterfaceScreen extends UpgradeableScreen<InterfaceContainer> {
|
||||
}
|
||||
|
||||
private void selectNextInterfaceMode() {
|
||||
final boolean backwards = getClient().mouse.wasRightButtonClicked();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ import appeng.client.gui.widgets.ServerSettingToggleButton;
|
||||
import appeng.client.gui.widgets.SettingToggleButton;
|
||||
import appeng.container.implementations.LevelEmitterContainer;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
|
||||
public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> {
|
||||
|
||||
@@ -51,15 +49,18 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT,
|
||||
this::onLevelChange);
|
||||
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT);
|
||||
this.level.setTextFieldBounds(25, 44, 75);
|
||||
this.level.addButtons(children::add, this::addButton);
|
||||
handler.setTextField(this.level);
|
||||
this.level.setValue(handler.getReportingValue());
|
||||
this.level.setOnChange(this::saveReportingValue);
|
||||
this.level.setOnConfirm(this::onClose);
|
||||
|
||||
this.changeFocus(true);
|
||||
}
|
||||
|
||||
private void onLevelChange(long level) {
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(level)));
|
||||
private void saveReportingValue() {
|
||||
this.level.getLongValue().ifPresent(handler::setReportingValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,6 +26,7 @@ import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import me.shedaniel.math.Rectangle;
|
||||
@@ -51,6 +52,7 @@ import appeng.client.gui.widgets.SettingToggleButton;
|
||||
import appeng.client.gui.widgets.TabButton;
|
||||
import appeng.client.me.InternalSlotME;
|
||||
import appeng.client.me.ItemRepo;
|
||||
import appeng.client.render.StackSizeRenderer;
|
||||
import appeng.container.implementations.CraftingStatusContainer;
|
||||
import appeng.container.implementations.MEMonitorableContainer;
|
||||
import appeng.container.slot.AppEngSlot;
|
||||
@@ -237,7 +239,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
if (this.viewCell || this instanceof WirelessTermScreen) {
|
||||
this.craftingStatusBtn = this.addButton(new TabButton(this.x + 170, this.y - 4, 2 + 11 * 16,
|
||||
GuiText.CraftingStatus.text(), this.itemRenderer, btn -> showCraftingStatus()));
|
||||
this.craftingStatusBtn.setHideEdge(13);
|
||||
this.craftingStatusBtn.setHideEdge(true);
|
||||
}
|
||||
|
||||
this.isAutoFocus = SearchBoxMode.AUTOSEARCH == searchMode || SearchBoxMode.JEI_AUTOSEARCH == searchMode
|
||||
@@ -294,6 +296,16 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
|
||||
this.currentMouseX = mouseX;
|
||||
this.currentMouseY = mouseY;
|
||||
|
||||
// Show the number of active crafting jobs
|
||||
if (this.craftingStatusBtn != null && handler.activeCraftingJobs != -1) {
|
||||
// The stack size renderer expects a 16x16 slot, while the button is normally
|
||||
// bigger
|
||||
int x = this.craftingStatusBtn.x + (this.craftingStatusBtn.getWidth() - 16) / 2;
|
||||
int y = this.craftingStatusBtn.y + (this.craftingStatusBtn.getHeight() - 16) / 2;
|
||||
StackSizeRenderer.renderSizeLabel(textRenderer, x - this.x, y - this.y,
|
||||
new LiteralText(String.valueOf(handler.activeCraftingJobs)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -358,6 +370,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
if (this.searchField != null) {
|
||||
this.searchField.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
|
||||
@@ -2,41 +2,58 @@ package appeng.client.gui.implementations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.NumberEntryType;
|
||||
import appeng.client.gui.widgets.ITickingWidget;
|
||||
import appeng.client.gui.widgets.NumberBox;
|
||||
import appeng.client.gui.widgets.ConfirmableTextField;
|
||||
import appeng.client.gui.widgets.ValidationIcon;
|
||||
import appeng.core.AEConfig;
|
||||
|
||||
/**
|
||||
* A utility widget that consists of a text-field to enter a number with
|
||||
* attached buttons to increment/decrement the number in fixed intervals.
|
||||
*/
|
||||
public class NumberEntryWidget implements ITickingWidget {
|
||||
public class NumberEntryWidget extends DrawableHelper {
|
||||
|
||||
private static final Text INVALID_NUMBER = new TranslatableText("gui.appliedenergistics2.validation.InvalidNumber");
|
||||
private static final String NUMBER_LESS_THAN_MIN_VALUE = "gui.appliedenergistics2.validation.NumberLessThanMinValue";
|
||||
private static final Text PLUS = Text.of("+");
|
||||
private static final Text MINUS = Text.of("-");
|
||||
private static final int TEXT_COLOR_ERROR = 0xFF1900;
|
||||
private static final int TEXT_COLOR_NORMAL = 0xFFFFFF;
|
||||
|
||||
private final AEBaseScreen<?> parent;
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
private final NumberBox level;
|
||||
private final ConfirmableTextField textField;
|
||||
private final NumberEntryType type;
|
||||
private List<ButtonWidget> buttons;
|
||||
private long minValue;
|
||||
private ValidationIcon validationIcon;
|
||||
|
||||
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type,
|
||||
LongConsumer changeListener) {
|
||||
// Called when the value changes
|
||||
private Runnable onChange;
|
||||
|
||||
// Called when the user presses enter while there's a valid number in the field
|
||||
private Runnable onConfirm;
|
||||
|
||||
private boolean hideValidationIcon;
|
||||
|
||||
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type) {
|
||||
this.parent = parent;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
@@ -45,27 +62,50 @@ public class NumberEntryWidget implements ITickingWidget {
|
||||
TextRenderer font = parent.getClient().textRenderer;
|
||||
int inputX = parent.getX() + x;
|
||||
int inputY = parent.getY() + y;
|
||||
this.level = new NumberBox(font, inputX, inputY, width, font.fontHeight, type.getInputType(), changeListener);
|
||||
this.level.setHasBorder(false);
|
||||
this.level.setMaxLength(16);
|
||||
this.level.setEditableColor(0xFFFFFF);
|
||||
this.level.setVisible(true);
|
||||
parent.setInitialFocus(this.level);
|
||||
this.textField = new ConfirmableTextField(font, inputX, inputY, width, font.fontHeight, LiteralText.EMPTY);
|
||||
this.textField.setHasBorder(false);
|
||||
this.textField.setMaxLength(16);
|
||||
this.textField.setEditableColor(TEXT_COLOR_NORMAL);
|
||||
this.textField.setVisible(true);
|
||||
this.textField.setSelected(true);
|
||||
parent.setInitialFocus(this.textField);
|
||||
this.textField.setChangedListener(text -> {
|
||||
validate();
|
||||
if (onChange != null) {
|
||||
this.onChange.run();
|
||||
}
|
||||
});
|
||||
this.textField.setOnConfirm(() -> {
|
||||
// Only confirm if it's actually valid
|
||||
if (this.onConfirm != null && getLongValue().isPresent()) {
|
||||
this.onConfirm.run();
|
||||
}
|
||||
});
|
||||
validate();
|
||||
}
|
||||
|
||||
public void setOnConfirm(Runnable callback) {
|
||||
this.onConfirm = callback;
|
||||
}
|
||||
|
||||
public void setOnChange(Runnable callback) {
|
||||
this.onChange = callback;
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.level.active = active;
|
||||
this.textField.active = active;
|
||||
this.buttons.forEach(b -> b.active = active);
|
||||
}
|
||||
|
||||
public void setTextFieldBounds(int x, int y, int width) {
|
||||
this.level.x = parent.getX() + x;
|
||||
this.level.y = parent.getY() + y;
|
||||
this.level.setWidth(width);
|
||||
this.textField.x = parent.getX() + x;
|
||||
this.textField.y = parent.getY() + y;
|
||||
this.textField.setWidth(width);
|
||||
}
|
||||
|
||||
public void setMinValue(long minValue) {
|
||||
this.level.setMinValue(minValue);
|
||||
this.minValue = minValue;
|
||||
validate();
|
||||
}
|
||||
|
||||
public void addButtons(Consumer<Element> addChildren, Consumer<ButtonWidget> addButton) {
|
||||
@@ -78,54 +118,116 @@ public class NumberEntryWidget implements ITickingWidget {
|
||||
int left = parent.getX() + x;
|
||||
int top = parent.getY() + y;
|
||||
|
||||
List<ButtonWidget> buttons = new ArrayList<>(8);
|
||||
List<ButtonWidget> buttons = new ArrayList<>(9);
|
||||
|
||||
buttons.add(new ButtonWidget(left, top, 22, 20, makeLabel(PLUS, a), btn -> addQty(a)));
|
||||
buttons.add(new ButtonWidget(left + 28, top, 28, 20, makeLabel(PLUS, b), btn -> addQty(b)));
|
||||
buttons.add(new ButtonWidget(left + 62, top, 32, 20, makeLabel(PLUS, c), btn -> addQty(c)));
|
||||
buttons.add(new ButtonWidget(left + 100, top, 38, 20, makeLabel(PLUS, d), btn -> addQty(d)));
|
||||
|
||||
// Need to add these now for sensible tab-order
|
||||
buttons.forEach(addButton);
|
||||
|
||||
// Placing this here will give a sensible tab order
|
||||
addChildren.accept(this.level);
|
||||
addChildren.accept(this.textField);
|
||||
|
||||
buttons.add(new ButtonWidget(left, top + 42, 22, 20, makeLabel(MINUS, a), btn -> addQty(-a)));
|
||||
buttons.add(new ButtonWidget(left + 28, top + 42, 28, 20, makeLabel(MINUS, b), btn -> addQty(-b)));
|
||||
buttons.add(new ButtonWidget(left + 62, top + 42, 32, 20, makeLabel(MINUS, c), btn -> addQty(-c)));
|
||||
buttons.add(new ButtonWidget(left + 100, top + 42, 38, 20, makeLabel(MINUS, d), btn -> addQty(-d)));
|
||||
|
||||
// This element is not focusable
|
||||
if (!hideValidationIcon) {
|
||||
this.validationIcon = new ValidationIcon(left + 104, top + 27);
|
||||
buttons.add(this.validationIcon);
|
||||
}
|
||||
|
||||
// Add the rest to the tab order
|
||||
buttons.subList(4, buttons.size()).forEach(addButton);
|
||||
|
||||
this.buttons = buttons;
|
||||
this.buttons.forEach(addButton);
|
||||
|
||||
// we need to re-validate because the icon may now be present and needs it's
|
||||
// initial state
|
||||
this.validate();
|
||||
}
|
||||
|
||||
private void addQty(final long i) {
|
||||
long currentValue = this.level.getValue();
|
||||
long minValue = this.level.getMinValue();
|
||||
this.level.setText(String.valueOf(Math.max(minValue, currentValue + i)));
|
||||
/**
|
||||
* Returns the integer value currently in the text-field, if it is a valid
|
||||
* number and is within the allowed min/max value.
|
||||
*/
|
||||
public OptionalInt getIntValue() {
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
int value = Integer.parseInt(text, 10);
|
||||
if (value < minValue) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
return OptionalInt.of(value);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) {
|
||||
this.level.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
public void setValue(long value, boolean skipNotify) {
|
||||
this.level.setValue(value, skipNotify);
|
||||
/**
|
||||
* Returns the long value currently in the text-field, if it is a valid number
|
||||
* and is within the allowed min/max value.
|
||||
*/
|
||||
public OptionalLong getLongValue() {
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
long value = Long.parseLong(text, 10);
|
||||
if (value < minValue) {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
return OptionalLong.of(value);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(long value) {
|
||||
setValue(value, false);
|
||||
this.textField.setText(String.valueOf(Math.max(minValue, value)));
|
||||
this.textField.setCursorToEnd();
|
||||
this.textField.setSelectionStart(0);
|
||||
validate();
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return level.getValue();
|
||||
private void addQty(final long i) {
|
||||
getLongValue().ifPresent(currentValue -> setValue(currentValue + i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
this.level.tick();
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) {
|
||||
this.textField.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
private void validate() {
|
||||
List<Text> validationErrors = new ArrayList<>();
|
||||
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
long value = Long.parseLong(text, 10);
|
||||
if (value < minValue) {
|
||||
validationErrors.add(new TranslatableText(NUMBER_LESS_THAN_MIN_VALUE, minValue));
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
validationErrors.add(INVALID_NUMBER);
|
||||
}
|
||||
|
||||
boolean valid = validationErrors.isEmpty();
|
||||
this.textField.setEditableColor(valid ? TEXT_COLOR_NORMAL : TEXT_COLOR_ERROR);
|
||||
if (this.validationIcon != null) {
|
||||
this.validationIcon.setValid(valid);
|
||||
this.validationIcon.setTooltip(validationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
private Text makeLabel(Text prefix, int amount) {
|
||||
return prefix.copy().append(String.valueOf(amount));
|
||||
}
|
||||
|
||||
public void setHideValidationIcon(boolean hideValidationIcon) {
|
||||
this.hideValidationIcon = hideValidationIcon;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.text.Text;
|
||||
@@ -26,8 +28,6 @@ import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.NumberEntryType;
|
||||
import appeng.container.implementations.PriorityContainer;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
|
||||
public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
|
||||
@@ -38,24 +38,38 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, Text title) {
|
||||
super(container, playerInventory, title);
|
||||
this.subGui = new AESubScreen(this, container.getPriorityHost());
|
||||
|
||||
// This is the effective size of the background image
|
||||
backgroundWidth = 175;
|
||||
backgroundHeight = 128;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY, this::onPriorityChange);
|
||||
this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY);
|
||||
this.priority.setTextFieldBounds(62, 57, 50);
|
||||
this.priority.setMinValue(Integer.MIN_VALUE);
|
||||
handler.setTextField(this.priority);
|
||||
this.priority.setValue(this.handler.getPriorityValue());
|
||||
this.priority.addButtons(children::add, this::addButton);
|
||||
|
||||
this.subGui.addBackButton(this::addButton, 154, 0);
|
||||
|
||||
this.priority.setOnChange(this::savePriority);
|
||||
this.priority.setOnConfirm(() -> {
|
||||
savePriority();
|
||||
this.subGui.goBack();
|
||||
});
|
||||
|
||||
changeFocus(true);
|
||||
}
|
||||
|
||||
private void onPriorityChange(long priority) {
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(priority)));
|
||||
private void savePriority() {
|
||||
OptionalInt priority = this.priority.getIntValue();
|
||||
if (priority.isPresent()) {
|
||||
handler.setPriority(priority.getAsInt());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,13 +80,10 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
@Override
|
||||
public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY,
|
||||
float partialTicks) {
|
||||
this.bindTexture(getBackground());
|
||||
this.bindTexture("guis/priority.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
|
||||
this.priority.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
return "guis/priority.png";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class ConfirmableTextField extends TextFieldWidget {
|
||||
|
||||
private Runnable onConfirm;
|
||||
|
||||
public ConfirmableTextField(TextRenderer fontRenderer, int x, int y, int width, int height, Text text) {
|
||||
super(fontRenderer, x, y, width, height, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (isActive() && (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER)) {
|
||||
if (this.onConfirm != null) {
|
||||
this.onConfirm.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
public void setOnConfirm(Runnable onConfirm) {
|
||||
this.onConfirm = onConfirm;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.sound.SoundManager;
|
||||
import net.minecraft.client.texture.TextureManager;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
@@ -33,6 +34,10 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
|
||||
private boolean halfSize = false;
|
||||
|
||||
private boolean disableClickSound = false;
|
||||
|
||||
private boolean disableBackground = false;
|
||||
|
||||
public IconButton(final int x, final int y, PressAction onPress) {
|
||||
super(x, y, 16, 16, LiteralText.EMPTY, onPress);
|
||||
}
|
||||
@@ -42,6 +47,13 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
this.active = vis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playDownSound(SoundManager soundManager) {
|
||||
if (!disableClickSound) {
|
||||
super.playDownSound(soundManager);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrices, final int mouseX, final int mouseY, float partial) {
|
||||
|
||||
@@ -72,7 +84,9 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
final int uv_y = iconIndex / 16;
|
||||
final int uv_x = iconIndex - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, 0, 0, 256 - 16, 256 - 16, 16, 16);
|
||||
if (!disableBackground) {
|
||||
drawTexture(matrices, 0, 0, 256 - 16, 256 - 16, 16, 16);
|
||||
}
|
||||
drawTexture(matrices, 0, 0, uv_x * 16, uv_y * 16, 16, 16);
|
||||
RenderSystem.popMatrix();
|
||||
} else {
|
||||
@@ -85,12 +99,18 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
final int uv_y = iconIndex / 16;
|
||||
final int uv_x = iconIndex - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, this.x, this.y, 256 - 16, 256 - 16, 16, 16);
|
||||
if (!disableBackground) {
|
||||
drawTexture(matrices, this.x, this.y, 256 - 16, 256 - 16, 16, 16);
|
||||
}
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, uv_y * 16, 16, 16);
|
||||
}
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
if (isHovered()) {
|
||||
renderToolTip(matrices, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
protected abstract int getIconIndex();
|
||||
@@ -133,4 +153,20 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
this.halfSize = halfSize;
|
||||
}
|
||||
|
||||
public boolean isDisableClickSound() {
|
||||
return disableClickSound;
|
||||
}
|
||||
|
||||
public void setDisableClickSound(boolean disableClickSound) {
|
||||
this.disableClickSound = disableClickSound;
|
||||
}
|
||||
|
||||
public boolean isDisableBackground() {
|
||||
return disableBackground;
|
||||
}
|
||||
|
||||
public void setDisableBackground(boolean disableBackground) {
|
||||
this.disableBackground = disableBackground;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.LiteralText;
|
||||
|
||||
public class NumberBox extends TextFieldWidget {
|
||||
|
||||
private final LongConsumer changeListener;
|
||||
|
||||
private long lastValue;
|
||||
|
||||
private long minValue = 0;
|
||||
|
||||
private long maxValue;
|
||||
|
||||
public NumberBox(final TextRenderer fontRenderer, final int x, final int y, final int width, final int height,
|
||||
final Class<?> type, LongConsumer changeListener) {
|
||||
super(fontRenderer, x, y, width, height, new LiteralText("0"));
|
||||
this.setText("0");
|
||||
setChangedListener(this::handleTextChanged);
|
||||
this.lastValue = 0;
|
||||
this.changeListener = changeListener;
|
||||
if (type == int.class || type == Integer.class) {
|
||||
maxValue = Integer.MAX_VALUE;
|
||||
} else {
|
||||
maxValue = Long.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: This method MUST NOT BE NAMED like a method in the superclass because
|
||||
// of a ForgeGradle remapping bug
|
||||
// since it'll not remap this method's name, but it will remap the name of the
|
||||
// method reference above.
|
||||
private void handleTextChanged(String text) {
|
||||
if (text.isEmpty()) {
|
||||
setText("0"); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
|
||||
boolean canBeNegative = canBeNegative();
|
||||
if (canBeNegative && text.equals("-")) {
|
||||
// Allow this as a special case to make typing in a negative number easier
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sanitized = new StringBuilder(text);
|
||||
boolean encounteredNonZero = false;
|
||||
for (int i = 0; i < sanitized.length(); i++) {
|
||||
char ch = sanitized.charAt(i);
|
||||
if (canBeNegative && i == 0 && ch == '-') {
|
||||
continue; // Allow leading minus sign
|
||||
}
|
||||
if (ch >= '1' && ch <= '9') {
|
||||
encounteredNonZero = true;
|
||||
continue;
|
||||
}
|
||||
if (ch != '0' || !encounteredNonZero) {
|
||||
sanitized.deleteCharAt(i--);
|
||||
}
|
||||
}
|
||||
if (sanitized.length() == 0) {
|
||||
sanitized.append('0');
|
||||
}
|
||||
String sanitizedStr = sanitized.toString();
|
||||
if (!sanitizedStr.equals(text)) {
|
||||
setText(sanitizedStr); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
if (getValue() < minValue) {
|
||||
setText(String.valueOf(minValue)); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
if (getValue() > maxValue) {
|
||||
setText(String.valueOf(maxValue)); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
|
||||
reportChange();
|
||||
}
|
||||
|
||||
private void reportChange() {
|
||||
long value = getValue();
|
||||
if (value != lastValue) {
|
||||
lastValue = value;
|
||||
changeListener.accept(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(long value, boolean skipNotify) {
|
||||
// This check avoid changing the cursor position needlessly
|
||||
if (value == this.getValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (skipNotify) {
|
||||
lastValue = value;
|
||||
}
|
||||
setText(String.valueOf(value));
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
if (getText().equals("-") && canBeNegative()) {
|
||||
return lastValue; // Allow this as a special case to type in a negative number more easily
|
||||
}
|
||||
|
||||
return Long.parseLong(getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int p_keyPressed_1_, int p_keyPressed_2_, int p_keyPressed_3_) {
|
||||
if (super.keyPressed(p_keyPressed_1_, p_keyPressed_2_, p_keyPressed_3_)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Swallow key presses for numbers because they would otherwise trigger the
|
||||
// hotbar swapping unintentionally
|
||||
return isFocused() && p_keyPressed_1_ >= '0' && p_keyPressed_1_ <= '9';
|
||||
}
|
||||
|
||||
public void setMinValue(long minValue) {
|
||||
this.minValue = minValue;
|
||||
}
|
||||
|
||||
public long getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
|
||||
private boolean canBeNegative() {
|
||||
return minValue < 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
@@ -47,6 +48,7 @@ import appeng.api.config.StorageFilter;
|
||||
import appeng.api.config.TerminalStyle;
|
||||
import appeng.api.config.ViewItems;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.core.localization.ButtonToolTips;
|
||||
import appeng.util.EnumCycler;
|
||||
|
||||
@@ -89,9 +91,11 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
|
||||
registerApp(16 * 7, Settings.CONDENSER_OUTPUT, CondenserOutput.TRASH, ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.Trash);
|
||||
registerApp(16 * 7 + 1, Settings.CONDENSER_OUTPUT, CondenserOutput.MATTER_BALLS,
|
||||
ButtonToolTips.CondenserOutput, ButtonToolTips.MatterBalls);
|
||||
ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.MatterBalls.text(CondenserOutput.MATTER_BALLS.requiredPower));
|
||||
registerApp(16 * 7 + 2, Settings.CONDENSER_OUTPUT, CondenserOutput.SINGULARITY,
|
||||
ButtonToolTips.CondenserOutput, ButtonToolTips.Singularity);
|
||||
ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.Singularity.text(CondenserOutput.SINGULARITY.requiredPower));
|
||||
|
||||
registerApp(16 * 9 + 1, Settings.ACCESS, AccessRestriction.READ, ButtonToolTips.IOMode,
|
||||
ButtonToolTips.Read);
|
||||
@@ -230,7 +234,13 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
|
||||
}
|
||||
|
||||
private void triggerPress() {
|
||||
boolean backwards = MinecraftClient.getInstance().mouse.wasRightButtonClicked();
|
||||
boolean backwards = false;
|
||||
// This isn't great, but we don't get any information about right-clicks
|
||||
// otherwise
|
||||
Screen currentScreen = MinecraftClient.getInstance().currentScreen;
|
||||
if (currentScreen instanceof AEBaseScreen) {
|
||||
backwards = ((AEBaseScreen<?>) currentScreen).isHandlingRightClick();
|
||||
}
|
||||
onPress.handle(this, backwards);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import net.minecraft.util.Identifier;
|
||||
public class TabButton extends ButtonWidget implements ITooltip {
|
||||
public static final Identifier TEXTURE_STATES = new Identifier("appliedenergistics2", "textures/guis/states.png");
|
||||
private final ItemRenderer itemRenderer;
|
||||
private int hideEdge = 0;
|
||||
private boolean hideEdge;
|
||||
private int myIcon = -1;
|
||||
private ItemStack myItem;
|
||||
|
||||
@@ -69,14 +69,17 @@ public class TabButton extends ButtonWidget implements ITooltip {
|
||||
|
||||
RenderSystem.enableAlphaTest();
|
||||
|
||||
int uv_x = (this.hideEdge > 0 ? 11 : 13);
|
||||
// Selects the button border from the sprite-sheet, where each type occupies a
|
||||
// 2x2 slot
|
||||
int uv_x = 8 + (this.hideEdge ? 0 : 2);
|
||||
int uv_y = 12 + (this.isFocused() ? 2 : 0);
|
||||
|
||||
final int offsetX = this.hideEdge > 0 ? 1 : 0;
|
||||
final int offsetX = this.hideEdge ? 1 : 0;
|
||||
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, 0, 25, 22);
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, uv_y * 16, 25, 22);
|
||||
|
||||
if (this.myIcon >= 0) {
|
||||
final int uv_y = this.myIcon / 16;
|
||||
uv_y = this.myIcon / 16;
|
||||
uv_x = this.myIcon - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, offsetX + this.x + 3, this.y + 3, uv_x * 16, uv_y * 16, 16, 16);
|
||||
@@ -122,11 +125,11 @@ public class TabButton extends ButtonWidget implements ITooltip {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
public int getHideEdge() {
|
||||
public boolean getHideEdge() {
|
||||
return this.hideEdge;
|
||||
}
|
||||
|
||||
public void setHideEdge(final int hideEdge) {
|
||||
public void setHideEdge(final boolean hideEdge) {
|
||||
this.hideEdge = hideEdge;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
/**
|
||||
* Displays a small icon that shows validation errors for some input control.
|
||||
*/
|
||||
public class ValidationIcon extends IconButton {
|
||||
|
||||
private final List<Text> tooltip = new ArrayList<>();
|
||||
|
||||
private boolean valid;
|
||||
|
||||
public ValidationIcon(int x, int y) {
|
||||
super(x, y, btn -> {
|
||||
});
|
||||
setDisableBackground(true);
|
||||
setDisableClickSound(true);
|
||||
setHalfSize(true);
|
||||
}
|
||||
|
||||
public void setValid(boolean valid) {
|
||||
setVisibility(!valid);
|
||||
if (valid) {
|
||||
this.tooltip.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTooltip(List<Text> lines) {
|
||||
this.tooltip.clear();
|
||||
this.tooltip.addAll(lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getIconIndex() {
|
||||
return 16 * 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeFocus(boolean flag) {
|
||||
return false; // Cannot focus this element
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderToolTip(MatrixStack matrices, int mouseX, int mouseY) {
|
||||
if (this.tooltip.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
Screen screen = client.currentScreen;
|
||||
if (screen == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
screen.renderTooltip(matrices, this.tooltip, x, y);
|
||||
}
|
||||
}
|
||||
@@ -66,10 +66,8 @@ import appeng.container.slot.PlayerInvSlot;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.core.sync.packets.InventoryActionPacket;
|
||||
import appeng.core.sync.packets.TargetItemStackPacket;
|
||||
import appeng.helpers.ICustomNameObject;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import appeng.me.helpers.PlayerSource;
|
||||
import appeng.mixins.ScreenHandlerListeners;
|
||||
@@ -88,11 +86,9 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
private final IGuiItemObject obj;
|
||||
private final HashMap<Integer, SyncData> syncData = new HashMap<>();
|
||||
private boolean isContainerValid = true;
|
||||
private String customName;
|
||||
private ContainerLocator locator;
|
||||
private IMEInventoryHandler<IAEItemStack> cellInv;
|
||||
private IEnergySource powerSrc;
|
||||
private boolean sentCustomName;
|
||||
private int ticksSinceCheck = 900;
|
||||
private IAEItemStack clientRequestedTargetItem = null;
|
||||
|
||||
@@ -317,9 +313,7 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
this.sendCustomName();
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (this.tileEntity != null
|
||||
&& this.tileEntity.getWorld().getBlockEntity(this.tileEntity.getPos()) != this.tileEntity) {
|
||||
this.setValidContainer(false);
|
||||
@@ -886,43 +880,6 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
this.sendContentUpdates();
|
||||
}
|
||||
|
||||
private void sendCustomName() {
|
||||
// FIXME: Trash this, this is handled by NamedContainerProvider now
|
||||
if (!this.sentCustomName) {
|
||||
this.sentCustomName = true;
|
||||
if (Platform.isServer()) {
|
||||
ICustomNameObject name = null;
|
||||
|
||||
if (this.part instanceof ICustomNameObject) {
|
||||
name = (ICustomNameObject) this.part;
|
||||
}
|
||||
|
||||
if (this.tileEntity instanceof ICustomNameObject) {
|
||||
name = (ICustomNameObject) this.tileEntity;
|
||||
}
|
||||
|
||||
if (this.obj instanceof ICustomNameObject) {
|
||||
name = (ICustomNameObject) this.obj;
|
||||
}
|
||||
|
||||
if (this instanceof ICustomNameObject) {
|
||||
name = (ICustomNameObject) this;
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
if (name.hasCustomInventoryName()) {
|
||||
this.setCustomName(name.getCustomInventoryName().getString());
|
||||
}
|
||||
|
||||
if (this.getCustomName() != null) {
|
||||
NetworkHandler.instance().sendTo(new ConfigValuePacket("CustomName", this.getCustomName()),
|
||||
(ServerPlayerEntity) this.getPlayerInventory().player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void swapSlotContents(final int slotA, final int slotB) {
|
||||
final Slot a = this.getSlot(slotA);
|
||||
final Slot b = this.getSlot(slotB);
|
||||
@@ -1012,14 +969,6 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
this.cellInv = cellInv;
|
||||
}
|
||||
|
||||
public String getCustomName() {
|
||||
return this.customName;
|
||||
}
|
||||
|
||||
public void setCustomName(final String customName) {
|
||||
this.customName = customName;
|
||||
}
|
||||
|
||||
public PlayerInventory getPlayerInventory() {
|
||||
return this.invPlayer;
|
||||
}
|
||||
@@ -1048,4 +997,18 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
this.powerSrc = powerSrc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this container instance lives on the client.
|
||||
*/
|
||||
protected boolean isClient() {
|
||||
return invPlayer.player.getEntityWorld().isClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this container instance lives on the server.
|
||||
*/
|
||||
protected boolean isServer() {
|
||||
return !isClient();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -89,6 +89,8 @@ public class SyncData {
|
||||
NetworkHandler.instance().sendTo(new ConfigValuePacket("SyncDat." + this.channel, json),
|
||||
(ServerPlayerEntity) o);
|
||||
}
|
||||
this.clientVersion = val;
|
||||
return;
|
||||
}
|
||||
|
||||
// Types other than Text must be non-null
|
||||
|
||||
@@ -50,7 +50,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.tile.misc.CellWorkbenchBlockEntity;
|
||||
import appeng.util.EnumCycler;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.inv.WrapperSupplierItemHandler;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
@@ -143,7 +142,7 @@ public class CellWorkbenchContainer extends UpgradeableContainer {
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
final ItemStack is = this.workBench.getInventoryByName("cell").getInvStack(0);
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
for (final ScreenHandlerListener listener : this.getListeners()) {
|
||||
if (this.prevStack != is) {
|
||||
// if the bars changed an item was probably made, so just send shit!
|
||||
|
||||
@@ -34,7 +34,6 @@ import appeng.container.interfaces.IProgressProvider;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.misc.CondenserBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CondenserContainer extends AEBaseContainer implements IProgressProvider {
|
||||
|
||||
@@ -76,13 +75,13 @@ public class CondenserContainer extends AEBaseContainer implements IProgressProv
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
final double maxStorage = this.condenser.getStorage();
|
||||
final double requiredEnergy = this.condenser.getRequiredPower();
|
||||
|
||||
this.requiredEnergy = requiredEnergy == 0 ? (int) maxStorage : (int) Math.min(requiredEnergy, maxStorage);
|
||||
this.storedPower = (int) this.condenser.getStoredPower();
|
||||
this.setOutput((CondenserOutput) this.condenser.getConfigManager().getSetting(Settings.CONDENSER_OUTPUT));
|
||||
this.output = (CondenserOutput) this.condenser.getConfigManager().getSetting(Settings.CONDENSER_OUTPUT);
|
||||
}
|
||||
|
||||
super.sendContentUpdates();
|
||||
@@ -102,7 +101,4 @@ public class CondenserContainer extends AEBaseContainer implements IProgressProv
|
||||
return this.output;
|
||||
}
|
||||
|
||||
private void setOutput(final CondenserOutput output) {
|
||||
this.output = output;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||
@@ -12,9 +14,7 @@ import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.features.IWirelessTermHandler;
|
||||
@@ -44,6 +44,8 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
private final SecurityPermissions requiredPermission;
|
||||
|
||||
private Function<I, Text> containerTitleStrategy = this::getDefaultContainerTitle;
|
||||
|
||||
public ContainerHelper(ContainerFactory<C, I> factory, Class<I> interfaceClass) {
|
||||
this(factory, interfaceClass, null);
|
||||
}
|
||||
@@ -55,19 +57,47 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom strategy for obtaining a custom container name.
|
||||
* <p>
|
||||
* The stratgy should return {@link LiteralText#EMPTY} if there's no custom
|
||||
* name.
|
||||
*/
|
||||
public ContainerHelper<C, I> withContainerTitle(Function<I, Text> containerTitleStrategy) {
|
||||
this.containerTitleStrategy = containerTitleStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a container that is based around a single block entity. The tile
|
||||
* entity's position is encoded in the packet buffer.
|
||||
*/
|
||||
public C fromNetwork(int windowId, PlayerInventory inv, PacketByteBuf packetBuf) {
|
||||
return fromNetwork(windowId, inv, packetBuf, (accessObj, container, buffer) -> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #open}, but allows or additional data to be read from the
|
||||
* packet, and passed onto the container.
|
||||
*/
|
||||
public C fromNetwork(int windowId, PlayerInventory inv, PacketByteBuf packetBuf,
|
||||
InitialDataDeserializer<C, I> initialDataDeserializer) {
|
||||
I host = getHostFromLocator(inv.player, ContainerLocator.read(packetBuf));
|
||||
if (host != null) {
|
||||
return factory.create(windowId, inv, host);
|
||||
C container = factory.create(windowId, inv, host);
|
||||
initialDataDeserializer.deserializeInitialData(host, container, packetBuf);
|
||||
return container;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean open(PlayerEntity player, ContainerLocator locator) {
|
||||
return open(player, locator, (accessObj, buffer) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public boolean open(PlayerEntity player, ContainerLocator locator, InitialDataSerializer<I> initialDataSerializer) {
|
||||
if (!(player instanceof ServerPlayerEntity)) {
|
||||
// Cannot open containers on the client or for non-players
|
||||
// FIXME logging?
|
||||
@@ -84,9 +114,9 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
return false;
|
||||
}
|
||||
|
||||
Text title = findContainerTitle(player.world, locator, accessInterface);
|
||||
Text title = containerTitleStrategy.apply(accessInterface);
|
||||
|
||||
player.openHandledScreen(new HandlerFactory(locator, title, accessInterface));
|
||||
player.openHandledScreen(new HandlerFactory(locator, title, accessInterface, initialDataSerializer));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -99,15 +129,20 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
private final Text title;
|
||||
|
||||
public HandlerFactory(ContainerLocator locator, Text title, I accessInterface) {
|
||||
private final InitialDataSerializer<I> initialDataSerializer;
|
||||
|
||||
public HandlerFactory(ContainerLocator locator, Text title, I accessInterface,
|
||||
InitialDataSerializer<I> initialDataSerializer) {
|
||||
this.locator = locator;
|
||||
this.title = title;
|
||||
this.accessInterface = accessInterface;
|
||||
this.initialDataSerializer = initialDataSerializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) {
|
||||
locator.write(buf);
|
||||
initialDataSerializer.serializeInitialData(accessInterface, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,28 +162,6 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
}
|
||||
|
||||
private Text findContainerTitle(World world, ContainerLocator locator, I accessInterface) {
|
||||
|
||||
if (accessInterface instanceof ICustomNameObject) {
|
||||
ICustomNameObject customNameObject = (ICustomNameObject) accessInterface;
|
||||
if (customNameObject.hasCustomInventoryName()) {
|
||||
return customNameObject.getCustomInventoryName();
|
||||
}
|
||||
}
|
||||
|
||||
// Use block name at position
|
||||
// FIXME: this is not right, we'd need to check the part's item stack, or custom
|
||||
// naming interface impl
|
||||
// FIXME: Should move this up, because at this point, it's hard to know where
|
||||
// the terminal host came from (part or tile)
|
||||
if (locator.hasBlockPos()) {
|
||||
return new TranslatableText(world.getBlockState(locator.getBlockPos()).getBlock().getTranslationKey());
|
||||
}
|
||||
|
||||
return new LiteralText("Unknown");
|
||||
|
||||
}
|
||||
|
||||
private I getHostFromLocator(PlayerEntity player, ContainerLocator locator) {
|
||||
if (locator.hasItemIndex()) {
|
||||
return getHostFromPlayerInventory(player, locator);
|
||||
@@ -225,6 +238,24 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
C create(int windowId, PlayerInventory playerInv, I accessObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy used to serialize initial data for opening the container on the
|
||||
* client-side into the packet that is sent to the client.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface InitialDataSerializer<I> {
|
||||
void serializeInitialData(I host, PacketByteBuf buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy used to deserialize initial data for opening the container on the
|
||||
* client-side from the packet received by the server.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface InitialDataDeserializer<C, I> {
|
||||
void deserializeInitialData(I host, C container, PacketByteBuf buffer);
|
||||
}
|
||||
|
||||
private boolean checkPermission(PlayerEntity player, Object accessInterface) {
|
||||
|
||||
if (requiredPermission != null) {
|
||||
@@ -235,4 +266,15 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
}
|
||||
|
||||
private Text getDefaultContainerTitle(I accessInterface) {
|
||||
if (accessInterface instanceof ICustomNameObject) {
|
||||
ICustomNameObject customNameObject = (ICustomNameObject) accessInterface;
|
||||
if (customNameObject.hasCustomInventoryName()) {
|
||||
return customNameObject.getCustomInventoryName();
|
||||
}
|
||||
}
|
||||
|
||||
return LiteralText.EMPTY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,14 +19,8 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
@@ -66,9 +60,8 @@ import appeng.me.helpers.PlayerSource;
|
||||
import appeng.parts.reporting.CraftingTerminalPart;
|
||||
import appeng.parts.reporting.PatternTerminalPart;
|
||||
import appeng.parts.reporting.TerminalPart;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CraftConfirmContainer extends AEBaseContainer {
|
||||
public class CraftConfirmContainer extends AEBaseContainer implements CraftingCPUCyclingContainer {
|
||||
|
||||
public static ScreenHandlerType<CraftConfirmContainer> TYPE;
|
||||
|
||||
@@ -83,98 +76,51 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
return helper.open(player, locator);
|
||||
}
|
||||
|
||||
private final ArrayList<CraftingCPURecord> cpus = new ArrayList<>();
|
||||
private final CraftingCPUCycler cpuCycler;
|
||||
|
||||
private ICraftingCPU selectedCpu;
|
||||
|
||||
private Future<ICraftingJob> job;
|
||||
private ICraftingJob result;
|
||||
@GuiSync(0)
|
||||
public long bytesUsed;
|
||||
@GuiSync(1)
|
||||
public long cpuBytesAvail;
|
||||
@GuiSync(2)
|
||||
public int cpuCoProcessors;
|
||||
@GuiSync(3)
|
||||
public boolean autoStart = false;
|
||||
@GuiSync(4)
|
||||
public boolean simulation = true;
|
||||
@GuiSync(5)
|
||||
public int selectedCpu = -1;
|
||||
|
||||
// Indicates whether any CPUs are available
|
||||
@GuiSync(6)
|
||||
public boolean noCPU = true;
|
||||
|
||||
// Properties of the currently selected crafting CPU, this can be null
|
||||
// if no CPUs are available, or if an automatic one is selected
|
||||
@GuiSync(1)
|
||||
public long cpuBytesAvail;
|
||||
@GuiSync(2)
|
||||
public int cpuCoProcessors;
|
||||
@GuiSync(7)
|
||||
public Text myName;
|
||||
public Text cpuName;
|
||||
|
||||
public CraftConfirmContainer(int id, PlayerInventory ip, ITerminalHost te) {
|
||||
super(TYPE, id, ip, te);
|
||||
this.cpuCycler = new CraftingCPUCycler(this::cpuMatches, this::onCPUSelectionChanged);
|
||||
// A player can select no crafting CPU to use a suitable one automatically
|
||||
this.cpuCycler.setAllowNoSelection(true);
|
||||
}
|
||||
|
||||
public void cycleCpu(final boolean next) {
|
||||
if (next) {
|
||||
this.setSelectedCpu(this.getSelectedCpu() + 1);
|
||||
} else {
|
||||
this.setSelectedCpu(this.getSelectedCpu() - 1);
|
||||
}
|
||||
|
||||
if (this.getSelectedCpu() < -1) {
|
||||
this.setSelectedCpu(this.cpus.size() - 1);
|
||||
} else if (this.getSelectedCpu() >= this.cpus.size()) {
|
||||
this.setSelectedCpu(-1);
|
||||
}
|
||||
|
||||
if (this.getSelectedCpu() == -1) {
|
||||
this.setCpuAvailableBytes(0);
|
||||
this.setCpuCoProcessors(0);
|
||||
this.setName(null);
|
||||
} else {
|
||||
CraftingCPURecord cpu = this.cpus.get(this.getSelectedCpu());
|
||||
this.setName(cpu.getName());
|
||||
this.setCpuAvailableBytes(cpu.getSize());
|
||||
this.setCpuCoProcessors(cpu.getProcessors());
|
||||
}
|
||||
@Override
|
||||
public void cycleSelectedCPU(final boolean next) {
|
||||
this.cpuCycler.cycleCpu(next);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
if (Platform.isClient()) {
|
||||
if (isClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class);
|
||||
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
|
||||
|
||||
int matches = 0;
|
||||
boolean changed = false;
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
boolean found = false;
|
||||
for (final CraftingCPURecord ccr : this.cpus) {
|
||||
if (ccr.getCpu() == c) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean matched = this.cpuMatches(c);
|
||||
|
||||
if (matched) {
|
||||
matches++;
|
||||
}
|
||||
|
||||
if (found == !matched) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed || this.cpus.size() != matches) {
|
||||
this.cpus.clear();
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
if (this.cpuMatches(c)) {
|
||||
this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c));
|
||||
}
|
||||
}
|
||||
|
||||
this.sendCPUs();
|
||||
}
|
||||
|
||||
this.setNoCPU(this.cpus.isEmpty());
|
||||
this.cpuCycler.detectAndSendChanges(this.getGrid());
|
||||
|
||||
super.sendContentUpdates();
|
||||
|
||||
@@ -277,22 +223,6 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
return c.getAvailableStorage() >= this.getUsedBytes() && !c.isBusy();
|
||||
}
|
||||
|
||||
private void sendCPUs() {
|
||||
Collections.sort(this.cpus);
|
||||
|
||||
if (this.getSelectedCpu() >= this.cpus.size()) {
|
||||
this.setSelectedCpu(-1);
|
||||
this.setCpuAvailableBytes(0);
|
||||
this.setCpuCoProcessors(0);
|
||||
this.setName(null);
|
||||
} else if (this.getSelectedCpu() != -1) {
|
||||
CraftingCPURecord cpu = this.cpus.get(this.getSelectedCpu());
|
||||
this.setName(cpu.getName());
|
||||
this.setCpuAvailableBytes(cpu.getSize());
|
||||
this.setCpuCoProcessors(cpu.getProcessors());
|
||||
}
|
||||
}
|
||||
|
||||
public void startJob() {
|
||||
ScreenHandlerType<?> originalGui = null;
|
||||
|
||||
@@ -315,9 +245,7 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
|
||||
if (this.result != null && !this.isSimulation()) {
|
||||
final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class);
|
||||
final ICraftingLink g = cc.submitJob(this.result, null,
|
||||
this.getSelectedCpu() == -1 ? null : this.cpus.get(this.getSelectedCpu()).getCpu(), true,
|
||||
this.getActionSrc());
|
||||
final ICraftingLink g = cc.submitJob(this.result, null, this.selectedCpu, true, this.getActionSrc());
|
||||
this.setAutoStart(false);
|
||||
if (g != null && originalGui != null && this.getLocator() != null) {
|
||||
ContainerOpener.openContainer(originalGui, getPlayerInventory().player, getLocator());
|
||||
@@ -347,6 +275,22 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private void onCPUSelectionChanged(CraftingCPURecord cpuRecord, boolean cpusAvailable) {
|
||||
noCPU = !cpusAvailable;
|
||||
|
||||
if (cpuRecord == null) {
|
||||
cpuBytesAvail = 0;
|
||||
cpuCoProcessors = 0;
|
||||
cpuName = null;
|
||||
selectedCpu = null;
|
||||
} else {
|
||||
cpuBytesAvail = cpuRecord.getSize();
|
||||
cpuCoProcessors = cpuRecord.getProcessors();
|
||||
cpuName = cpuRecord.getName();
|
||||
selectedCpu = cpuRecord.getCpu();
|
||||
}
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return this.getPlayerInv().player.world;
|
||||
}
|
||||
@@ -371,42 +315,18 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
return this.cpuBytesAvail;
|
||||
}
|
||||
|
||||
private void setCpuAvailableBytes(final long cpuBytesAvail) {
|
||||
this.cpuBytesAvail = cpuBytesAvail;
|
||||
}
|
||||
|
||||
public int getCpuCoProcessors() {
|
||||
return this.cpuCoProcessors;
|
||||
}
|
||||
|
||||
private void setCpuCoProcessors(final int cpuCoProcessors) {
|
||||
this.cpuCoProcessors = cpuCoProcessors;
|
||||
}
|
||||
|
||||
public int getSelectedCpu() {
|
||||
return this.selectedCpu;
|
||||
}
|
||||
|
||||
private void setSelectedCpu(final int selectedCpu) {
|
||||
this.selectedCpu = selectedCpu;
|
||||
}
|
||||
|
||||
public Text getName() {
|
||||
return this.myName;
|
||||
}
|
||||
|
||||
private void setName(@Nullable final Text myName) {
|
||||
this.myName = myName;
|
||||
return this.cpuName;
|
||||
}
|
||||
|
||||
public boolean hasNoCPU() {
|
||||
return this.noCPU;
|
||||
}
|
||||
|
||||
private void setNoCPU(final boolean noCPU) {
|
||||
this.noCPU = noCPU;
|
||||
}
|
||||
|
||||
public boolean isSimulation() {
|
||||
return this.simulation;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.screen.ScreenHandlerListener;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.LiteralText;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.networking.IGrid;
|
||||
@@ -46,24 +46,28 @@ import appeng.core.Api;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.core.sync.packets.MEInventoryUpdatePacket;
|
||||
import appeng.helpers.ICustomNameObject;
|
||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||
import appeng.tile.crafting.CraftingBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CraftingCPUContainer extends AEBaseContainer
|
||||
implements IMEMonitorHandlerReceiver<IAEItemStack>, ICustomNameObject {
|
||||
public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorHandlerReceiver<IAEItemStack> {
|
||||
|
||||
public static ScreenHandlerType<CraftingCPUContainer> TYPE;
|
||||
|
||||
private static final ContainerHelper<CraftingCPUContainer, CraftingBlockEntity> helper = new ContainerHelper<>(
|
||||
CraftingCPUContainer::new, CraftingBlockEntity.class, SecurityPermissions.CRAFT);
|
||||
CraftingCPUContainer::new, CraftingBlockEntity.class, SecurityPermissions.CRAFT)
|
||||
.withContainerTitle(craftingTileEntity -> {
|
||||
// Use the cluster's custom name instead of the right-clicked block entities one
|
||||
CraftingCPUCluster cluster = craftingTileEntity.getCluster();
|
||||
if (cluster != null && cluster.getName() != null) {
|
||||
return cluster.getName();
|
||||
}
|
||||
return LiteralText.EMPTY;
|
||||
});
|
||||
|
||||
private final IItemList<IAEItemStack> list = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
|
||||
.createList();
|
||||
private IGrid network;
|
||||
private final IGrid network;
|
||||
private CraftingCPUCluster monitor = null;
|
||||
private Text cpuName = null;
|
||||
|
||||
@GuiSync(0)
|
||||
public long eta = -1;
|
||||
@@ -77,14 +81,16 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
final IActionHost host = (IActionHost) (te instanceof IActionHost ? te : null);
|
||||
|
||||
if (host != null && host.getActionableNode() != null) {
|
||||
this.setNetwork(host.getActionableNode().getGrid());
|
||||
this.network = host.getActionableNode().getGrid();
|
||||
} else {
|
||||
this.network = null;
|
||||
}
|
||||
|
||||
if (te instanceof CraftingBlockEntity) {
|
||||
this.setCPU(((CraftingBlockEntity) te).getCluster());
|
||||
}
|
||||
|
||||
if (this.getNetwork() == null && Platform.isServer()) {
|
||||
if (this.getNetwork() == null && isServer()) {
|
||||
this.setValidContainer(false);
|
||||
}
|
||||
}
|
||||
@@ -114,15 +120,13 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
}
|
||||
|
||||
if (c instanceof CraftingCPUCluster) {
|
||||
this.cpuName = c.getName();
|
||||
this.setMonitor((CraftingCPUCluster) c);
|
||||
this.monitor = (CraftingCPUCluster) c;
|
||||
this.list.resetStatus();
|
||||
this.getMonitor().getListOfItem(this.list, CraftingItemList.ALL);
|
||||
this.getMonitor().addListener(this, null);
|
||||
this.setEstimatedTime(0);
|
||||
} else {
|
||||
this.setMonitor(null);
|
||||
this.cpuName = null;
|
||||
this.monitor = null;
|
||||
this.setEstimatedTime(-1);
|
||||
}
|
||||
}
|
||||
@@ -153,7 +157,7 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
if (Platform.isServer() && this.getMonitor() != null && !this.list.isEmpty()) {
|
||||
if (isServer() && this.getMonitor() != null && !this.list.isEmpty()) {
|
||||
try {
|
||||
if (this.getEstimatedTime() >= 0) {
|
||||
final long elapsedTime = this.getMonitor().getElapsedTime();
|
||||
@@ -218,16 +222,6 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getCustomInventoryName() {
|
||||
return this.cpuName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomInventoryName() {
|
||||
return this.cpuName != null;
|
||||
}
|
||||
|
||||
public long getEstimatedTime() {
|
||||
return this.eta;
|
||||
}
|
||||
@@ -240,15 +234,8 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
return this.monitor;
|
||||
}
|
||||
|
||||
private void setMonitor(final CraftingCPUCluster monitor) {
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
IGrid getNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
|
||||
private void setNetwork(final IGrid network) {
|
||||
this.network = network;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.text.LiteralText;
|
||||
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
|
||||
/**
|
||||
* Utility class for dialogs that can cycle through crafting CPUs
|
||||
*/
|
||||
class CraftingCPUCycler {
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ChangeListener {
|
||||
void onChange(CraftingCPURecord selectedCpu, boolean cpusAvailable);
|
||||
}
|
||||
|
||||
private final Predicate<ICraftingCPU> cpuFilter;
|
||||
private final ChangeListener changeListener;
|
||||
private final List<CraftingCPURecord> cpus = new ArrayList<>();
|
||||
private int selectedCpu = -1;
|
||||
private boolean initialDataSent = false;
|
||||
private boolean allowNoSelection;
|
||||
|
||||
public CraftingCPUCycler(Predicate<ICraftingCPU> cpuFilter, ChangeListener changeListener) {
|
||||
this.cpuFilter = cpuFilter;
|
||||
this.changeListener = changeListener;
|
||||
}
|
||||
|
||||
public void detectAndSendChanges(IGrid network) {
|
||||
final ICraftingGrid cc = network.getCache(ICraftingGrid.class);
|
||||
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
|
||||
|
||||
int matches = 0;
|
||||
boolean changed = !initialDataSent;
|
||||
initialDataSent = true;
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
boolean found = false;
|
||||
for (final CraftingCPURecord ccr : this.cpus) {
|
||||
if (ccr.getCpu() == c) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean matched = this.cpuFilter.test(c);
|
||||
|
||||
if (matched) {
|
||||
matches++;
|
||||
}
|
||||
|
||||
if (found == !matched) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed || this.cpus.size() != matches) {
|
||||
this.cpus.clear();
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
if (this.cpuFilter.test(c)) {
|
||||
this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c));
|
||||
}
|
||||
}
|
||||
|
||||
// Sort and assign numeric IDs in case they have no names
|
||||
Collections.sort(this.cpus);
|
||||
for (int i = 0; i < this.cpus.size(); i++) {
|
||||
CraftingCPURecord cpu = cpus.get(i);
|
||||
if (cpu.getName() == null) {
|
||||
cpu.setName(new LiteralText("#" + (i + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
this.notifyListener();
|
||||
}
|
||||
}
|
||||
|
||||
public void cycleCpu(final boolean next) {
|
||||
if (next) {
|
||||
this.selectedCpu++;
|
||||
} else {
|
||||
this.selectedCpu--;
|
||||
}
|
||||
|
||||
// If "no CPU" is a valid selection, then -1 is the first potential item
|
||||
int lowerLimit = this.allowNoSelection ? -1 : 0;
|
||||
|
||||
if (this.selectedCpu < lowerLimit) {
|
||||
this.selectedCpu = this.cpus.size() - 1;
|
||||
} else if (this.selectedCpu >= this.cpus.size()) {
|
||||
this.selectedCpu = lowerLimit;
|
||||
}
|
||||
|
||||
this.notifyListener();
|
||||
}
|
||||
|
||||
public boolean isAllowNoSelection() {
|
||||
return allowNoSelection;
|
||||
}
|
||||
|
||||
public void setAllowNoSelection(boolean allowNoSelection) {
|
||||
this.allowNoSelection = allowNoSelection;
|
||||
}
|
||||
|
||||
private void notifyListener() {
|
||||
if (this.selectedCpu >= this.cpus.size()) {
|
||||
this.selectedCpu = -1;
|
||||
}
|
||||
|
||||
// Force the selected CPU to the first available CPU unless no-selection is
|
||||
// explicitly allowed
|
||||
if (!this.allowNoSelection && this.selectedCpu == -1 && !this.cpus.isEmpty()) {
|
||||
this.selectedCpu = 0;
|
||||
}
|
||||
|
||||
if (this.selectedCpu != -1) {
|
||||
this.changeListener.onChange(this.cpus.get(this.selectedCpu), true);
|
||||
} else {
|
||||
this.changeListener.onChange(null, !this.cpus.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
/**
|
||||
* Implemented on screens that show information about a crafting CPU and allow
|
||||
* the CPU to be cycled. Is triggered by receiving a config value packet with
|
||||
* name <code>Terminal.Cpu</code>.
|
||||
*/
|
||||
public interface CraftingCPUCyclingContainer {
|
||||
|
||||
void cycleSelectedCPU(boolean forward);
|
||||
|
||||
}
|
||||
@@ -25,16 +25,16 @@ import net.minecraft.text.Text;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
|
||||
public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
|
||||
private final Text myName;
|
||||
private final ICraftingCPU cpu;
|
||||
private final long size;
|
||||
private final int processors;
|
||||
private Text name;
|
||||
|
||||
public CraftingCPURecord(final long size, final int coProcessors, final ICraftingCPU server) {
|
||||
this.size = size;
|
||||
this.processors = coProcessors;
|
||||
this.cpu = server;
|
||||
this.myName = server.getName();
|
||||
this.name = server.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,10 +50,6 @@ public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
|
||||
return this.cpu;
|
||||
}
|
||||
|
||||
Text getName() {
|
||||
return this.myName;
|
||||
}
|
||||
|
||||
int getProcessors() {
|
||||
return this.processors;
|
||||
}
|
||||
@@ -61,4 +57,13 @@ public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
|
||||
long getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public Text getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(Text name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,12 +18,6 @@
|
||||
|
||||
package appeng.container.implementations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
@@ -31,14 +25,13 @@ import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.storage.ITerminalHost;
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CraftingStatusContainer extends CraftingCPUContainer {
|
||||
public class CraftingStatusContainer extends CraftingCPUContainer implements CraftingCPUCyclingContainer {
|
||||
|
||||
public static ScreenHandlerType<CraftingStatusContainer> TYPE;
|
||||
|
||||
@@ -53,13 +46,13 @@ public class CraftingStatusContainer extends CraftingCPUContainer {
|
||||
return helper.open(player, locator);
|
||||
}
|
||||
|
||||
private final List<CraftingCPURecord> cpus = new ArrayList<>();
|
||||
@GuiSync(5)
|
||||
public int selectedCpu = -1;
|
||||
private final CraftingCPUCycler cpuCycler = new CraftingCPUCycler(this::cpuMatches, this::onCPUSelectionChanged);
|
||||
|
||||
@GuiSync(6)
|
||||
public boolean noCPU = true;
|
||||
|
||||
@GuiSync(7)
|
||||
public Text myName;
|
||||
public Text cpuName;
|
||||
|
||||
public CraftingStatusContainer(int id, final PlayerInventory ip, final ITerminalHost te) {
|
||||
super(TYPE, id, ip, te);
|
||||
@@ -67,43 +60,9 @@ public class CraftingStatusContainer extends CraftingCPUContainer {
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
if (Platform.isServer() && this.getNetwork() != null) {
|
||||
final ICraftingGrid cc = this.getNetwork().getCache(ICraftingGrid.class);
|
||||
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
|
||||
|
||||
int matches = 0;
|
||||
boolean changed = false;
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
boolean found = false;
|
||||
for (final CraftingCPURecord ccr : this.cpus) {
|
||||
if (ccr.getCpu() == c) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean matched = this.cpuMatches(c);
|
||||
|
||||
if (matched) {
|
||||
matches++;
|
||||
}
|
||||
|
||||
if (found == !matched) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed || this.cpus.size() != matches) {
|
||||
this.cpus.clear();
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
if (this.cpuMatches(c)) {
|
||||
this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c));
|
||||
}
|
||||
}
|
||||
|
||||
this.sendCPUs();
|
||||
}
|
||||
|
||||
this.noCPU = this.cpus.isEmpty();
|
||||
IGrid network = this.getNetwork();
|
||||
if (isServer() && network != null) {
|
||||
cpuCycler.detectAndSendChanges(network);
|
||||
}
|
||||
|
||||
super.sendContentUpdates();
|
||||
@@ -113,52 +72,20 @@ public class CraftingStatusContainer extends CraftingCPUContainer {
|
||||
return c.isBusy();
|
||||
}
|
||||
|
||||
private void sendCPUs() {
|
||||
Collections.sort(this.cpus);
|
||||
|
||||
if (this.selectedCpu >= this.cpus.size()) {
|
||||
this.selectedCpu = -1;
|
||||
this.myName = null;
|
||||
} else if (this.selectedCpu != -1) {
|
||||
this.myName = this.cpus.get(this.selectedCpu).getName();
|
||||
}
|
||||
|
||||
if (this.selectedCpu == -1 && this.cpus.size() > 0) {
|
||||
this.selectedCpu = 0;
|
||||
}
|
||||
|
||||
if (this.selectedCpu != -1) {
|
||||
if (this.cpus.get(this.selectedCpu).getCpu() != this.getMonitor()) {
|
||||
this.setCPU(this.cpus.get(this.selectedCpu).getCpu());
|
||||
}
|
||||
private void onCPUSelectionChanged(CraftingCPURecord cpuRecord, boolean cpusAvailable) {
|
||||
noCPU = !cpusAvailable;
|
||||
if (cpuRecord == null) {
|
||||
cpuName = null;
|
||||
setCPU(null);
|
||||
} else {
|
||||
this.setCPU(null);
|
||||
cpuName = cpuRecord.getName();
|
||||
setCPU(cpuRecord.getCpu());
|
||||
}
|
||||
}
|
||||
|
||||
public void cycleCpu(final boolean next) {
|
||||
if (next) {
|
||||
this.selectedCpu++;
|
||||
} else {
|
||||
this.selectedCpu--;
|
||||
}
|
||||
|
||||
if (this.selectedCpu < -1) {
|
||||
this.selectedCpu = this.cpus.size() - 1;
|
||||
} else if (this.selectedCpu >= this.cpus.size()) {
|
||||
this.selectedCpu = -1;
|
||||
}
|
||||
|
||||
if (this.selectedCpu == -1 && this.cpus.size() > 0) {
|
||||
this.selectedCpu = 0;
|
||||
}
|
||||
|
||||
if (this.selectedCpu == -1) {
|
||||
this.myName = null;
|
||||
this.setCPU(null);
|
||||
} else {
|
||||
this.myName = this.cpus.get(this.selectedCpu).getName();
|
||||
this.setCPU(this.cpus.get(this.selectedCpu).getCpu());
|
||||
}
|
||||
@Override
|
||||
public void cycleSelectedCPU(boolean forward) {
|
||||
this.cpuCycler.cycleCpu(forward);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ import appeng.container.slot.FakeTypeOnlySlot;
|
||||
import appeng.container.slot.OptionalTypeOnlyFakeSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.parts.automation.FormationPlanePart;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class FormationPlaneContainer extends UpgradeableContainer {
|
||||
|
||||
@@ -108,7 +107,7 @@ public class FormationPlaneContainer extends UpgradeableContainer {
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
|
||||
this.setPlaceMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.PLACE_BLOCK));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.storage.IOPortBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class IOPortContainer extends UpgradeableContainer {
|
||||
|
||||
@@ -112,7 +111,7 @@ public class IOPortContainer extends UpgradeableContainer {
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setOperationMode(
|
||||
(OperationMode) this.getUpgradeable().getConfigManager().getSetting(Settings.OPERATION_MODE));
|
||||
this.setFullMode(
|
||||
|
||||
@@ -36,7 +36,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.tile.misc.InscriberBlockEntity;
|
||||
import appeng.tile.misc.InscriberRecipes;
|
||||
import appeng.util.Platform;
|
||||
|
||||
/**
|
||||
* @author AlgorithmX2
|
||||
@@ -120,7 +119,7 @@ public class InscriberContainer extends UpgradeableContainer implements IProgres
|
||||
public void sendContentUpdates() {
|
||||
this.standardDetectAndSendChanges();
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.maxProcessingTime = this.ti.getMaxProcessingTime();
|
||||
this.processingTime = this.ti.getProcessingTime();
|
||||
}
|
||||
|
||||
@@ -55,7 +55,6 @@ import appeng.parts.reporting.InterfaceTerminalPart;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.tile.misc.InterfaceBlockEntity;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.inv.AdaptorFixedInv;
|
||||
import appeng.util.inv.WrapperCursorItemHandler;
|
||||
@@ -88,7 +87,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
public InterfaceTerminalContainer(int id, final PlayerInventory ip, final InterfaceTerminalPart anchor) {
|
||||
super(TYPE, id, ip, anchor);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.grid = anchor.getActionableNode().getGrid();
|
||||
}
|
||||
|
||||
@@ -97,7 +96,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
if (Platform.isClient()) {
|
||||
if (isClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
package appeng.container.implementations;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
@@ -33,13 +31,13 @@ import appeng.api.config.RedstoneMode;
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.client.gui.implementations.NumberEntryWidget;
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.FakeTypeOnlySlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.parts.automation.LevelEmitterPart;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
|
||||
@@ -49,38 +47,46 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
LevelEmitterContainer::new, LevelEmitterPart.class, SecurityPermissions.BUILD);
|
||||
|
||||
public static LevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketByteBuf buf) {
|
||||
return helper.fromNetwork(windowId, inv, buf);
|
||||
return helper.fromNetwork(windowId, inv, buf, (host, container, buffer) -> {
|
||||
container.reportingValue = buffer.readVarLong();
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean open(PlayerEntity player, ContainerLocator locator) {
|
||||
return helper.open(player, locator);
|
||||
return helper.open(player, locator, (host, buffer) -> {
|
||||
buffer.writeVarLong(host.getReportingValue());
|
||||
});
|
||||
}
|
||||
|
||||
private final LevelEmitterPart lvlEmitter;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
private NumberEntryWidget textField;
|
||||
@GuiSync(2)
|
||||
public LevelType lvType;
|
||||
@GuiSync(3)
|
||||
public long EmitterValue = -1;
|
||||
@GuiSync(4)
|
||||
public YesNo cmType;
|
||||
|
||||
// Only synced once on container-open, and only used on client
|
||||
private long reportingValue;
|
||||
|
||||
public LevelEmitterContainer(int id, final PlayerInventory ip, final LevelEmitterPart te) {
|
||||
super(TYPE, id, ip, te);
|
||||
this.lvlEmitter = te;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void setTextField(final NumberEntryWidget level) {
|
||||
this.textField = level;
|
||||
this.textField.setValue(this.EmitterValue);
|
||||
public long getReportingValue() {
|
||||
return reportingValue;
|
||||
}
|
||||
|
||||
public void setLevel(final long l, final PlayerEntity player) {
|
||||
this.lvlEmitter.setReportingValue(l);
|
||||
this.EmitterValue = l;
|
||||
public void setReportingValue(long reportingValue) {
|
||||
if (isClient()) {
|
||||
if (reportingValue != this.reportingValue) {
|
||||
this.reportingValue = reportingValue;
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(reportingValue)));
|
||||
}
|
||||
} else {
|
||||
this.lvlEmitter.setReportingValue(reportingValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,7 +122,6 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
|
||||
@Override
|
||||
public int availableUpgrades() {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -124,8 +129,7 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
this.EmitterValue = this.lvlEmitter.getReportingValue();
|
||||
if (isServer()) {
|
||||
this.setCraftingMode(
|
||||
(YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.CRAFT_VIA_REDSTONE));
|
||||
this.setLevelMode((LevelType) this.getUpgradeable().getConfigManager().getSetting(Settings.LEVEL_TYPE));
|
||||
@@ -137,15 +141,6 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
this.standardDetectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
|
||||
if (field.equals("EmitterValue")) {
|
||||
if (this.textField != null) {
|
||||
this.textField.setValue(this.EmitterValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public YesNo getCraftingMode() {
|
||||
return this.cmType;
|
||||
@@ -163,4 +158,5 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
private void setLevelMode(final LevelType lvType) {
|
||||
this.lvType = lvType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ import appeng.api.implementations.tiles.IViewCellStorage;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.energy.IEnergyGrid;
|
||||
import appeng.api.networking.energy.IEnergySource;
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
@@ -73,7 +75,6 @@ import appeng.core.sync.packets.MEInventoryUpdatePacket;
|
||||
import appeng.me.helpers.ChannelPowerSrc;
|
||||
import appeng.util.ConfigManager;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class MEMonitorableContainer extends AEBaseContainer
|
||||
implements IConfigManagerHost, IConfigurableObject, IMEMonitorHandlerReceiver<IAEItemStack> {
|
||||
@@ -101,6 +102,13 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
public boolean canAccessViewCells = false;
|
||||
@GuiSync(98)
|
||||
public boolean hasPower = false;
|
||||
/**
|
||||
* The number of active crafting jobs in the network. -1 means unknown and will
|
||||
* hide the label on the screen.
|
||||
*/
|
||||
@GuiSync(100)
|
||||
public int activeCraftingJobs = -1;
|
||||
|
||||
private IConfigManagerHost gui;
|
||||
private IConfigManager serverCM;
|
||||
private IGridNode networkNode;
|
||||
@@ -122,7 +130,7 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL);
|
||||
this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.serverCM = monitorable.getConfigManager();
|
||||
|
||||
this.monitor = monitorable
|
||||
@@ -183,12 +191,14 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (this.monitor != this.host
|
||||
.getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class))) {
|
||||
this.setValidContainer(false);
|
||||
}
|
||||
|
||||
this.updateActiveCraftingJobs();
|
||||
|
||||
for (final Settings set : this.serverCM.getSettings()) {
|
||||
final Enum<?> sideLocal = this.serverCM.getSetting(set);
|
||||
final Enum<?> sideRemote = this.clientCM.getSetting(set);
|
||||
@@ -286,8 +296,38 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
this.queueInventory(c);
|
||||
}
|
||||
|
||||
private void updateActiveCraftingJobs() {
|
||||
IGridNode hostNode = networkNode;
|
||||
if (hostNode == null) {
|
||||
// Wireless terminals do not directly expose the target grid (even though they
|
||||
// have one)
|
||||
if (host instanceof IActionHost) {
|
||||
hostNode = ((IActionHost) host).getActionableNode();
|
||||
}
|
||||
}
|
||||
IGrid grid = null;
|
||||
if (hostNode != null) {
|
||||
grid = hostNode.getGrid();
|
||||
}
|
||||
|
||||
if (grid == null) {
|
||||
// No grid to query crafting jobs from
|
||||
this.activeCraftingJobs = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
int activeJobs = 0;
|
||||
ICraftingGrid craftingGrid = grid.getCache(ICraftingGrid.class);
|
||||
for (ICraftingCPU cpus : craftingGrid.getCpus()) {
|
||||
if (cpus.isBusy()) {
|
||||
activeJobs++;
|
||||
}
|
||||
}
|
||||
this.activeCraftingJobs = activeJobs;
|
||||
}
|
||||
|
||||
private void queueInventory(final ScreenHandlerListener c) {
|
||||
if (Platform.isServer() && c instanceof PlayerEntity && this.monitor != null) {
|
||||
if (isServer() && c instanceof PlayerEntity && this.monitor != null) {
|
||||
try {
|
||||
MEInventoryUpdatePacket piu = new MEInventoryUpdatePacket();
|
||||
final IItemList<IAEItemStack> monitorCache = this.monitor.getStorageList();
|
||||
@@ -356,7 +396,7 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
|
||||
@Override
|
||||
public IConfigManager getConfigManager() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
return this.serverCM;
|
||||
}
|
||||
return this.clientCM;
|
||||
|
||||
@@ -42,7 +42,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.items.misc.EncodedPatternItem;
|
||||
import appeng.tile.crafting.MolecularAssemblerBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class MolecularAssemblerContainer extends UpgradeableContainer implements IProgressProvider {
|
||||
|
||||
@@ -148,7 +147,7 @@ public class MolecularAssemblerContainer extends UpgradeableContainer implements
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setRedStoneMode(
|
||||
(RedstoneMode) this.getUpgradeable().getConfigManager().getSetting(Settings.REDSTONE_CONTROLLED));
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.MEInventoryUpdatePacket;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
|
||||
public class NetworkStatusContainer extends AEBaseContainer {
|
||||
@@ -83,7 +82,7 @@ public class NetworkStatusContainer extends AEBaseContainer {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.network == null && Platform.isServer()) {
|
||||
if (this.network == null && isServer()) {
|
||||
this.setValidContainer(false);
|
||||
}
|
||||
}
|
||||
@@ -100,7 +99,7 @@ public class NetworkStatusContainer extends AEBaseContainer {
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
this.delay++;
|
||||
if (Platform.isServer() && this.delay > 15 && this.network != null) {
|
||||
if (isServer() && this.delay > 15 && this.network != null) {
|
||||
this.delay = 0;
|
||||
|
||||
final IEnergyGrid eg = this.network.getCache(IEnergyGrid.class);
|
||||
|
||||
@@ -297,9 +297,9 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
@Override
|
||||
public boolean isSlotEnabled(final int idx) {
|
||||
if (idx == 1) {
|
||||
return Platform.isServer() ? !this.getPatternTerminal().isCraftingRecipe() : !this.isCraftingMode();
|
||||
return isServer() ? !this.getPatternTerminal().isCraftingRecipe() : !this.isCraftingMode();
|
||||
} else if (idx == 2) {
|
||||
return Platform.isServer() ? this.getPatternTerminal().isCraftingRecipe() : this.isCraftingMode();
|
||||
return isServer() ? this.getPatternTerminal().isCraftingRecipe() : this.isCraftingMode();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -401,7 +401,7 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
super.sendContentUpdates();
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (this.isCraftingMode() != this.getPatternTerminal().isCraftingRecipe()) {
|
||||
this.setCraftingMode(this.getPatternTerminal().isCraftingRecipe());
|
||||
this.updateOrderOfOutputSlots();
|
||||
@@ -423,7 +423,7 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
|
||||
@Override
|
||||
public void onSlotChange(final Slot s) {
|
||||
if (s == this.patternSlotOUT && Platform.isServer()) {
|
||||
if (s == this.patternSlotOUT && isServer()) {
|
||||
for (final ScreenHandlerListener listener : this.getListeners()) {
|
||||
for (int i = 0; i < this.slots.size(); i++) {
|
||||
Slot slot = this.slots.get(i);
|
||||
@@ -438,7 +438,7 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
this.sendContentUpdates();
|
||||
}
|
||||
|
||||
if (s == this.craftSlot && Platform.isClient()) {
|
||||
if (s == this.craftSlot && isClient()) {
|
||||
this.getAndUpdateOutput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
package appeng.container.implementations;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
@@ -28,12 +26,11 @@ import net.minecraft.screen.ScreenHandlerType;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.client.gui.implementations.NumberEntryWidget;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class PriorityContainer extends AEBaseContainer {
|
||||
|
||||
@@ -43,59 +40,53 @@ public class PriorityContainer extends AEBaseContainer {
|
||||
PriorityContainer::new, IPriorityHost.class, SecurityPermissions.BUILD);
|
||||
|
||||
public static PriorityContainer fromNetwork(int windowId, PlayerInventory inv, PacketByteBuf buf) {
|
||||
return helper.fromNetwork(windowId, inv, buf);
|
||||
return helper.fromNetwork(windowId, inv, buf, (host, container, buffer) -> {
|
||||
container.priorityValue = buffer.readVarInt();
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean open(PlayerEntity player, ContainerLocator locator) {
|
||||
return helper.open(player, locator);
|
||||
return helper.open(player, locator, (host, buffer) -> buffer.writeVarInt(host.getPriority()));
|
||||
}
|
||||
|
||||
private final IPriorityHost priHost;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
private NumberEntryWidget textField;
|
||||
@GuiSync(2)
|
||||
public long PriorityValue = -1;
|
||||
private int priorityValue;
|
||||
|
||||
public PriorityContainer(int id, final PlayerInventory ip, final IPriorityHost te) {
|
||||
super(TYPE, id, ip, (BlockEntity) (te instanceof BlockEntity ? te : null),
|
||||
(IPart) (te instanceof IPart ? te : null));
|
||||
this.priHost = te;
|
||||
this.priorityValue = te.getPriority();
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void setTextField(final NumberEntryWidget level) {
|
||||
this.textField = level;
|
||||
this.textField.setValue(this.PriorityValue, true);
|
||||
}
|
||||
|
||||
public void setPriority(final int newValue, final PlayerEntity player) {
|
||||
this.priHost.setPriority(newValue);
|
||||
this.PriorityValue = newValue;
|
||||
public void setPriority(final int newValue) {
|
||||
if (newValue != priorityValue) {
|
||||
if (isClient()) {
|
||||
// If for whatever reason the client enters the value first, do not update based
|
||||
// on incoming server data
|
||||
this.priorityValue = newValue;
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(newValue)));
|
||||
} else {
|
||||
this.priHost.setPriority(newValue);
|
||||
this.priorityValue = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
super.sendContentUpdates();
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
this.PriorityValue = this.priHost.getPriority();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
|
||||
if (field.equals("PriorityValue")) {
|
||||
if (this.textField != null) {
|
||||
this.textField.setValue(this.PriorityValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
super.onUpdate(field, oldValue, newValue);
|
||||
public int getPriorityValue() {
|
||||
return priorityValue;
|
||||
}
|
||||
|
||||
public IPriorityHost getPriorityHost() {
|
||||
return this.priHost;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import appeng.core.Api;
|
||||
import appeng.items.contents.QuartzKnifeObj;
|
||||
import appeng.items.materials.MaterialItem;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class QuartzKnifeContainer extends AEBaseContainer {
|
||||
|
||||
@@ -142,7 +141,7 @@ public class QuartzKnifeContainer extends AEBaseContainer {
|
||||
}
|
||||
|
||||
private void makePlate() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (!inSlot.getSlot(0).extract(1).isEmpty()) {
|
||||
final ItemStack item = QuartzKnifeContainer.this.toolInv.getItemStack();
|
||||
final ItemStack before = item.copy();
|
||||
|
||||
@@ -35,7 +35,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.spatial.SpatialIOPortBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class SpatialIOPortContainer extends AEBaseContainer {
|
||||
|
||||
@@ -65,7 +64,7 @@ public class SpatialIOPortContainer extends AEBaseContainer {
|
||||
public SpatialIOPortContainer(int id, final PlayerInventory ip, final SpatialIOPortBlockEntity spatialIOPort) {
|
||||
super(TYPE, id, ip, spatialIOPort, null);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.network = spatialIOPort.getGridNode(AEPartLocation.INTERNAL).getGrid();
|
||||
}
|
||||
|
||||
@@ -89,7 +88,7 @@ public class SpatialIOPortContainer extends AEBaseContainer {
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.delay++;
|
||||
if (this.delay > 15 && this.network != null) {
|
||||
this.delay = 0;
|
||||
|
||||
@@ -45,7 +45,6 @@ import appeng.container.slot.OptionalTypeOnlyFakeSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.parts.misc.StorageBusPart;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
|
||||
@@ -125,7 +124,7 @@ public class StorageBusContainer extends UpgradeableContainer {
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
|
||||
this.setReadWriteMode(
|
||||
(AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS));
|
||||
|
||||
@@ -52,7 +52,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.items.contents.NetworkToolViewer;
|
||||
import appeng.items.tools.NetworkToolItem;
|
||||
import appeng.parts.automation.ExportBusPart;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class UpgradeableContainer extends AEBaseContainer implements IOptionalSlotHost {
|
||||
|
||||
@@ -200,7 +199,7 @@ public class UpgradeableContainer extends AEBaseContainer implements IOptionalSl
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
final IConfigManager cm = this.getUpgradeable().getConfigManager();
|
||||
this.loadSettingsFromHost(cm);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.interfaces.IProgressProvider;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.misc.VibrationChamberBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class VibrationChamberContainer extends AEBaseContainer implements IProgressProvider {
|
||||
|
||||
@@ -65,7 +64,7 @@ public class VibrationChamberContainer extends AEBaseContainer implements IProgr
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.remainingBurnTime = this.vibrationChamber.getMaxBurnTime() <= 0 ? 0
|
||||
: (int) (100.0 * this.vibrationChamber.getBurnTime() / this.vibrationChamber.getMaxBurnTime());
|
||||
this.burnSpeed = this.remainingBurnTime <= 0 ? 0 : this.vibrationChamber.getBurnSpeed();
|
||||
|
||||
@@ -28,7 +28,6 @@ import appeng.container.ContainerLocator;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.localization.PlayerMessages;
|
||||
import appeng.helpers.WirelessTerminalGuiObject;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class WirelessTermContainer extends MEPortableCellContainer {
|
||||
|
||||
@@ -57,7 +56,7 @@ public class WirelessTermContainer extends MEPortableCellContainer {
|
||||
super.sendContentUpdates();
|
||||
|
||||
if (!this.wirelessTerminalGUIObject.rangeCheck()) {
|
||||
if (Platform.isServer() && this.isValidContainer()) {
|
||||
if (isServer() && this.isValidContainer()) {
|
||||
this.getPlayerInv().player.sendSystemMessage(PlayerMessages.OutOfRange.get(), Util.NIL_UUID);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import appeng.core.sync.network.INetworkInfo;
|
||||
public abstract class BasePacket {
|
||||
|
||||
/**
|
||||
* Sadly {@link PacketBuffer#readString()} gets inlined by Proguard which means
|
||||
* Sadly {@link PacketByteBuf#readString()} gets inlined by Proguard which means
|
||||
* it's not available on the Server. This field has the default string length
|
||||
* that is used for writeString, which then also should be used for readString
|
||||
* when it has no special length requirements.
|
||||
|
||||
@@ -37,7 +37,7 @@ import appeng.container.AEBaseContainer;
|
||||
import appeng.container.implementations.CellWorkbenchContainer;
|
||||
import appeng.container.implementations.CraftConfirmContainer;
|
||||
import appeng.container.implementations.CraftingCPUContainer;
|
||||
import appeng.container.implementations.CraftingStatusContainer;
|
||||
import appeng.container.implementations.CraftingCPUCyclingContainer;
|
||||
import appeng.container.implementations.LevelEmitterContainer;
|
||||
import appeng.container.implementations.NetworkToolContainer;
|
||||
import appeng.container.implementations.PatternTermContainer;
|
||||
@@ -97,12 +97,9 @@ public class ConfigValuePacket extends BasePacket {
|
||||
final ItemStack is = player.getStackInHand(hand);
|
||||
final IMouseWheelItem si = (IMouseWheelItem) is.getItem();
|
||||
si.onWheel(is, this.Value.equals("WheelUp"));
|
||||
} else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftingStatusContainer) {
|
||||
final CraftingStatusContainer qk = (CraftingStatusContainer) c;
|
||||
qk.cycleCpu(this.Value.equals("Next"));
|
||||
} else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftConfirmContainer) {
|
||||
final CraftConfirmContainer qk = (CraftConfirmContainer) c;
|
||||
qk.cycleCpu(this.Value.equals("Next"));
|
||||
} else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftingCPUCyclingContainer) {
|
||||
final CraftingCPUCyclingContainer qk = (CraftingCPUCyclingContainer) c;
|
||||
qk.cycleSelectedCPU(this.Value.equals("Next"));
|
||||
} else if (this.Name.equals("Terminal.Start") && c instanceof CraftConfirmContainer) {
|
||||
final CraftConfirmContainer qk = (CraftConfirmContainer) c;
|
||||
qk.startJob();
|
||||
@@ -117,13 +114,13 @@ public class ConfigValuePacket extends BasePacket {
|
||||
sc.toggleSetting(this.Value, player);
|
||||
} else if (this.Name.equals("PriorityHost.Priority") && c instanceof PriorityContainer) {
|
||||
final PriorityContainer pc = (PriorityContainer) c;
|
||||
pc.setPriority(Integer.parseInt(this.Value), player);
|
||||
pc.setPriority(Integer.parseInt(this.Value));
|
||||
} else if (this.Name.equals("LevelEmitter.Value") && c instanceof LevelEmitterContainer) {
|
||||
final LevelEmitterContainer lvc = (LevelEmitterContainer) c;
|
||||
lvc.setLevel(Long.parseLong(this.Value), player);
|
||||
lvc.setReportingValue(Long.parseLong(this.Value));
|
||||
} else if (this.Name.equals("FluidLevelEmitter.Value") && c instanceof FluidLevelEmitterContainer) {
|
||||
final FluidLevelEmitterContainer lvc = (FluidLevelEmitterContainer) c;
|
||||
lvc.setLevel(Long.parseLong(this.Value), player);
|
||||
lvc.setReportingValue(Long.parseLong(this.Value));
|
||||
} else if (this.Name.startsWith("PatternTerminal.") && c instanceof PatternTermContainer) {
|
||||
final PatternTermContainer cpt = (PatternTermContainer) c;
|
||||
if (this.Name.equals("PatternTerminal.CraftMode")) {
|
||||
@@ -191,9 +188,7 @@ public class ConfigValuePacket extends BasePacket {
|
||||
public void clientPacketData(final INetworkInfo network, final PlayerEntity player) {
|
||||
final ScreenHandler c = player.currentScreenHandler;
|
||||
|
||||
if (this.Name.equals("CustomName") && c instanceof AEBaseContainer) {
|
||||
((AEBaseContainer) c).setCustomName(this.Value);
|
||||
} else if (this.Name.startsWith("SyncDat.")) {
|
||||
if (this.Name.startsWith("SyncDat.")) {
|
||||
((AEBaseContainer) c).stringSync(Integer.parseInt(this.Name.substring(8)), this.Value);
|
||||
} else if (this.Name.equals("CraftingStatus") && this.Value.equals("Clear")) {
|
||||
final Screen gs = MinecraftClient.getInstance().currentScreen;
|
||||
|
||||
@@ -11,8 +11,6 @@ import appeng.client.gui.implementations.NumberEntryWidget;
|
||||
import appeng.client.gui.implementations.UpgradeableScreen;
|
||||
import appeng.client.gui.widgets.ServerSettingToggleButton;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.fluids.client.gui.widgets.FluidSlotWidget;
|
||||
import appeng.fluids.container.FluidLevelEmitterContainer;
|
||||
|
||||
@@ -28,17 +26,24 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_FLUID_VOLUME,
|
||||
this::onLevelChange);
|
||||
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_FLUID_VOLUME);
|
||||
this.level.setTextFieldBounds(25, 44, 75);
|
||||
handler.setTextField(this.level);
|
||||
this.level.addButtons(children::add, this::addButton);
|
||||
this.level.setValue(handler.getReportingValue());
|
||||
this.level.setOnChange(this::saveReportingValue);
|
||||
this.level.setOnConfirm(this::onClose);
|
||||
|
||||
this.changeFocus(true);
|
||||
|
||||
final int y = 40;
|
||||
final int x = 80 + 57;
|
||||
this.guiSlots.add(new FluidSlotWidget(this.handler.getFluidConfigInventory(), 0, 0, x, y));
|
||||
}
|
||||
|
||||
private void saveReportingValue() {
|
||||
this.level.getLongValue().ifPresent(handler::setReportingValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addButtons() {
|
||||
this.redstoneMode = new ServerSettingToggleButton<>(this.x - 18, this.y + 28, Settings.REDSTONE_EMITTER,
|
||||
@@ -79,8 +84,4 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
|
||||
protected void handleButtonVisibility() {
|
||||
}
|
||||
|
||||
private void onLevelChange(long level) {
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("FluidLevelEmitter.Value", String.valueOf(level)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import appeng.container.implementations.UpgradeableContainer;
|
||||
import appeng.fluids.helper.FluidSyncHelper;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public abstract class FluidConfigurableContainer extends UpgradeableContainer implements IFluidSyncContainer {
|
||||
private FluidSyncHelper sync = null;
|
||||
@@ -76,7 +75,7 @@ public abstract class FluidConfigurableContainer extends UpgradeableContainer im
|
||||
|
||||
@Override
|
||||
protected void standardDetectAndSendChanges() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.getSyncHelper().sendDiff(this.getListeners());
|
||||
|
||||
// clear out config items that are no longer valid (eg capacity upgrade removed)
|
||||
|
||||
@@ -36,7 +36,6 @@ import appeng.fluids.helper.DualityFluidInterface;
|
||||
import appeng.fluids.helper.FluidSyncHelper;
|
||||
import appeng.fluids.helper.IFluidInterfaceHost;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class FluidInterfaceContainer extends FluidConfigurableContainer {
|
||||
|
||||
@@ -81,7 +80,7 @@ public class FluidInterfaceContainer extends FluidConfigurableContainer {
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.tankSync.sendDiff(this.getListeners());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package appeng.fluids.container;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
@@ -10,13 +8,12 @@ import net.minecraft.screen.ScreenHandlerType;
|
||||
import appeng.api.config.RedstoneMode;
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.client.gui.implementations.NumberEntryWidget;
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.implementations.ContainerHelper;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.fluids.parts.FluidLevelEmitterPart;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
|
||||
public static ScreenHandlerType<FluidLevelEmitterContainer> TYPE;
|
||||
@@ -25,34 +22,41 @@ public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
|
||||
FluidLevelEmitterContainer::new, FluidLevelEmitterPart.class, SecurityPermissions.BUILD);
|
||||
|
||||
public static FluidLevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketByteBuf buf) {
|
||||
return helper.fromNetwork(windowId, inv, buf);
|
||||
return helper.fromNetwork(windowId, inv, buf, (host, container, buffer) -> {
|
||||
container.reportingValue = buffer.readVarLong();
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean open(PlayerEntity player, ContainerLocator locator) {
|
||||
return helper.open(player, locator);
|
||||
return helper.open(player, locator, (host, buffer) -> {
|
||||
buffer.writeVarLong(host.getReportingValue());
|
||||
});
|
||||
}
|
||||
|
||||
private final FluidLevelEmitterPart lvlEmitter;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
private NumberEntryWidget textField;
|
||||
@GuiSync(3)
|
||||
public long EmitterValue = -1;
|
||||
// Only synced once on container-open, and only used on client
|
||||
private long reportingValue;
|
||||
|
||||
public FluidLevelEmitterContainer(int id, final PlayerInventory ip, final FluidLevelEmitterPart te) {
|
||||
super(TYPE, id, ip, te);
|
||||
this.lvlEmitter = te;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void setTextField(final NumberEntryWidget level) {
|
||||
this.textField = level;
|
||||
this.textField.setValue(this.EmitterValue);
|
||||
public long getReportingValue() {
|
||||
return reportingValue;
|
||||
}
|
||||
|
||||
public void setLevel(final long l, final PlayerEntity player) {
|
||||
this.lvlEmitter.setReportingValue(l);
|
||||
this.EmitterValue = l;
|
||||
public void setReportingValue(long reportingValue) {
|
||||
if (isClient()) {
|
||||
if (reportingValue != this.reportingValue) {
|
||||
this.reportingValue = reportingValue;
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new ConfigValuePacket("FluidLevelEmitter.Value", String.valueOf(reportingValue)));
|
||||
}
|
||||
} else {
|
||||
this.lvlEmitter.setReportingValue(reportingValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,8 +78,7 @@ public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
this.EmitterValue = this.lvlEmitter.getReportingValue();
|
||||
if (isServer()) {
|
||||
this.setRedStoneMode(
|
||||
(RedstoneMode) this.getUpgradeable().getConfigManager().getSetting(Settings.REDSTONE_EMITTER));
|
||||
}
|
||||
@@ -83,15 +86,6 @@ public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
|
||||
this.standardDetectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
|
||||
if (field.equals("EmitterValue")) {
|
||||
if (this.textField != null) {
|
||||
this.textField.setValue(this.EmitterValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEFluidTank getFluidConfigInventory() {
|
||||
return this.lvlEmitter.getConfig();
|
||||
|
||||
@@ -44,7 +44,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.fluids.parts.FluidStorageBusPart;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
|
||||
/**
|
||||
@@ -129,7 +128,7 @@ public class FluidStorageBusContainer extends FluidConfigurableContainer {
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
|
||||
this.setReadWriteMode(
|
||||
(AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS));
|
||||
|
||||
@@ -124,7 +124,7 @@ public class FluidTerminalContainer extends AEBaseContainer
|
||||
this.clientCM.registerSetting(Settings.SORT_BY, SortOrder.NAME);
|
||||
this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING);
|
||||
this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL);
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.serverCM = terminal.getConfigManager();
|
||||
this.monitor = terminal
|
||||
.getInventory(Api.instance().storage().getStorageChannel(IFluidStorageChannel.class));
|
||||
@@ -196,7 +196,7 @@ public class FluidTerminalContainer extends AEBaseContainer
|
||||
}
|
||||
|
||||
private void queueInventory(final ScreenHandlerListener c) {
|
||||
if (Platform.isServer() && c instanceof PlayerEntity && this.monitor != null) {
|
||||
if (isServer() && c instanceof PlayerEntity && this.monitor != null) {
|
||||
try {
|
||||
MEFluidInventoryUpdatePacket piu = new MEFluidInventoryUpdatePacket();
|
||||
final IItemList<IAEFluidStack> monitorCache = this.monitor.getStorageList();
|
||||
@@ -221,14 +221,14 @@ public class FluidTerminalContainer extends AEBaseContainer
|
||||
|
||||
@Override
|
||||
public IConfigManager getConfigManager() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
return this.serverCM;
|
||||
}
|
||||
return this.clientCM;
|
||||
}
|
||||
|
||||
public void setTargetStack(final IAEFluidStack stack) {
|
||||
if (Platform.isClient()) {
|
||||
if (isClient()) {
|
||||
if (stack == null && this.clientRequestedTargetFluid == null) {
|
||||
return;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ public class FluidTerminalContainer extends AEBaseContainer
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (this.monitor != this.terminal
|
||||
.getInventory(Api.instance().storage().getStorageChannel(IFluidStorageChannel.class))) {
|
||||
this.setValidContainer(false);
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
|
||||
package appeng.fluids.helper;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import alexiil.mc.lib.attributes.AttributeList;
|
||||
import alexiil.mc.lib.attributes.fluid.volume.FluidVolume;
|
||||
import alexiil.mc.lib.attributes.fluid.amount.FluidAmount;
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -319,8 +320,8 @@ public class DualityFluidInterface
|
||||
toStore.setStackSize(-toStore.getStackSize());
|
||||
|
||||
// make sure strange things didn't happen...
|
||||
final FluidVolume canExtract = this.tanks.drain(slot, toStore.getFluidStack(), false);
|
||||
if (canExtract.isEmpty() || canExtract.getAmount() != toStore.getStackSize()) {
|
||||
final FluidAmount canExtract = this.tanks.drain(slot, toStore.getFluidStack(), false);
|
||||
if (canExtract.isZero() || canExtract.asLong(1000, RoundingMode.DOWN) != toStore.getStackSize()) {
|
||||
changed = true;
|
||||
} else {
|
||||
IAEFluidStack notStored = Platform.poweredInsert(src, dest, toStore, this.interfaceRequestSource);
|
||||
@@ -329,8 +330,8 @@ public class DualityFluidInterface
|
||||
if (toStore.getStackSize() > 0) {
|
||||
// extract items!
|
||||
changed = true;
|
||||
final FluidVolume removed = this.tanks.drain(slot, toStore.getFluidStack(), true);
|
||||
if (removed.isEmpty() || toStore.getStackSize() != removed.getAmount()) {
|
||||
final FluidAmount removed = this.tanks.drain(slot, toStore.getFluidStack(), true);
|
||||
if (removed.isZero() || toStore.getStackSize() != removed.asLong(1000, RoundingMode.DOWN)) {
|
||||
throw new IllegalStateException("bad attempt at managing tanks. ( drain )");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,14 @@ import appeng.core.AELog;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class AEFluidInventory implements IAEFluidTank {
|
||||
|
||||
/**
|
||||
* While this may seem redundant, it helps since this class heavily mixes AE
|
||||
* fluids stacks, which use null to represent "nothing", and Minecraft's
|
||||
* FluidStack, which uses #isEmpty() to represent nothing.
|
||||
*/
|
||||
private static final IAEFluidStack EMPTY_AE_FLUIDSTACK = null;
|
||||
|
||||
private final IAEFluidStack[] fluids;
|
||||
private final IAEFluidInventory handler;
|
||||
private final int capacity;
|
||||
@@ -48,13 +56,13 @@ public class AEFluidInventory implements IAEFluidTank {
|
||||
public void setFluidInSlot(final int slot, final IAEFluidStack fluid) {
|
||||
if (slot >= 0 && slot < this.getSlots()) {
|
||||
if (Objects.equals(this.fluids[slot], fluid)) {
|
||||
if (fluid != null && fluid.getStackSize() != this.fluids[slot].getStackSize()) {
|
||||
if (fluid != EMPTY_AE_FLUIDSTACK && fluid.getStackSize() != this.fluids[slot].getStackSize()) {
|
||||
this.fluids[slot].setStackSize(Math.min(fluid.getStackSize(), this.capacity));
|
||||
this.onContentChanged(slot);
|
||||
}
|
||||
} else {
|
||||
if (fluid == null) {
|
||||
this.fluids[slot] = null;
|
||||
if (fluid == EMPTY_AE_FLUIDSTACK) {
|
||||
this.fluids[slot] = EMPTY_AE_FLUIDSTACK;
|
||||
} else {
|
||||
this.fluids[slot] = fluid.copy();
|
||||
this.fluids[slot].setStackSize(Math.min(fluid.getStackSize(), this.capacity));
|
||||
@@ -76,7 +84,7 @@ public class AEFluidInventory implements IAEFluidTank {
|
||||
if (slot >= 0 && slot < this.getSlots()) {
|
||||
return this.fluids[slot];
|
||||
}
|
||||
return null;
|
||||
return EMPTY_AE_FLUIDSTACK;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,7 +107,7 @@ public class AEFluidInventory implements IAEFluidTank {
|
||||
if (tank < 0 || tank >= fluids.length) {
|
||||
return FluidVolumeUtil.EMPTY;
|
||||
}
|
||||
return fluids[tank] == null ? FluidVolumeUtil.EMPTY : fluids[tank].getFluidStack();
|
||||
return fluids[tank] == EMPTY_AE_FLUIDSTACK ? FluidVolumeUtil.EMPTY : fluids[tank].getFluidStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,13 +127,13 @@ public class AEFluidInventory implements IAEFluidTank {
|
||||
|
||||
final IAEFluidStack fluid = this.fluids[slot];
|
||||
|
||||
if (fluid != null && !fluid.getFluidStack().equals(resource)) {
|
||||
if (fluid != EMPTY_AE_FLUIDSTACK && !fluid.getFluidStack().equals(resource)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amountToStore = this.capacity;
|
||||
|
||||
if (fluid != null) {
|
||||
if (fluid != EMPTY_AE_FLUIDSTACK) {
|
||||
amountToStore -= fluid.getStackSize();
|
||||
}
|
||||
|
||||
@@ -143,19 +151,19 @@ public class AEFluidInventory implements IAEFluidTank {
|
||||
return amountToStore;
|
||||
}
|
||||
|
||||
public FluidVolume drain(final int slot, final FluidVolume resource, final boolean doDrain) {
|
||||
public FluidAmount drain(final int slot, final FluidVolume resource, final boolean doDrain) {
|
||||
final IAEFluidStack fluid = this.fluids[slot];
|
||||
if (resource.isEmpty() || fluid == null || !fluid.getFluidStack().equals(resource)) {
|
||||
return null;
|
||||
if (resource.isEmpty() || fluid == EMPTY_AE_FLUIDSTACK || !fluid.getFluidStack().equals(resource)) {
|
||||
return FluidAmount.ZERO;
|
||||
}
|
||||
int toDrain = (int) resource.getAmount_F().asLong(1000, RoundingMode.DOWN);
|
||||
return this.drain(slot, toDrain, doDrain);
|
||||
}
|
||||
|
||||
public FluidVolume drain(final int slot, final int maxDrain, boolean doDrain) {
|
||||
public FluidAmount drain(final int slot, final int maxDrain, boolean doDrain) {
|
||||
final IAEFluidStack fluid = this.fluids[slot];
|
||||
if (fluid == null || maxDrain <= 0) {
|
||||
return null;
|
||||
if (fluid == EMPTY_AE_FLUIDSTACK || maxDrain <= 0) {
|
||||
return FluidAmount.ZERO;
|
||||
}
|
||||
|
||||
int drained = maxDrain;
|
||||
@@ -163,15 +171,15 @@ public class AEFluidInventory implements IAEFluidTank {
|
||||
drained = (int) fluid.getStackSize();
|
||||
}
|
||||
|
||||
FluidVolume stack = fluid.getFluidStack().withAmount(FluidAmount.of(drained, 1000));
|
||||
FluidAmount amount = FluidAmount.of(drained, 1000);
|
||||
if (doDrain) {
|
||||
fluid.setStackSize(fluid.getStackSize() - drained);
|
||||
if (fluid.getStackSize() <= 0) {
|
||||
this.fluids[slot] = null;
|
||||
this.fluids[slot] = EMPTY_AE_FLUIDSTACK;
|
||||
}
|
||||
this.onContentChanged(slot);
|
||||
}
|
||||
return stack;
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void writeToNBT(final CompoundTag data, final String name) {
|
||||
@@ -185,7 +193,7 @@ public class AEFluidInventory implements IAEFluidTank {
|
||||
try {
|
||||
final CompoundTag c = new CompoundTag();
|
||||
|
||||
if (this.fluids[x] != null) {
|
||||
if (this.fluids[x] != EMPTY_AE_FLUIDSTACK) {
|
||||
this.fluids[x].writeToNBT(c);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.LinkedListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.world.World;
|
||||
@@ -73,7 +73,7 @@ public class TickHandler {
|
||||
ServerTickEvents.END_SERVER_TICK.register(this::onAfterServerTick);
|
||||
ServerTickEvents.START_WORLD_TICK.register(this::onBeforeWorldTick);
|
||||
ServerTickEvents.END_WORLD_TICK.register(this::onAfterWorldTick);
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register(this::onServerStopping);
|
||||
ServerWorldEvents.UNLOAD.register(this::onUnloadWorld);
|
||||
}
|
||||
|
||||
public static TickHandler instance() {
|
||||
@@ -135,38 +135,13 @@ public class TickHandler {
|
||||
this.getRepo().clear();
|
||||
}
|
||||
|
||||
// FIXME FABRIC It does not look like worlds can ever unload in Fabric.
|
||||
// FIXME FABRIC public void unloadWorld(final WorldEvent.Unload ev) {
|
||||
// FIXME FABRIC if (Platform.isServer()) // for no there is no reason to care about this on the client...
|
||||
// FIXME FABRIC {
|
||||
// FIXME FABRIC final List<IGridNode> toDestroy = new ArrayList<>();
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC this.getRepo().updateNetworks();
|
||||
// FIXME FABRIC for (final Grid g : this.getRepo().networks) {
|
||||
// FIXME FABRIC for (final IGridNode n : g.getNodes()) {
|
||||
// FIXME FABRIC if (n.getWorld() == ev.getWorld()) {
|
||||
// FIXME FABRIC toDestroy.add(n);
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC for (final IGridNode n : toDestroy) {
|
||||
// FIXME FABRIC n.destroy();
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC }
|
||||
|
||||
/**
|
||||
* This is primarily useful for an integrated server being stopped, and can be
|
||||
* fully replaced by the event above once world unload events hit.
|
||||
*/
|
||||
private void onServerStopping(MinecraftServer server) {
|
||||
public void onUnloadWorld(MinecraftServer server, ServerWorld world) {
|
||||
final List<IGridNode> toDestroy = new ArrayList<>();
|
||||
this.server.updateNetworks();
|
||||
for (final Grid g : this.server.networks) {
|
||||
|
||||
this.getRepo().updateNetworks();
|
||||
for (final Grid g : this.getRepo().networks) {
|
||||
for (final IGridNode n : g.getNodes()) {
|
||||
WorldAccess nodeWorld = n.getWorld();
|
||||
if (nodeWorld instanceof ServerWorld && ((ServerWorld) nodeWorld).getServer() == server) {
|
||||
if (n.getWorld() == world) {
|
||||
toDestroy.add(n);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ package appeng.tile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -31,7 +30,6 @@ import javax.annotation.Nullable;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
||||
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachmentBlockEntity;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
@@ -69,24 +67,8 @@ import appeng.util.SettingsFrom;
|
||||
public class AEBaseBlockEntity extends BlockEntity implements IOrientable, ICommonTile, ICustomNameObject,
|
||||
BlockEntityClientSerializable, RenderAttachmentBlockEntity, AttributeProvider {
|
||||
|
||||
// FIXME: should probably remove at start of next server tick!
|
||||
static {
|
||||
ServerChunkEvents.CHUNK_UNLOAD.register((serverWorld, worldChunk) -> {
|
||||
List<AEBaseBlockEntity> entitiesToRemove = null;
|
||||
for (BlockEntity value : worldChunk.getBlockEntities().values()) {
|
||||
if (value instanceof AEBaseBlockEntity) {
|
||||
if (entitiesToRemove == null) {
|
||||
entitiesToRemove = new ArrayList<>();
|
||||
}
|
||||
entitiesToRemove.add((AEBaseBlockEntity) value);
|
||||
}
|
||||
}
|
||||
if (entitiesToRemove != null) {
|
||||
for (AEBaseBlockEntity blockEntity : entitiesToRemove) {
|
||||
blockEntity.onChunkUnloaded();
|
||||
}
|
||||
}
|
||||
});
|
||||
DeferredTileEntityUnloader.register();
|
||||
}
|
||||
|
||||
protected void onChunkUnloaded() {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
package appeng.tile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.util.IWorldCallable;
|
||||
|
||||
/**
|
||||
* We need to defer actually unloading tile entities until the end of the tick,
|
||||
* after the chunk has been saved to disk. The CHUNK_UNLOAD event runs before
|
||||
* the chunk has been saved, and if we disconnect nodes at that point, the saved
|
||||
* data will be missing information from the node (such as the player id).
|
||||
*/
|
||||
class DeferredTileEntityUnloader implements IWorldCallable<Void> {
|
||||
|
||||
public static void register() {
|
||||
ServerChunkEvents.CHUNK_UNLOAD.register((serverWorld, worldChunk) -> {
|
||||
List<AEBaseBlockEntity> entitiesToRemove = null;
|
||||
for (BlockEntity value : worldChunk.getBlockEntities().values()) {
|
||||
if (value instanceof AEBaseBlockEntity) {
|
||||
if (entitiesToRemove == null) {
|
||||
entitiesToRemove = new ArrayList<>();
|
||||
}
|
||||
entitiesToRemove.add((AEBaseBlockEntity) value);
|
||||
}
|
||||
}
|
||||
if (entitiesToRemove != null) {
|
||||
TickHandler.instance().addCallable(serverWorld, new DeferredTileEntityUnloader(entitiesToRemove));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final List<AEBaseBlockEntity> entitiesToRemove;
|
||||
|
||||
public DeferredTileEntityUnloader(List<AEBaseBlockEntity> entitiesToRemove) {
|
||||
this.entitiesToRemove = entitiesToRemove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void call(World world) {
|
||||
for (AEBaseBlockEntity blockEntity : entitiesToRemove) {
|
||||
blockEntity.onChunkUnloaded();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public class CraftingStorageBlockEntity extends CraftingBlockEntity {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final AbstractCraftingUnitBlock unit = (AbstractCraftingUnitBlock) this.world.getBlockState(this.pos)
|
||||
final AbstractCraftingUnitBlock<?> unit = (AbstractCraftingUnitBlock<?>) this.world.getBlockState(this.pos)
|
||||
.getBlock();
|
||||
switch (unit.type) {
|
||||
default:
|
||||
|
||||
@@ -722,11 +722,11 @@ public class ChestBlockEntity extends AENetworkPowerBlockEntity
|
||||
public void addAllAttributes(World world, BlockPos pos, BlockState state, AttributeList<?> to) {
|
||||
super.addAllAttributes(world, pos, state, to);
|
||||
|
||||
if (fluidInsertable != null && to.getSearchDirection() != getForward()) {
|
||||
if (fluidInsertable != null && to.getSearchDirection() != getForward().getOpposite()) {
|
||||
to.offer(fluidInsertable);
|
||||
}
|
||||
|
||||
if (accessor != null && to.getSearchDirection() != getForward()) {
|
||||
if (accessor != null && to.getSearchDirection() != getForward().getOpposite()) {
|
||||
to.offer(accessor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,13 +219,6 @@ public class Platform {
|
||||
return !AppEng.instance().isOnServerThread();
|
||||
}
|
||||
|
||||
/*
|
||||
* returns true if client classes are available.
|
||||
*/
|
||||
public static boolean isClientInstall() {
|
||||
return CLIENT_INSTALL;
|
||||
}
|
||||
|
||||
public static boolean hasPermissions(final DimensionalCoord dc, final PlayerEntity player) {
|
||||
if (!dc.isInWorld(player.world)) {
|
||||
return false;
|
||||
|
||||
@@ -289,6 +289,8 @@
|
||||
"gui.appliedenergistics2.With": "with",
|
||||
"gui.appliedenergistics2.Yellow": "Yellow",
|
||||
"gui.appliedenergistics2.Yes": "Yes",
|
||||
"gui.appliedenergistics2.validation.InvalidNumber": "Please enter a number",
|
||||
"gui.appliedenergistics2.validation.NumberLessThanMinValue": "Please enter a number greater than or equal to %d",
|
||||
"gui.appliedenergistics2.inWorldCraftingPresses": "Crafting Presses are found in the center of meteorites which can be found in around the world, they can be located by using a meteorite compass.",
|
||||
"gui.appliedenergistics2.inWorldFluix": "Drop 1 Charged Certus Quartz + 1 Nether Quartz + Redstone Dust into a puddle next to one another and wait a moment to receive 2 Fluix Crystals.",
|
||||
"gui.appliedenergistics2.inWorldPurificationCertus": "Drop a Certus Quartz Seed made from Certus Quartz Dust and Sand into a puddle of water; to make the process faster add Crystal Growth Accelerators.",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Reference in New Issue
Block a user