Merge remote-tracking branch 'origin/8.0.x-1.16.1'

This commit is contained in:
Sebastian Hartte
2020-09-20 00:42:52 +02:00
55 changed files with 888 additions and 839 deletions
@@ -106,6 +106,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
private Stopwatch dbl_clickTimer = Stopwatch.createStarted(); private Stopwatch dbl_clickTimer = Stopwatch.createStarted();
private ItemStack dbl_whichItem = ItemStack.EMPTY; private ItemStack dbl_whichItem = ItemStack.EMPTY;
private Slot bl_clicked; private Slot bl_clicked;
private boolean handlingRightClick;
protected final List<CustomSlotWidget> guiSlots = new ArrayList<>(); protected final List<CustomSlotWidget> guiSlots = new ArrayList<>();
public AEBaseScreen(T container, PlayerInventory playerInventory, ITextComponent title) { public AEBaseScreen(T container, PlayerInventory playerInventory, ITextComponent title) {
@@ -275,12 +276,18 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) { public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
this.drag_click.clear(); this.drag_click.clear();
// Forward right-clicks as-if they were left-clicks
if (btn == 1) { if (btn == 1) {
for (final Object o : this.buttons) { handlingRightClick = true;
final Widget widget = (Widget) o; try {
if (widget.isMouseOver(xCoord, yCoord)) { for (final Object o : this.buttons) {
return super.mouseClicked(xCoord, yCoord, 0); final Widget widget = (Widget) o;
if (widget.isMouseOver(xCoord, yCoord)) {
return super.mouseClicked(xCoord, yCoord, 0);
}
} }
} finally {
handlingRightClick = false;
} }
} }
@@ -628,15 +635,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
} }
protected ITextComponent getGuiDisplayName(final ITextComponent in) { protected ITextComponent getGuiDisplayName(final ITextComponent in) {
return this.hasCustomInventoryName() ? new StringTextComponent(this.getInventoryName()) : in; return title.getString().isEmpty() ? in : title;
}
private boolean hasCustomInventoryName() {
return this.container.getCustomName() != null;
}
private String getInventoryName() {
return this.container.getCustomName();
} }
/** /**
@@ -822,4 +821,12 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
} }
} }
/**
* Returns true while the current event being handled is a click of the right
* mouse button.
*/
public boolean isHandlingRightClick() {
return handlingRightClick;
}
} }
@@ -55,35 +55,23 @@ final class AESubScreen {
IPriorityHost priorityHost = (IPriorityHost) containerTarget; IPriorityHost priorityHost = (IPriorityHost) containerTarget;
this.previousContainerIcon = priorityHost.getItemStackRepresentation(); this.previousContainerIcon = priorityHost.getItemStackRepresentation();
this.previousContainerType = ChestContainer.TYPE; this.previousContainerType = ChestContainer.TYPE;
} } else if (containerTarget instanceof IPriorityHost) {
else if (containerTarget instanceof IPriorityHost) {
IPriorityHost priorityHost = (IPriorityHost) containerTarget; IPriorityHost priorityHost = (IPriorityHost) containerTarget;
this.previousContainerIcon = priorityHost.getItemStackRepresentation(); this.previousContainerIcon = priorityHost.getItemStackRepresentation();
this.previousContainerType = priorityHost.getContainerType(); this.previousContainerType = priorityHost.getContainerType();
} } else if (containerTarget instanceof WirelessTerminalGuiObject) {
else if (containerTarget instanceof WirelessTerminalGuiObject) {
this.previousContainerIcon = definitions.items().wirelessTerminal().maybeStack(1).orElse(ItemStack.EMPTY); this.previousContainerIcon = definitions.items().wirelessTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = WirelessTermContainer.TYPE; this.previousContainerType = WirelessTermContainer.TYPE;
} } else if (containerTarget instanceof TerminalPart) {
else if (containerTarget instanceof TerminalPart) {
this.previousContainerIcon = parts.terminal().maybeStack(1).orElse(ItemStack.EMPTY); this.previousContainerIcon = parts.terminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = MEMonitorableContainer.TYPE; this.previousContainerType = MEMonitorableContainer.TYPE;
} } else if (containerTarget instanceof CraftingTerminalPart) {
else if (containerTarget instanceof CraftingTerminalPart) {
this.previousContainerIcon = parts.craftingTerminal().maybeStack(1).orElse(ItemStack.EMPTY); this.previousContainerIcon = parts.craftingTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = CraftingTermContainer.TYPE; this.previousContainerType = CraftingTermContainer.TYPE;
} } else if (containerTarget instanceof PatternTerminalPart) {
else if (containerTarget instanceof PatternTerminalPart) {
this.previousContainerIcon = parts.patternTerminal().maybeStack(1).orElse(ItemStack.EMPTY); this.previousContainerIcon = parts.patternTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
this.previousContainerType = PatternTermContainer.TYPE; this.previousContainerType = PatternTermContainer.TYPE;
} } else {
else {
this.previousContainerIcon = null; this.previousContainerIcon = null;
this.previousContainerType = null; this.previousContainerType = null;
} }
@@ -48,22 +48,28 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
public void init() { public void init() {
super.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.setValue(1);
this.amountToCraft.setTextFieldBounds(62, 57, 50); this.amountToCraft.setTextFieldBounds(62, 57, 50);
this.amountToCraft.setMinValue(1); this.amountToCraft.setMinValue(1);
this.amountToCraft.setHideValidationIcon(true);
this.amountToCraft.addButtons(children::add, this::addButton); this.amountToCraft.addButtons(children::add, this::addButton);
this.next = this.addButton( this.next = this.addButton(
new Button(this.guiLeft + 128, this.guiTop + 51, 38, 20, GuiText.Next.text(), this::confirm)); new Button(this.guiLeft + 128, this.guiTop + 51, 38, 20, GuiText.Next.text(), this::confirm));
this.amountToCraft.setOnConfirm(() -> this.confirm(this.next));
subGui.addBackButton(this::addButton, 154, 0); subGui.addBackButton(this::addButton, 154, 0);
changeFocus(true);
} }
private void confirm(Button button) { private void confirm(Button button) {
NetworkHandler.instance() int amount = this.amountToCraft.getIntValue().orElse(0);
.sendToServer(new CraftRequestPacket((int) this.amountToCraft.getValue(), hasShiftDown())); if (amount <= 0) {
return;
}
NetworkHandler.instance().sendToServer(new CraftRequestPacket(amount, hasShiftDown()));
} }
@Override @Override
@@ -80,23 +86,9 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
this.bindTexture("guis/craft_amt.png"); this.bindTexture("guis/craft_amt.png");
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset()); GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
this.next.active = this.amountToCraft.getValue() > 0; this.next.active = this.amountToCraft.getIntValue().orElse(0) > 0;
this.amountToCraft.render(matrixStack, offsetX, offsetY, partialTicks); this.amountToCraft.render(matrixStack, 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";
}
} }
@@ -27,6 +27,8 @@ import com.google.common.base.Joiner;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.util.InputMappings; import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
@@ -76,10 +78,6 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
this.setScrollBar(scrollbar); this.setScrollBar(scrollbar);
} }
boolean isAutoStart() {
return this.container.isAutoStart();
}
@Override @Override
public void init() { public void init() {
super.init(); super.init();
@@ -90,8 +88,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
this.addButton(this.start); this.addButton(this.start);
this.selectCPU = new Button(this.guiLeft + (219 - 180) / 2, this.guiTop + this.ySize - 68, 180, 20, this.selectCPU = new Button(this.guiLeft + (219 - 180) / 2, this.guiTop + this.ySize - 68, 180, 20,
new StringTextComponent(GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic), getNextCpuButtonLabel(), btn -> selectNextCpu());
btn -> selectNextCpu());
this.selectCPU.active = false; this.selectCPU.active = false;
this.addButton(this.selectCPU); this.addButton(this.selectCPU);
@@ -139,22 +136,22 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
} }
private void updateCPUButtonText() { private void updateCPUButtonText() {
String btnTextText = GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic.getLocal(); this.selectCPU.setMessage(getNextCpuButtonLabel());
if (this.container.getSelectedCpu() >= 0)// && status.selectedCpu < status.cpus.size() ) }
{
if (this.container.getName() != null) {
final String name = this.container.getName().getStringTruncated(20);
btnTextText = GuiText.CraftingCPU.getLocal() + ": " + name;
} else {
btnTextText = GuiText.CraftingCPU.getLocal() + ": #" + this.container.getSelectedCpu();
}
}
private ITextComponent getNextCpuButtonLabel() {
if (this.container.hasNoCPU()) { if (this.container.hasNoCPU()) {
btnTextText = GuiText.NoCraftingCPUs.getLocal(); return GuiText.NoCraftingCPUs.text();
} }
this.selectCPU.setMessage(new StringTextComponent(btnTextText)); ITextComponent cpuName;
if (this.container.cpuName == null) {
cpuName = GuiText.Automatic.text();
} else {
cpuName = this.container.cpuName;
}
return GuiText.CraftingCPU.withSuffix(": ").append(cpuName);
} }
private boolean isSimulation() { private boolean isSimulation() {
@@ -447,7 +444,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
@Override @Override
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) { public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) { if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
if (keyCode == 28) { if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) {
this.start(); this.start();
return true; return true;
} }
@@ -456,7 +453,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
} }
private void selectNextCpu() { private void selectNextCpu() {
final boolean backwards = minecraft.mouseHelper.isRightDown(); final boolean backwards = isHandlingRightClick();
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next")); NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
} }
@@ -16,10 +16,6 @@
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>. * along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/ */
/**
*
*/
package appeng.client.gui.implementations; package appeng.client.gui.implementations;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
@@ -27,7 +23,6 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import appeng.container.implementations.CraftingStatusContainer; import appeng.container.implementations.CraftingStatusContainer;
import appeng.core.localization.GuiText; import appeng.core.localization.GuiText;
@@ -50,14 +45,13 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
public void init() { public void init() {
super.init(); super.init();
this.selectCPU = new Button(this.guiLeft + 8, this.guiTop + this.ySize - 25, 150, 20, this.selectCPU = new Button(this.guiLeft + 8, this.guiTop + this.ySize - 25, 150, 20, getNextCpuButtonLabel(),
new StringTextComponent(GuiText.CraftingCPU.getLocal() + ": " + GuiText.NoCraftingCPUs),
btn -> selectNextCpu()); btn -> selectNextCpu());
this.addButton(this.selectCPU); this.addButton(this.selectCPU);
subGui.addBackButton(btn -> { subGui.addBackButton(btn -> {
addButton(btn); addButton(btn);
btn.setHideEdge(13); btn.setHideEdge(true);
}, 213, -4); }, 213, -4);
} }
@@ -68,23 +62,14 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
} }
private void updateCPUButtonText() { private void updateCPUButtonText() {
String btnTextText = GuiText.NoCraftingJobs.getLocal(); this.selectCPU.setMessage(getNextCpuButtonLabel());
}
if (this.container.selectedCpu >= 0)// && status.selectedCpu < status.cpus.size() )
{
if (this.container.myName != null) {
final String name = this.container.myName.getStringTruncated(20);
btnTextText = GuiText.CPUs.getLocal() + ": " + name;
} else {
btnTextText = GuiText.CPUs.getLocal() + ": #" + this.container.selectedCpu;
}
}
private ITextComponent getNextCpuButtonLabel() {
if (this.container.noCPU) { if (this.container.noCPU) {
btnTextText = GuiText.NoCraftingJobs.getLocal(); return GuiText.NoCraftingJobs.text();
} }
return GuiText.CraftingCPU.withSuffix(": ").append(container.cpuName);
this.selectCPU.setMessage(new StringTextComponent(btnTextText));
} }
@Override @Override
@@ -92,9 +77,8 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
return in; // the cup name is on the button return in; // the cup name is on the button
} }
// FIXME: Extract to separate class? Shared with GuiCraftConfirm
private void selectNextCpu() { private void selectNextCpu() {
final boolean backwards = minecraft.mouseHelper.isRightDown(); final boolean backwards = isHandlingRightClick();
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next")); NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
} }
@@ -90,7 +90,7 @@ public class InterfaceScreen extends UpgradeableScreen<InterfaceContainer> {
} }
private void selectNextInterfaceMode() { private void selectNextInterfaceMode() {
final boolean backwards = getMinecraft().mouseHelper.isRightDown(); final boolean backwards = isHandlingRightClick();
NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards)); NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards));
} }
@@ -35,8 +35,6 @@ import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton; import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.LevelEmitterContainer; import appeng.container.implementations.LevelEmitterContainer;
import appeng.core.localization.GuiText; import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> { public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> {
@@ -52,15 +50,18 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
public void init() { public void init() {
super.init(); super.init();
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT, this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT);
this::onLevelChange);
this.level.setTextFieldBounds(25, 44, 75); this.level.setTextFieldBounds(25, 44, 75);
this.level.addButtons(children::add, this::addButton); this.level.addButtons(children::add, this::addButton);
container.setTextField(this.level); this.level.setValue(container.getReportingValue());
this.level.setOnChange(this::saveReportingValue);
this.level.setOnConfirm(this::closeScreen);
this.changeFocus(true);
} }
private void onLevelChange(long level) { private void saveReportingValue() {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(level))); this.level.getLongValue().ifPresent(container::setReportingValue);
} }
@Override @Override
@@ -238,7 +238,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
if (this.viewCell || this instanceof WirelessTermScreen) { if (this.viewCell || this instanceof WirelessTermScreen) {
this.craftingStatusBtn = this.addButton(new TabButton(this.guiLeft + 170, this.guiTop - 4, 2 + 11 * 16, this.craftingStatusBtn = this.addButton(new TabButton(this.guiLeft + 170, this.guiTop - 4, 2 + 11 * 16,
GuiText.CraftingStatus.text(), this.itemRenderer, btn -> showCraftingStatus())); GuiText.CraftingStatus.text(), this.itemRenderer, btn -> showCraftingStatus()));
this.craftingStatusBtn.setHideEdge(13); this.craftingStatusBtn.setHideEdge(true);
} }
this.isAutoFocus = SearchBoxMode.AUTOSEARCH == searchMode || SearchBoxMode.JEI_AUTOSEARCH == searchMode this.isAutoFocus = SearchBoxMode.AUTOSEARCH == searchMode || SearchBoxMode.JEI_AUTOSEARCH == searchMode
@@ -2,43 +2,60 @@ package appeng.client.gui.implementations;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.LongConsumer;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.IGuiEventListener; import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import appeng.client.gui.AEBaseScreen; import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.NumberEntryType; import appeng.client.gui.NumberEntryType;
import appeng.client.gui.widgets.ITickingWidget; import appeng.client.gui.widgets.ConfirmableTextField;
import appeng.client.gui.widgets.NumberBox; import appeng.client.gui.widgets.ValidationIcon;
import appeng.core.AEConfig; import appeng.core.AEConfig;
/** /**
* A utility widget that consists of a text-field to enter a number with * A utility widget that consists of a text-field to enter a number with
* attached buttons to increment/decrement the number in fixed intervals. * attached buttons to increment/decrement the number in fixed intervals.
*/ */
public class NumberEntryWidget implements ITickingWidget { public class NumberEntryWidget extends AbstractGui {
private static final ITextComponent INVALID_NUMBER = new TranslationTextComponent(
"gui.appliedenergistics2.validation.InvalidNumber");
private static final String NUMBER_LESS_THAN_MIN_VALUE = "gui.appliedenergistics2.validation.NumberLessThanMinValue";
private static final ITextComponent PLUS = new StringTextComponent("+"); private static final ITextComponent PLUS = new StringTextComponent("+");
private static final ITextComponent MINUS = new StringTextComponent("-"); private static final ITextComponent MINUS = new StringTextComponent("-");
private static final int TEXT_COLOR_ERROR = 0xFF1900;
private static final int TEXT_COLOR_NORMAL = 0xFFFFFF;
private final AEBaseScreen<?> parent; private final AEBaseScreen<?> parent;
private final int x; private final int x;
private final int y; private final int y;
private final NumberBox level; private final ConfirmableTextField textField;
private final NumberEntryType type; private final NumberEntryType type;
private List<Button> buttons; private List<Button> buttons;
private long minValue;
private ValidationIcon validationIcon;
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type, // Called when the value changes
LongConsumer changeListener) { 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.parent = parent;
this.x = x; this.x = x;
this.y = y; this.y = y;
@@ -47,28 +64,51 @@ public class NumberEntryWidget implements ITickingWidget {
FontRenderer font = parent.getMinecraft().fontRenderer; FontRenderer font = parent.getMinecraft().fontRenderer;
int inputX = parent.getGuiLeft() + x; int inputX = parent.getGuiLeft() + x;
int inputY = parent.getGuiTop() + y; int inputY = parent.getGuiTop() + y;
this.level = new NumberBox(font, inputX, inputY, width, font.FONT_HEIGHT, type.getInputType(), changeListener); this.textField = new ConfirmableTextField(font, inputX, inputY, width, font.FONT_HEIGHT,
this.level.setEnableBackgroundDrawing(false); StringTextComponent.EMPTY);
this.level.setMaxStringLength(16); this.textField.setEnableBackgroundDrawing(false);
this.level.setTextColor(0xFFFFFF); this.textField.setMaxStringLength(16);
this.level.setVisible(true); this.textField.setTextColor(TEXT_COLOR_NORMAL);
this.level.setFocused2(true); this.textField.setVisible(true);
parent.setFocusedDefault(this.level); this.textField.setFocused2(true);
parent.setFocusedDefault(this.textField);
this.textField.setResponder(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) { public void setActive(boolean active) {
this.level.setEnabled(active); this.textField.setEnabled(active);
this.buttons.forEach(b -> b.active = active); this.buttons.forEach(b -> b.active = active);
} }
public void setTextFieldBounds(int x, int y, int width) { public void setTextFieldBounds(int x, int y, int width) {
this.level.x = parent.getGuiLeft() + x; this.textField.x = parent.getGuiLeft() + x;
this.level.y = parent.getGuiTop() + y; this.textField.y = parent.getGuiTop() + y;
this.level.setWidth(width); this.textField.setWidth(width);
} }
public void setMinValue(long minValue) { public void setMinValue(long minValue) {
this.level.setMinValue(minValue); this.minValue = minValue;
validate();
} }
public void addButtons(Consumer<IGuiEventListener> addChildren, Consumer<Button> addButton) { public void addButtons(Consumer<IGuiEventListener> addChildren, Consumer<Button> addButton) {
@@ -81,54 +121,116 @@ public class NumberEntryWidget implements ITickingWidget {
int left = parent.getGuiLeft() + x; int left = parent.getGuiLeft() + x;
int top = parent.getGuiTop() + y; int top = parent.getGuiTop() + y;
List<Button> buttons = new ArrayList<>(8); List<Button> buttons = new ArrayList<>(9);
buttons.add(new Button(left, top, 22, 20, makeLabel(PLUS, a), btn -> addQty(a))); buttons.add(new Button(left, top, 22, 20, makeLabel(PLUS, a), btn -> addQty(a)));
buttons.add(new Button(left + 28, top, 28, 20, makeLabel(PLUS, b), btn -> addQty(b))); buttons.add(new Button(left + 28, top, 28, 20, makeLabel(PLUS, b), btn -> addQty(b)));
buttons.add(new Button(left + 62, top, 32, 20, makeLabel(PLUS, c), btn -> addQty(c))); buttons.add(new Button(left + 62, top, 32, 20, makeLabel(PLUS, c), btn -> addQty(c)));
buttons.add(new Button(left + 100, top, 38, 20, makeLabel(PLUS, d), btn -> addQty(d))); buttons.add(new Button(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 // Placing this here will give a sensible tab order
addChildren.accept(this.level); addChildren.accept(this.textField);
buttons.add(new Button(left, top + 42, 22, 20, makeLabel(MINUS, a), btn -> addQty(-a))); buttons.add(new Button(left, top + 42, 22, 20, makeLabel(MINUS, a), btn -> addQty(-a)));
buttons.add(new Button(left + 28, top + 42, 28, 20, makeLabel(MINUS, b), btn -> addQty(-b))); buttons.add(new Button(left + 28, top + 42, 28, 20, makeLabel(MINUS, b), btn -> addQty(-b)));
buttons.add(new Button(left + 62, top + 42, 32, 20, makeLabel(MINUS, c), btn -> addQty(-c))); buttons.add(new Button(left + 62, top + 42, 32, 20, makeLabel(MINUS, c), btn -> addQty(-c)));
buttons.add(new Button(left + 100, top + 42, 38, 20, makeLabel(MINUS, d), btn -> addQty(-d))); buttons.add(new Button(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 = 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(); * Returns the integer value currently in the text-field, if it is a valid
long minValue = this.level.getMinValue(); * number and is within the allowed min/max value.
this.level.setText(String.valueOf(Math.max(minValue, currentValue + i))); */
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 matrixStack, int mouseX, int mouseY, float partialTicks) { /**
this.level.render(matrixStack, mouseX, mouseY, partialTicks); * Returns the long value currently in the text-field, if it is a valid number
} * and is within the allowed min/max value.
*/
public void setValue(long value, boolean skipNotify) { public OptionalLong getLongValue() {
this.level.setValue(value, skipNotify); 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) { public void setValue(long value) {
setValue(value, false); this.textField.setText(String.valueOf(Math.max(minValue, value)));
this.textField.setCursorPositionEnd();
this.textField.setSelectionPos(0);
validate();
} }
public long getValue() { private void addQty(final long i) {
return level.getValue(); getLongValue().ifPresent(currentValue -> setValue(currentValue + i));
} }
@Override public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) {
public void tick() { this.textField.render(matrices, mouseX, mouseY, partialTicks);
this.level.tick(); }
private void validate() {
List<ITextComponent> validationErrors = new ArrayList<>();
String text = textField.getText().trim();
try {
long value = Long.parseLong(text, 10);
if (value < minValue) {
validationErrors.add(new TranslationTextComponent(NUMBER_LESS_THAN_MIN_VALUE, minValue));
}
} catch (NumberFormatException ignored) {
validationErrors.add(INVALID_NUMBER);
}
boolean valid = validationErrors.isEmpty();
this.textField.setTextColor(valid ? TEXT_COLOR_NORMAL : TEXT_COLOR_ERROR);
if (this.validationIcon != null) {
this.validationIcon.setValid(valid);
this.validationIcon.setTooltip(validationErrors);
}
} }
private ITextComponent makeLabel(ITextComponent prefix, int amount) { private ITextComponent makeLabel(ITextComponent prefix, int amount) {
return prefix.copyRaw().appendString(String.valueOf(amount)); return prefix.copyRaw().appendString(String.valueOf(amount));
} }
public void setHideValidationIcon(boolean hideValidationIcon) {
this.hideValidationIcon = hideValidationIcon;
}
} }
@@ -18,6 +18,8 @@
package appeng.client.gui.implementations; package appeng.client.gui.implementations;
import java.util.OptionalInt;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
@@ -27,8 +29,6 @@ import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.NumberEntryType; import appeng.client.gui.NumberEntryType;
import appeng.container.implementations.PriorityContainer; import appeng.container.implementations.PriorityContainer;
import appeng.core.localization.GuiText; import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
public class PriorityScreen extends AEBaseScreen<PriorityContainer> { public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
@@ -39,24 +39,38 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, ITextComponent title) { public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, ITextComponent title) {
super(container, playerInventory, title); super(container, playerInventory, title);
this.subGui = new AESubScreen(this, container.getPriorityHost()); this.subGui = new AESubScreen(this, container.getPriorityHost());
// This is the effective size of the background image
xSize = 175;
ySize = 128;
} }
@Override @Override
public void init() { public void init() {
super.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.setTextFieldBounds(62, 57, 50);
this.priority.setMinValue(Integer.MIN_VALUE); this.priority.setMinValue(Integer.MIN_VALUE);
container.setTextField(this.priority); this.priority.setValue(this.container.getPriorityValue());
this.priority.addButtons(children::add, this::addButton); this.priority.addButtons(children::add, this::addButton);
this.subGui.addBackButton(this::addButton, 154, 0); 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) { private void savePriority() {
NetworkHandler.instance() OptionalInt priority = this.priority.getIntValue();
.sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(priority))); if (priority.isPresent()) {
container.setPriority(priority.getAsInt());
}
} }
@Override @Override
@@ -68,13 +82,10 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
@Override @Override
public void drawBG(MatrixStack matrixStack, final int offsetX, final int offsetY, final int mouseX, public void drawBG(MatrixStack matrixStack, final int offsetX, final int offsetY, final int mouseX,
final int mouseY, float partialTicks) { final int mouseY, float partialTicks) {
this.bindTexture(getBackground()); this.bindTexture("guis/priority.png");
blit(matrixStack, offsetX, offsetY, 0, 0, this.xSize, this.ySize); blit(matrixStack, offsetX, offsetY, 0, 0, this.xSize, this.ySize);
this.priority.render(matrixStack, mouseX, mouseY, partialTicks); this.priority.render(matrixStack, 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.gui.FontRenderer;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.util.text.ITextComponent;
public class ConfirmableTextField extends TextFieldWidget {
private Runnable onConfirm;
public ConfirmableTextField(FontRenderer fontRenderer, int x, int y, int width, int height, ITextComponent text) {
super(fontRenderer, x, y, width, height, text);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (canWrite() && (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.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@@ -35,6 +36,10 @@ public abstract class IconButton extends Button implements ITooltip {
private boolean halfSize = false; private boolean halfSize = false;
private boolean disableClickSound = false;
private boolean disableBackground = false;
public IconButton(final int x, final int y, IPressable onPress) { public IconButton(final int x, final int y, IPressable onPress) {
super(x, y, 16, 16, StringTextComponent.EMPTY, onPress); super(x, y, 16, 16, StringTextComponent.EMPTY, onPress);
} }
@@ -44,6 +49,13 @@ public abstract class IconButton extends Button implements ITooltip {
this.active = vis; this.active = vis;
} }
@Override
public void playDownSound(SoundHandler soundHandler) {
if (!disableClickSound) {
super.playDownSound(soundHandler);
}
}
@Override @Override
public void renderButton(MatrixStack matrixStack, final int mouseX, final int mouseY, float partial) { public void renderButton(MatrixStack matrixStack, final int mouseX, final int mouseY, float partial) {
@@ -74,7 +86,9 @@ public abstract class IconButton extends Button implements ITooltip {
final int uv_y = iconIndex / 16; final int uv_y = iconIndex / 16;
final int uv_x = iconIndex - uv_y * 16; final int uv_x = iconIndex - uv_y * 16;
GuiUtils.drawTexturedModalRect(0, 0, 256 - 16, 256 - 16, 16, 16, 0); if (!disableBackground) {
GuiUtils.drawTexturedModalRect(0, 0, 256 - 16, 256 - 16, 16, 16, 0);
}
GuiUtils.drawTexturedModalRect(0, 0, uv_x * 16, uv_y * 16, 16, 16, 0); GuiUtils.drawTexturedModalRect(0, 0, uv_x * 16, uv_y * 16, 16, 16, 0);
RenderSystem.popMatrix(); RenderSystem.popMatrix();
} else { } else {
@@ -87,12 +101,18 @@ public abstract class IconButton extends Button implements ITooltip {
final int uv_y = iconIndex / 16; final int uv_y = iconIndex / 16;
final int uv_x = iconIndex - uv_y * 16; final int uv_x = iconIndex - uv_y * 16;
GuiUtils.drawTexturedModalRect(this.x, this.y, 256 - 16, 256 - 16, 16, 16, 0); if (!disableBackground) {
GuiUtils.drawTexturedModalRect(this.x, this.y, 256 - 16, 256 - 16, 16, 16, 0);
}
GuiUtils.drawTexturedModalRect(this.x, this.y, uv_x * 16, uv_y * 16, 16, 16, 0); GuiUtils.drawTexturedModalRect(this.x, this.y, uv_x * 16, uv_y * 16, 16, 16, 0);
} }
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
if (isHovered()) {
renderToolTip(matrixStack, mouseX, mouseY);
}
} }
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
} }
protected abstract int getIconIndex(); protected abstract int getIconIndex();
@@ -135,4 +155,20 @@ public abstract class IconButton extends Button implements ITooltip {
this.halfSize = halfSize; 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.gui.FontRenderer;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.util.text.StringTextComponent;
public class NumberBox extends TextFieldWidget {
private final LongConsumer changeListener;
private long lastValue;
private long minValue = 0;
private long maxValue;
public NumberBox(final FontRenderer 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 StringTextComponent("0"));
this.setText("0");
setResponder(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 java.util.regex.Pattern;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
@@ -47,6 +48,7 @@ import appeng.api.config.StorageFilter;
import appeng.api.config.TerminalStyle; import appeng.api.config.TerminalStyle;
import appeng.api.config.ViewItems; import appeng.api.config.ViewItems;
import appeng.api.config.YesNo; import appeng.api.config.YesNo;
import appeng.client.gui.AEBaseScreen;
import appeng.core.localization.ButtonToolTips; import appeng.core.localization.ButtonToolTips;
import appeng.util.EnumCycler; 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, registerApp(16 * 7, Settings.CONDENSER_OUTPUT, CondenserOutput.TRASH, ButtonToolTips.CondenserOutput,
ButtonToolTips.Trash); ButtonToolTips.Trash);
registerApp(16 * 7 + 1, Settings.CONDENSER_OUTPUT, CondenserOutput.MATTER_BALLS, 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, 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, registerApp(16 * 9 + 1, Settings.ACCESS, AccessRestriction.READ, ButtonToolTips.IOMode,
ButtonToolTips.Read); ButtonToolTips.Read);
@@ -230,7 +234,13 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
} }
private void triggerPress() { private void triggerPress() {
boolean backwards = Minecraft.getInstance().mouseHelper.isRightDown(); boolean backwards = false;
// This isn't great, but we don't get any information about right-clicks
// otherwise
Screen currentScreen = Minecraft.getInstance().currentScreen;
if (currentScreen instanceof AEBaseScreen) {
backwards = ((AEBaseScreen<?>) currentScreen).isHandlingRightClick();
}
onPress.handle(this, backwards); onPress.handle(this, backwards);
} }
@@ -33,7 +33,7 @@ public class TabButton extends Button implements ITooltip {
public static final ResourceLocation TEXTURE_STATES = new ResourceLocation("appliedenergistics2", public static final ResourceLocation TEXTURE_STATES = new ResourceLocation("appliedenergistics2",
"textures/guis/states.png"); "textures/guis/states.png");
private final ItemRenderer itemRenderer; private final ItemRenderer itemRenderer;
private int hideEdge = 0; private boolean hideEdge;
private int myIcon = -1; private int myIcon = -1;
private ItemStack myItem; private ItemStack myItem;
@@ -71,14 +71,17 @@ public class TabButton extends Button implements ITooltip {
RenderSystem.enableAlphaTest(); 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;
blit(matrixStack, this.x, this.y, uv_x * 16, 0, 25, 22); blit(matrixStack, this.x, this.y, uv_x * 16, uv_y * 16, 25, 22);
if (this.myIcon >= 0) { if (this.myIcon >= 0) {
final int uv_y = this.myIcon / 16; uv_y = this.myIcon / 16;
uv_x = this.myIcon - uv_y * 16; uv_x = this.myIcon - uv_y * 16;
blit(matrixStack, offsetX + this.x + 3, this.y + 3, uv_x * 16, uv_y * 16, 16, 16); blit(matrixStack, offsetX + this.x + 3, this.y + 3, uv_x * 16, uv_y * 16, 16, 16);
@@ -128,11 +131,11 @@ public class TabButton extends Button implements ITooltip {
return this.visible; return this.visible;
} }
public int getHideEdge() { public boolean getHideEdge() {
return this.hideEdge; return this.hideEdge;
} }
public void setHideEdge(final int hideEdge) { public void setHideEdge(final boolean hideEdge) {
this.hideEdge = hideEdge; this.hideEdge = hideEdge;
} }
} }
@@ -0,0 +1,65 @@
package appeng.client.gui.widgets;
import java.util.ArrayList;
import java.util.List;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.text.ITextComponent;
/**
* Displays a small icon that shows validation errors for some input control.
*/
public class ValidationIcon extends IconButton {
private final List<ITextComponent> 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<ITextComponent> 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;
}
Minecraft client = Minecraft.getInstance();
Screen screen = client.currentScreen;
if (screen == null) {
return;
}
screen.renderToolTip(matrices, this.tooltip, x, y, client.fontRenderer);
}
}
@@ -113,7 +113,7 @@ abstract class CraftingCubeBakedModel implements IDynamicBakedModel {
return quads; return quads;
} }
private void addRing(CubeBuilder builder, @Nullable Direction side, EnumSet<Direction> connections) { private void addRing(CubeBuilder builder, Direction side, EnumSet<Direction> connections) {
// Fill in the corners // Fill in the corners
builder.setTexture(this.ringCorner); builder.setTexture(this.ringCorner);
this.addCornerCap(builder, connections, side, Direction.UP, Direction.EAST, Direction.NORTH); this.addCornerCap(builder, connections, side, Direction.UP, Direction.EAST, Direction.NORTH);
@@ -65,10 +65,8 @@ import appeng.container.slot.PlayerInvSlot;
import appeng.core.AELog; import appeng.core.AELog;
import appeng.core.Api; import appeng.core.Api;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.core.sync.packets.InventoryActionPacket; import appeng.core.sync.packets.InventoryActionPacket;
import appeng.core.sync.packets.TargetItemStackPacket; import appeng.core.sync.packets.TargetItemStackPacket;
import appeng.helpers.ICustomNameObject;
import appeng.helpers.InventoryAction; import appeng.helpers.InventoryAction;
import appeng.me.helpers.PlayerSource; import appeng.me.helpers.PlayerSource;
import appeng.util.InventoryAdaptor; import appeng.util.InventoryAdaptor;
@@ -86,11 +84,9 @@ public abstract class AEBaseContainer extends Container {
private final IGuiItemObject obj; private final IGuiItemObject obj;
private final HashMap<Integer, SyncData> syncData = new HashMap<>(); private final HashMap<Integer, SyncData> syncData = new HashMap<>();
private boolean isContainerValid = true; private boolean isContainerValid = true;
private String customName;
private ContainerLocator locator; private ContainerLocator locator;
private IMEInventoryHandler<IAEItemStack> cellInv; private IMEInventoryHandler<IAEItemStack> cellInv;
private IEnergySource powerSrc; private IEnergySource powerSrc;
private boolean sentCustomName;
private int ticksSinceCheck = 900; private int ticksSinceCheck = 900;
private IAEItemStack clientRequestedTargetItem = null; private IAEItemStack clientRequestedTargetItem = null;
@@ -297,9 +293,7 @@ public abstract class AEBaseContainer extends Container {
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.sendCustomName(); if (isServer()) {
if (Platform.isServer()) {
if (this.tileEntity != null if (this.tileEntity != null
&& this.tileEntity.getWorld().getTileEntity(this.tileEntity.getPos()) != this.tileEntity) { && this.tileEntity.getWorld().getTileEntity(this.tileEntity.getPos()) != this.tileEntity) {
this.setValidContainer(false); this.setValidContainer(false);
@@ -866,43 +860,6 @@ public abstract class AEBaseContainer extends Container {
this.detectAndSendChanges(); this.detectAndSendChanges();
} }
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) { public void swapSlotContents(final int slotA, final int slotB) {
final Slot a = this.getSlot(slotA); final Slot a = this.getSlot(slotA);
final Slot b = this.getSlot(slotB); final Slot b = this.getSlot(slotB);
@@ -992,14 +949,6 @@ public abstract class AEBaseContainer extends Container {
this.cellInv = cellInv; this.cellInv = cellInv;
} }
public String getCustomName() {
return this.customName;
}
public void setCustomName(final String customName) {
this.customName = customName;
}
public PlayerInventory getPlayerInventory() { public PlayerInventory getPlayerInventory() {
return this.invPlayer; return this.invPlayer;
} }
@@ -1028,4 +977,18 @@ public abstract class AEBaseContainer extends Container {
this.powerSrc = powerSrc; this.powerSrc = powerSrc;
} }
/**
* Returns whether this container instance lives on the client.
*/
protected boolean isClient() {
return invPlayer.player.getEntityWorld().isRemote();
}
/**
* 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), NetworkHandler.instance().sendTo(new ConfigValuePacket("SyncDat." + this.channel, json),
(ServerPlayerEntity) o); (ServerPlayerEntity) o);
} }
this.clientVersion = val;
return;
} }
// Types other than ITextComponent must be non-null // Types other than ITextComponent must be non-null
@@ -49,7 +49,6 @@ import appeng.container.slot.RestrictedInputSlot;
import appeng.core.Api; import appeng.core.Api;
import appeng.tile.misc.CellWorkbenchTileEntity; import appeng.tile.misc.CellWorkbenchTileEntity;
import appeng.util.EnumCycler; import appeng.util.EnumCycler;
import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil; import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.WrapperSupplierItemHandler; import appeng.util.inv.WrapperSupplierItemHandler;
import appeng.util.iterators.NullIterator; import appeng.util.iterators.NullIterator;
@@ -143,7 +142,7 @@ public class CellWorkbenchContainer extends UpgradeableContainer {
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
final ItemStack is = this.workBench.getInventoryByName("cell").getStackInSlot(0); final ItemStack is = this.workBench.getInventoryByName("cell").getStackInSlot(0);
if (Platform.isServer()) { if (isServer()) {
for (final IContainerListener listener : this.listeners) { for (final IContainerListener listener : this.listeners) {
if (this.prevStack != is) { if (this.prevStack != is) {
// if the bars changed an item was probably made, so just send shit! // if the bars changed an item was probably made, so just send shit!
@@ -33,7 +33,6 @@ import appeng.container.interfaces.IProgressProvider;
import appeng.container.slot.OutputSlot; import appeng.container.slot.OutputSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.tile.misc.CondenserTileEntity; import appeng.tile.misc.CondenserTileEntity;
import appeng.util.Platform;
public class CondenserContainer extends AEBaseContainer implements IProgressProvider { public class CondenserContainer extends AEBaseContainer implements IProgressProvider {
@@ -75,13 +74,13 @@ public class CondenserContainer extends AEBaseContainer implements IProgressProv
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (Platform.isServer()) { if (isServer()) {
final double maxStorage = this.condenser.getStorage(); final double maxStorage = this.condenser.getStorage();
final double requiredEnergy = this.condenser.getRequiredPower(); final double requiredEnergy = this.condenser.getRequiredPower();
this.requiredEnergy = requiredEnergy == 0 ? (int) maxStorage : (int) Math.min(requiredEnergy, maxStorage); this.requiredEnergy = requiredEnergy == 0 ? (int) maxStorage : (int) Math.min(requiredEnergy, maxStorage);
this.storedPower = (int) this.condenser.getStoredPower(); 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.detectAndSendChanges(); super.detectAndSendChanges();
@@ -101,7 +100,4 @@ public class CondenserContainer extends AEBaseContainer implements IProgressProv
return this.output; return this.output;
} }
private void setOutput(final CondenserOutput output) {
this.output = output;
}
} }
@@ -1,5 +1,7 @@
package appeng.container.implementations; package appeng.container.implementations;
import java.util.function.Function;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
@@ -11,8 +13,6 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.fml.network.NetworkHooks;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
@@ -43,6 +43,8 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
private final SecurityPermissions requiredPermission; private final SecurityPermissions requiredPermission;
private Function<I, ITextComponent> containerTitleStrategy = this::getDefaultContainerTitle;
public ContainerHelper(ContainerFactory<C, I> factory, Class<I> interfaceClass) { public ContainerHelper(ContainerFactory<C, I> factory, Class<I> interfaceClass) {
this(factory, interfaceClass, null); this(factory, interfaceClass, null);
} }
@@ -54,19 +56,47 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
this.factory = factory; this.factory = factory;
} }
/**
* Specifies a custom strategy for obtaining a custom container name.
*
* The stratgy should return {@link StringTextComponent#EMPTY} if there's no
* custom name.
*/
public ContainerHelper<C, I> withContainerTitle(Function<I, ITextComponent> containerTitleStrategy) {
this.containerTitleStrategy = containerTitleStrategy;
return this;
}
/** /**
* Opens a container that is based around a single tile entity. The tile * Opens a container that is based around a single tile entity. The tile
* entity's position is encoded in the packet buffer. * entity's position is encoded in the packet buffer.
*/ */
public C fromNetwork(int windowId, PlayerInventory inv, PacketBuffer packetBuf) { public C fromNetwork(int windowId, PlayerInventory inv, PacketBuffer 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, PacketBuffer packetBuf,
InitialDataDeserializer<C, I> initialDataDeserializer) {
I host = getHostFromLocator(inv.player, ContainerLocator.read(packetBuf)); I host = getHostFromLocator(inv.player, ContainerLocator.read(packetBuf));
if (host != null) { 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; return null;
} }
public boolean open(PlayerEntity player, ContainerLocator locator) { 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)) { if (!(player instanceof ServerPlayerEntity)) {
// Cannot open containers on the client or for non-players // Cannot open containers on the client or for non-players
// FIXME logging? // FIXME logging?
@@ -83,7 +113,7 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
return false; return false;
} }
ITextComponent title = findContainerTitle(player.world, locator, accessInterface); ITextComponent title = containerTitleStrategy.apply(accessInterface);
INamedContainerProvider container = new SimpleNamedContainerProvider((wnd, p, pl) -> { INamedContainerProvider container = new SimpleNamedContainerProvider((wnd, p, pl) -> {
C c = factory.create(wnd, p, accessInterface); C c = factory.create(wnd, p, accessInterface);
@@ -92,34 +122,14 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
c.setLocator(locator); c.setLocator(locator);
return c; return c;
}, title); }, title);
NetworkHooks.openGui((ServerPlayerEntity) player, container, locator::write); NetworkHooks.openGui((ServerPlayerEntity) player, container, buffer -> {
locator.write(buffer);
initialDataSerializer.serializeInitialData(accessInterface, buffer);
});
return true; return true;
} }
private ITextComponent 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 TranslationTextComponent(
world.getBlockState(locator.getBlockPos()).getBlock().getTranslationKey());
}
return new StringTextComponent("Unknown");
}
private I getHostFromLocator(PlayerEntity player, ContainerLocator locator) { private I getHostFromLocator(PlayerEntity player, ContainerLocator locator) {
if (locator.hasItemIndex()) { if (locator.hasItemIndex()) {
return getHostFromPlayerInventory(player, locator); return getHostFromPlayerInventory(player, locator);
@@ -196,6 +206,24 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
C create(int windowId, PlayerInventory playerInv, I accessObj); 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, PacketBuffer 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, PacketBuffer buffer);
}
private boolean checkPermission(PlayerEntity player, Object accessInterface) { private boolean checkPermission(PlayerEntity player, Object accessInterface) {
if (requiredPermission != null) { if (requiredPermission != null) {
@@ -206,4 +234,15 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
} }
private ITextComponent getDefaultContainerTitle(I accessInterface) {
if (accessInterface instanceof ICustomNameObject) {
ICustomNameObject customNameObject = (ICustomNameObject) accessInterface;
if (customNameObject.hasCustomInventoryName()) {
return customNameObject.getCustomInventoryName();
}
}
return StringTextComponent.EMPTY;
}
} }
@@ -19,14 +19,8 @@
package appeng.container.implementations; package appeng.container.implementations;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.Future; 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.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
@@ -66,9 +60,8 @@ import appeng.me.helpers.PlayerSource;
import appeng.parts.reporting.CraftingTerminalPart; import appeng.parts.reporting.CraftingTerminalPart;
import appeng.parts.reporting.PatternTerminalPart; import appeng.parts.reporting.PatternTerminalPart;
import appeng.parts.reporting.TerminalPart; import appeng.parts.reporting.TerminalPart;
import appeng.util.Platform;
public class CraftConfirmContainer extends AEBaseContainer { public class CraftConfirmContainer extends AEBaseContainer implements CraftingCPUCyclingContainer {
public static ContainerType<CraftConfirmContainer> TYPE; public static ContainerType<CraftConfirmContainer> TYPE;
@@ -83,98 +76,51 @@ public class CraftConfirmContainer extends AEBaseContainer {
return helper.open(player, locator); return helper.open(player, locator);
} }
private final ArrayList<CraftingCPURecord> cpus = new ArrayList<>(); private final CraftingCPUCycler cpuCycler;
private ICraftingCPU selectedCpu;
private Future<ICraftingJob> job; private Future<ICraftingJob> job;
private ICraftingJob result; private ICraftingJob result;
@GuiSync(0) @GuiSync(0)
public long bytesUsed; public long bytesUsed;
@GuiSync(1)
public long cpuBytesAvail;
@GuiSync(2)
public int cpuCoProcessors;
@GuiSync(3) @GuiSync(3)
public boolean autoStart = false; public boolean autoStart = false;
@GuiSync(4) @GuiSync(4)
public boolean simulation = true; public boolean simulation = true;
@GuiSync(5)
public int selectedCpu = -1; // Indicates whether any CPUs are available
@GuiSync(6) @GuiSync(6)
public boolean noCPU = true; 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) @GuiSync(7)
public ITextComponent myName; public ITextComponent cpuName;
public CraftConfirmContainer(int id, PlayerInventory ip, ITerminalHost te) { public CraftConfirmContainer(int id, PlayerInventory ip, ITerminalHost te) {
super(TYPE, id, ip, 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) { @Override
if (next) { public void cycleSelectedCPU(final boolean next) {
this.setSelectedCpu(this.getSelectedCpu() + 1); this.cpuCycler.cycleCpu(next);
} 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 @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (Platform.isClient()) { if (isClient()) {
return; return;
} }
final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class); this.cpuCycler.detectAndSendChanges(this.getGrid());
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());
super.detectAndSendChanges(); super.detectAndSendChanges();
@@ -278,22 +224,6 @@ public class CraftConfirmContainer extends AEBaseContainer {
return c.getAvailableStorage() >= this.getUsedBytes() && !c.isBusy(); 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() { public void startJob() {
ContainerType<?> originalGui = null; ContainerType<?> originalGui = null;
@@ -316,9 +246,7 @@ public class CraftConfirmContainer extends AEBaseContainer {
if (this.result != null && !this.isSimulation()) { if (this.result != null && !this.isSimulation()) {
final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class); final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class);
final ICraftingLink g = cc.submitJob(this.result, null, final ICraftingLink g = cc.submitJob(this.result, null, this.selectedCpu, true, this.getActionSrc());
this.getSelectedCpu() == -1 ? null : this.cpus.get(this.getSelectedCpu()).getCpu(), true,
this.getActionSrc());
this.setAutoStart(false); this.setAutoStart(false);
if (g != null && originalGui != null && this.getLocator() != null) { if (g != null && originalGui != null && this.getLocator() != null) {
ContainerOpener.openContainer(originalGui, getPlayerInventory().player, getLocator()); ContainerOpener.openContainer(originalGui, getPlayerInventory().player, getLocator());
@@ -348,6 +276,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() { public World getWorld() {
return this.getPlayerInv().player.world; return this.getPlayerInv().player.world;
} }
@@ -372,42 +316,18 @@ public class CraftConfirmContainer extends AEBaseContainer {
return this.cpuBytesAvail; return this.cpuBytesAvail;
} }
private void setCpuAvailableBytes(final long cpuBytesAvail) {
this.cpuBytesAvail = cpuBytesAvail;
}
public int getCpuCoProcessors() { public int getCpuCoProcessors() {
return this.cpuCoProcessors; 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 ITextComponent getName() { public ITextComponent getName() {
return this.myName; return this.cpuName;
}
private void setName(@Nullable final ITextComponent myName) {
this.myName = myName;
} }
public boolean hasNoCPU() { public boolean hasNoCPU() {
return this.noCPU; return this.noCPU;
} }
private void setNoCPU(final boolean noCPU) {
this.noCPU = noCPU;
}
public boolean isSimulation() { public boolean isSimulation() {
return this.simulation; return this.simulation;
} }
@@ -26,7 +26,7 @@ import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.inventory.container.IContainerListener; import net.minecraft.inventory.container.IContainerListener;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
@@ -46,24 +46,28 @@ import appeng.core.Api;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket; import appeng.core.sync.packets.ConfigValuePacket;
import appeng.core.sync.packets.MEInventoryUpdatePacket; import appeng.core.sync.packets.MEInventoryUpdatePacket;
import appeng.helpers.ICustomNameObject;
import appeng.me.cluster.implementations.CraftingCPUCluster; import appeng.me.cluster.implementations.CraftingCPUCluster;
import appeng.tile.crafting.CraftingTileEntity; import appeng.tile.crafting.CraftingTileEntity;
import appeng.util.Platform;
public class CraftingCPUContainer extends AEBaseContainer public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorHandlerReceiver<IAEItemStack> {
implements IMEMonitorHandlerReceiver<IAEItemStack>, ICustomNameObject {
public static ContainerType<CraftingCPUContainer> TYPE; public static ContainerType<CraftingCPUContainer> TYPE;
private static final ContainerHelper<CraftingCPUContainer, CraftingTileEntity> helper = new ContainerHelper<>( private static final ContainerHelper<CraftingCPUContainer, CraftingTileEntity> helper = new ContainerHelper<>(
CraftingCPUContainer::new, CraftingTileEntity.class, SecurityPermissions.CRAFT); CraftingCPUContainer::new, CraftingTileEntity.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 StringTextComponent.EMPTY;
});
private final IItemList<IAEItemStack> list = Api.instance().storage().getStorageChannel(IItemStorageChannel.class) private final IItemList<IAEItemStack> list = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList(); .createList();
private IGrid network; private final IGrid network;
private CraftingCPUCluster monitor = null; private CraftingCPUCluster monitor = null;
private ITextComponent cpuName = null;
@GuiSync(0) @GuiSync(0)
public long eta = -1; public long eta = -1;
@@ -77,14 +81,16 @@ public class CraftingCPUContainer extends AEBaseContainer
final IActionHost host = (IActionHost) (te instanceof IActionHost ? te : null); final IActionHost host = (IActionHost) (te instanceof IActionHost ? te : null);
if (host != null && host.getActionableNode() != null) { if (host != null && host.getActionableNode() != null) {
this.setNetwork(host.getActionableNode().getGrid()); this.network = host.getActionableNode().getGrid();
} else {
this.network = null;
} }
if (te instanceof CraftingTileEntity) { if (te instanceof CraftingTileEntity) {
this.setCPU(((CraftingTileEntity) te).getCluster()); this.setCPU(((CraftingTileEntity) te).getCluster());
} }
if (this.getNetwork() == null && Platform.isServer()) { if (this.getNetwork() == null && isServer()) {
this.setValidContainer(false); this.setValidContainer(false);
} }
} }
@@ -114,15 +120,13 @@ public class CraftingCPUContainer extends AEBaseContainer
} }
if (c instanceof CraftingCPUCluster) { if (c instanceof CraftingCPUCluster) {
this.cpuName = c.getName(); this.monitor = (CraftingCPUCluster) c;
this.setMonitor((CraftingCPUCluster) c);
this.list.resetStatus(); this.list.resetStatus();
this.getMonitor().getListOfItem(this.list, CraftingItemList.ALL); this.getMonitor().getListOfItem(this.list, CraftingItemList.ALL);
this.getMonitor().addListener(this, null); this.getMonitor().addListener(this, null);
this.setEstimatedTime(0); this.setEstimatedTime(0);
} else { } else {
this.setMonitor(null); this.monitor = null;
this.cpuName = null;
this.setEstimatedTime(-1); this.setEstimatedTime(-1);
} }
} }
@@ -153,7 +157,7 @@ public class CraftingCPUContainer extends AEBaseContainer
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (Platform.isServer() && this.getMonitor() != null && !this.list.isEmpty()) { if (isServer() && this.getMonitor() != null && !this.list.isEmpty()) {
try { try {
if (this.getEstimatedTime() >= 0) { if (this.getEstimatedTime() >= 0) {
final long elapsedTime = this.getMonitor().getElapsedTime(); final long elapsedTime = this.getMonitor().getElapsedTime();
@@ -218,16 +222,6 @@ public class CraftingCPUContainer extends AEBaseContainer
} }
@Override
public ITextComponent getCustomInventoryName() {
return this.cpuName;
}
@Override
public boolean hasCustomInventoryName() {
return this.cpuName != null;
}
public long getEstimatedTime() { public long getEstimatedTime() {
return this.eta; return this.eta;
} }
@@ -240,15 +234,8 @@ public class CraftingCPUContainer extends AEBaseContainer
return this.monitor; return this.monitor;
} }
private void setMonitor(final CraftingCPUCluster monitor) {
this.monitor = monitor;
}
IGrid getNetwork() { IGrid getNetwork() {
return this.network; 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.util.text.StringTextComponent;
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 StringTextComponent("#" + (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.util.text.ITextComponent;
import appeng.api.networking.crafting.ICraftingCPU; import appeng.api.networking.crafting.ICraftingCPU;
public class CraftingCPURecord implements Comparable<CraftingCPURecord> { public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
private final ITextComponent myName;
private final ICraftingCPU cpu; private final ICraftingCPU cpu;
private final long size; private final long size;
private final int processors; private final int processors;
private ITextComponent name;
public CraftingCPURecord(final long size, final int coProcessors, final ICraftingCPU server) { public CraftingCPURecord(final long size, final int coProcessors, final ICraftingCPU server) {
this.size = size; this.size = size;
this.processors = coProcessors; this.processors = coProcessors;
this.cpu = server; this.cpu = server;
this.myName = server.getName(); this.name = server.getName();
} }
@Override @Override
@@ -50,10 +50,6 @@ public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
return this.cpu; return this.cpu;
} }
ITextComponent getName() {
return this.myName;
}
int getProcessors() { int getProcessors() {
return this.processors; return this.processors;
} }
@@ -61,4 +57,13 @@ public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
long getSize() { long getSize() {
return this.size; return this.size;
} }
public ITextComponent getName() {
return name;
}
public void setName(ITextComponent name) {
this.name = name;
}
} }
@@ -18,12 +18,6 @@
package appeng.container.implementations; 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.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
@@ -31,14 +25,13 @@ import net.minecraft.network.PacketBuffer;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid;
import appeng.api.networking.crafting.ICraftingCPU; import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.storage.ITerminalHost; import appeng.api.storage.ITerminalHost;
import appeng.container.ContainerLocator; import appeng.container.ContainerLocator;
import appeng.container.guisync.GuiSync; import appeng.container.guisync.GuiSync;
import appeng.util.Platform;
public class CraftingStatusContainer extends CraftingCPUContainer { public class CraftingStatusContainer extends CraftingCPUContainer implements CraftingCPUCyclingContainer {
public static ContainerType<CraftingStatusContainer> TYPE; public static ContainerType<CraftingStatusContainer> TYPE;
@@ -53,13 +46,13 @@ public class CraftingStatusContainer extends CraftingCPUContainer {
return helper.open(player, locator); return helper.open(player, locator);
} }
private final List<CraftingCPURecord> cpus = new ArrayList<>(); private final CraftingCPUCycler cpuCycler = new CraftingCPUCycler(this::cpuMatches, this::onCPUSelectionChanged);
@GuiSync(5)
public int selectedCpu = -1;
@GuiSync(6) @GuiSync(6)
public boolean noCPU = true; public boolean noCPU = true;
@GuiSync(7) @GuiSync(7)
public ITextComponent myName; public ITextComponent cpuName;
public CraftingStatusContainer(int id, final PlayerInventory ip, final ITerminalHost te) { public CraftingStatusContainer(int id, final PlayerInventory ip, final ITerminalHost te) {
super(TYPE, id, ip, te); super(TYPE, id, ip, te);
@@ -67,43 +60,9 @@ public class CraftingStatusContainer extends CraftingCPUContainer {
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (Platform.isServer() && this.getNetwork() != null) { IGrid network = this.getNetwork();
final ICraftingGrid cc = this.getNetwork().getCache(ICraftingGrid.class); if (isServer() && network != null) {
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus(); cpuCycler.detectAndSendChanges(network);
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();
} }
super.detectAndSendChanges(); super.detectAndSendChanges();
@@ -113,52 +72,20 @@ public class CraftingStatusContainer extends CraftingCPUContainer {
return c.isBusy(); return c.isBusy();
} }
private void sendCPUs() { private void onCPUSelectionChanged(CraftingCPURecord cpuRecord, boolean cpusAvailable) {
Collections.sort(this.cpus); noCPU = !cpusAvailable;
if (cpuRecord == null) {
if (this.selectedCpu >= this.cpus.size()) { cpuName = null;
this.selectedCpu = -1; setCPU(null);
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());
}
} else { } else {
this.setCPU(null); cpuName = cpuRecord.getName();
setCPU(cpuRecord.getCpu());
} }
} }
public void cycleCpu(final boolean next) { @Override
if (next) { public void cycleSelectedCPU(boolean forward) {
this.selectedCpu++; this.cpuCycler.cycleCpu(forward);
} 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());
}
} }
} }
@@ -35,7 +35,6 @@ import appeng.container.slot.FakeTypeOnlySlot;
import appeng.container.slot.OptionalTypeOnlyFakeSlot; import appeng.container.slot.OptionalTypeOnlyFakeSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.parts.automation.FormationPlanePart; import appeng.parts.automation.FormationPlanePart;
import appeng.util.Platform;
public class FormationPlaneContainer extends UpgradeableContainer { public class FormationPlaneContainer extends UpgradeableContainer {
@@ -107,7 +106,7 @@ public class FormationPlaneContainer extends UpgradeableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE)); this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
this.setPlaceMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.PLACE_BLOCK)); this.setPlaceMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.PLACE_BLOCK));
} }
@@ -34,7 +34,6 @@ import appeng.container.guisync.GuiSync;
import appeng.container.slot.OutputSlot; import appeng.container.slot.OutputSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.tile.storage.IOPortTileEntity; import appeng.tile.storage.IOPortTileEntity;
import appeng.util.Platform;
public class IOPortContainer extends UpgradeableContainer { public class IOPortContainer extends UpgradeableContainer {
@@ -111,7 +110,7 @@ public class IOPortContainer extends UpgradeableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
this.setOperationMode( this.setOperationMode(
(OperationMode) this.getUpgradeable().getConfigManager().getSetting(Settings.OPERATION_MODE)); (OperationMode) this.getUpgradeable().getConfigManager().getSetting(Settings.OPERATION_MODE));
this.setFullMode( this.setFullMode(
@@ -35,7 +35,6 @@ import appeng.container.slot.RestrictedInputSlot;
import appeng.core.Api; import appeng.core.Api;
import appeng.tile.misc.InscriberRecipes; import appeng.tile.misc.InscriberRecipes;
import appeng.tile.misc.InscriberTileEntity; import appeng.tile.misc.InscriberTileEntity;
import appeng.util.Platform;
/** /**
* @author AlgorithmX2 * @author AlgorithmX2
@@ -119,7 +118,7 @@ public class InscriberContainer extends UpgradeableContainer implements IProgres
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.standardDetectAndSendChanges(); this.standardDetectAndSendChanges();
if (Platform.isServer()) { if (isServer()) {
this.maxProcessingTime = this.ti.getMaxProcessingTime(); this.maxProcessingTime = this.ti.getMaxProcessingTime();
this.processingTime = this.ti.getProcessingTime(); this.processingTime = this.ti.getProcessingTime();
} }
@@ -52,7 +52,6 @@ import appeng.parts.reporting.InterfaceTerminalPart;
import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.misc.InterfaceTileEntity; import appeng.tile.misc.InterfaceTileEntity;
import appeng.util.InventoryAdaptor; import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil; import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.AdaptorItemHandler; import appeng.util.inv.AdaptorItemHandler;
import appeng.util.inv.WrapperCursorItemHandler; 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) { public InterfaceTerminalContainer(int id, final PlayerInventory ip, final InterfaceTerminalPart anchor) {
super(TYPE, id, ip, anchor); super(TYPE, id, ip, anchor);
if (Platform.isServer()) { if (isServer()) {
this.grid = anchor.getActionableNode().getGrid(); this.grid = anchor.getActionableNode().getGrid();
} }
@@ -97,7 +96,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (Platform.isClient()) { if (isClient()) {
return; return;
} }
@@ -22,8 +22,6 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import appeng.api.config.FuzzyMode; import appeng.api.config.FuzzyMode;
@@ -32,13 +30,13 @@ import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings; import appeng.api.config.Settings;
import appeng.api.config.YesNo; import appeng.api.config.YesNo;
import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.container.ContainerLocator; import appeng.container.ContainerLocator;
import appeng.container.guisync.GuiSync; import appeng.container.guisync.GuiSync;
import appeng.container.slot.FakeTypeOnlySlot; import appeng.container.slot.FakeTypeOnlySlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.parts.automation.LevelEmitterPart; import appeng.parts.automation.LevelEmitterPart;
import appeng.util.Platform;
public class LevelEmitterContainer extends UpgradeableContainer { public class LevelEmitterContainer extends UpgradeableContainer {
@@ -48,38 +46,46 @@ public class LevelEmitterContainer extends UpgradeableContainer {
LevelEmitterContainer::new, LevelEmitterPart.class, SecurityPermissions.BUILD); LevelEmitterContainer::new, LevelEmitterPart.class, SecurityPermissions.BUILD);
public static LevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer buf) { public static LevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer 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) { 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; private final LevelEmitterPart lvlEmitter;
@OnlyIn(Dist.CLIENT)
private NumberEntryWidget textField;
@GuiSync(2) @GuiSync(2)
public LevelType lvType; public LevelType lvType;
@GuiSync(3) @GuiSync(3)
public long EmitterValue = -1;
@GuiSync(4)
public YesNo cmType; 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) { public LevelEmitterContainer(int id, final PlayerInventory ip, final LevelEmitterPart te) {
super(TYPE, id, ip, te); super(TYPE, id, ip, te);
this.lvlEmitter = te; this.lvlEmitter = te;
} }
@OnlyIn(Dist.CLIENT) public long getReportingValue() {
public void setTextField(final NumberEntryWidget level) { return reportingValue;
this.textField = level;
this.textField.setValue(this.EmitterValue);
} }
public void setLevel(final long l, final PlayerEntity player) { public void setReportingValue(long reportingValue) {
this.lvlEmitter.setReportingValue(l); if (isClient()) {
this.EmitterValue = l; if (reportingValue != this.reportingValue) {
this.reportingValue = reportingValue;
NetworkHandler.instance()
.sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(reportingValue)));
}
} else {
this.lvlEmitter.setReportingValue(reportingValue);
}
} }
@Override @Override
@@ -115,7 +121,6 @@ public class LevelEmitterContainer extends UpgradeableContainer {
@Override @Override
public int availableUpgrades() { public int availableUpgrades() {
return 1; return 1;
} }
@@ -123,8 +128,7 @@ public class LevelEmitterContainer extends UpgradeableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
this.EmitterValue = this.lvlEmitter.getReportingValue();
this.setCraftingMode( this.setCraftingMode(
(YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.CRAFT_VIA_REDSTONE)); (YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.CRAFT_VIA_REDSTONE));
this.setLevelMode((LevelType) this.getUpgradeable().getConfigManager().getSetting(Settings.LEVEL_TYPE)); this.setLevelMode((LevelType) this.getUpgradeable().getConfigManager().getSetting(Settings.LEVEL_TYPE));
@@ -136,15 +140,6 @@ public class LevelEmitterContainer extends UpgradeableContainer {
this.standardDetectAndSendChanges(); 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 @Override
public YesNo getCraftingMode() { public YesNo getCraftingMode() {
return this.cmType; return this.cmType;
@@ -162,4 +157,5 @@ public class LevelEmitterContainer extends UpgradeableContainer {
private void setLevelMode(final LevelType lvType) { private void setLevelMode(final LevelType lvType) {
this.lvType = lvType; this.lvType = lvType;
} }
} }
@@ -75,7 +75,6 @@ import appeng.core.sync.packets.MEInventoryUpdatePacket;
import appeng.me.helpers.ChannelPowerSrc; import appeng.me.helpers.ChannelPowerSrc;
import appeng.util.ConfigManager; import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost; import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
public class MEMonitorableContainer extends AEBaseContainer public class MEMonitorableContainer extends AEBaseContainer
implements IConfigManagerHost, IConfigurableObject, IMEMonitorHandlerReceiver<IAEItemStack> { implements IConfigManagerHost, IConfigurableObject, IMEMonitorHandlerReceiver<IAEItemStack> {
@@ -131,7 +130,7 @@ public class MEMonitorableContainer extends AEBaseContainer
this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL); this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL);
this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING); this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING);
if (Platform.isServer()) { if (isServer()) {
this.serverCM = monitorable.getConfigManager(); this.serverCM = monitorable.getConfigManager();
this.monitor = monitorable this.monitor = monitorable
@@ -192,7 +191,7 @@ public class MEMonitorableContainer extends AEBaseContainer
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (Platform.isServer()) { if (isServer()) {
if (this.monitor != this.host if (this.monitor != this.host
.getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class))) { .getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class))) {
this.setValidContainer(false); this.setValidContainer(false);
@@ -328,7 +327,7 @@ public class MEMonitorableContainer extends AEBaseContainer
} }
private void queueInventory(final IContainerListener c) { private void queueInventory(final IContainerListener c) {
if (Platform.isServer() && c instanceof PlayerEntity && this.monitor != null) { if (isServer() && c instanceof PlayerEntity && this.monitor != null) {
try { try {
MEInventoryUpdatePacket piu = new MEInventoryUpdatePacket(); MEInventoryUpdatePacket piu = new MEInventoryUpdatePacket();
final IItemList<IAEItemStack> monitorCache = this.monitor.getStorageList(); final IItemList<IAEItemStack> monitorCache = this.monitor.getStorageList();
@@ -397,7 +396,7 @@ public class MEMonitorableContainer extends AEBaseContainer
@Override @Override
public IConfigManager getConfigManager() { public IConfigManager getConfigManager() {
if (Platform.isServer()) { if (isServer()) {
return this.serverCM; return this.serverCM;
} }
return this.clientCM; return this.clientCM;
@@ -41,7 +41,6 @@ import appeng.container.slot.RestrictedInputSlot;
import appeng.core.Api; import appeng.core.Api;
import appeng.items.misc.EncodedPatternItem; import appeng.items.misc.EncodedPatternItem;
import appeng.tile.crafting.MolecularAssemblerTileEntity; import appeng.tile.crafting.MolecularAssemblerTileEntity;
import appeng.util.Platform;
public class MolecularAssemblerContainer extends UpgradeableContainer implements IProgressProvider { public class MolecularAssemblerContainer extends UpgradeableContainer implements IProgressProvider {
@@ -147,7 +146,7 @@ public class MolecularAssemblerContainer extends UpgradeableContainer implements
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
this.setRedStoneMode( this.setRedStoneMode(
(RedstoneMode) this.getUpgradeable().getConfigManager().getSetting(Settings.REDSTONE_CONTROLLED)); (RedstoneMode) this.getUpgradeable().getConfigManager().getSetting(Settings.REDSTONE_CONTROLLED));
} }
@@ -43,7 +43,6 @@ import appeng.container.guisync.GuiSync;
import appeng.core.Api; import appeng.core.Api;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.MEInventoryUpdatePacket; import appeng.core.sync.packets.MEInventoryUpdatePacket;
import appeng.util.Platform;
import appeng.util.item.AEItemStack; import appeng.util.item.AEItemStack;
public class NetworkStatusContainer extends AEBaseContainer { 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); this.setValidContainer(false);
} }
} }
@@ -100,7 +99,7 @@ public class NetworkStatusContainer extends AEBaseContainer {
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.delay++; this.delay++;
if (Platform.isServer() && this.delay > 15 && this.network != null) { if (isServer() && this.delay > 15 && this.network != null) {
this.delay = 0; this.delay = 0;
final IEnergyGrid eg = this.network.getCache(IEnergyGrid.class); final IEnergyGrid eg = this.network.getCache(IEnergyGrid.class);
@@ -291,9 +291,9 @@ public class PatternTermContainer extends MEMonitorableContainer
@Override @Override
public boolean isSlotEnabled(final int idx) { public boolean isSlotEnabled(final int idx) {
if (idx == 1) { if (idx == 1) {
return Platform.isServer() ? !this.getPatternTerminal().isCraftingRecipe() : !this.isCraftingMode(); return isServer() ? !this.getPatternTerminal().isCraftingRecipe() : !this.isCraftingMode();
} else if (idx == 2) { } else if (idx == 2) {
return Platform.isServer() ? this.getPatternTerminal().isCraftingRecipe() : this.isCraftingMode(); return isServer() ? this.getPatternTerminal().isCraftingRecipe() : this.isCraftingMode();
} else { } else {
return false; return false;
} }
@@ -395,7 +395,7 @@ public class PatternTermContainer extends MEMonitorableContainer
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
super.detectAndSendChanges(); super.detectAndSendChanges();
if (Platform.isServer()) { if (isServer()) {
if (this.isCraftingMode() != this.getPatternTerminal().isCraftingRecipe()) { if (this.isCraftingMode() != this.getPatternTerminal().isCraftingRecipe()) {
this.setCraftingMode(this.getPatternTerminal().isCraftingRecipe()); this.setCraftingMode(this.getPatternTerminal().isCraftingRecipe());
this.updateOrderOfOutputSlots(); this.updateOrderOfOutputSlots();
@@ -417,7 +417,7 @@ public class PatternTermContainer extends MEMonitorableContainer
@Override @Override
public void onSlotChange(final Slot s) { public void onSlotChange(final Slot s) {
if (s == this.patternSlotOUT && Platform.isServer()) { if (s == this.patternSlotOUT && isServer()) {
for (final IContainerListener listener : this.listeners) { for (final IContainerListener listener : this.listeners) {
for (final Slot slot : this.inventorySlots) { for (final Slot slot : this.inventorySlots) {
if (slot instanceof OptionalFakeSlot || slot instanceof FakeCraftingMatrixSlot) { if (slot instanceof OptionalFakeSlot || slot instanceof FakeCraftingMatrixSlot) {
@@ -431,7 +431,7 @@ public class PatternTermContainer extends MEMonitorableContainer
this.detectAndSendChanges(); this.detectAndSendChanges();
} }
if (s == this.craftSlot && Platform.isClient()) { if (s == this.craftSlot && isClient()) {
this.getAndUpdateOutput(); this.getAndUpdateOutput();
} }
} }
@@ -23,17 +23,14 @@ import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
import appeng.api.parts.IPart; import appeng.api.parts.IPart;
import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
import appeng.container.ContainerLocator; 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.helpers.IPriorityHost;
import appeng.util.Platform;
public class PriorityContainer extends AEBaseContainer { public class PriorityContainer extends AEBaseContainer {
@@ -43,60 +40,53 @@ public class PriorityContainer extends AEBaseContainer {
PriorityContainer::new, IPriorityHost.class, SecurityPermissions.BUILD); PriorityContainer::new, IPriorityHost.class, SecurityPermissions.BUILD);
public static PriorityContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer buf) { public static PriorityContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer 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) { 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; private final IPriorityHost priHost;
@OnlyIn(Dist.CLIENT) private int priorityValue;
private NumberEntryWidget textField;
@GuiSync(2)
public long PriorityValue = -1;
public PriorityContainer(int id, final PlayerInventory ip, final IPriorityHost te) { public PriorityContainer(int id, final PlayerInventory ip, final IPriorityHost te) {
super(TYPE, id, ip, (TileEntity) (te instanceof TileEntity ? te : null), super(TYPE, id, ip, (TileEntity) (te instanceof TileEntity ? te : null),
(IPart) (te instanceof IPart ? te : null)); (IPart) (te instanceof IPart ? te : null));
this.priHost = te; this.priHost = te;
this.priorityValue = te.getPriority();
} }
@OnlyIn(Dist.CLIENT) public void setPriority(final int newValue) {
public void setTextField(final NumberEntryWidget level) { if (newValue != priorityValue) {
this.textField = level; if (isClient()) {
this.textField.setValue(this.PriorityValue, true); // If for whatever reason the client enters the value first, do not update based
} // on incoming server data
this.priorityValue = newValue;
public void setPriority(final int newValue, final PlayerEntity player) { NetworkHandler.instance()
this.priHost.setPriority(newValue); .sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(newValue)));
this.PriorityValue = newValue; } else {
this.priHost.setPriority(newValue);
this.priorityValue = newValue;
}
}
} }
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
super.detectAndSendChanges(); super.detectAndSendChanges();
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) {
this.PriorityValue = this.priHost.getPriority();
}
} }
@Override public int getPriorityValue() {
public void onUpdate(final String field, final Object oldValue, final Object newValue) { return priorityValue;
if (field.equals("PriorityValue")) {
if (this.textField != null) {
this.textField.setValue(this.PriorityValue, true);
}
}
super.onUpdate(field, oldValue, newValue);
} }
public IPriorityHost getPriorityHost() { public IPriorityHost getPriorityHost() {
return this.priHost; return this.priHost;
} }
} }
@@ -38,7 +38,6 @@ import appeng.core.Api;
import appeng.items.contents.QuartzKnifeObj; import appeng.items.contents.QuartzKnifeObj;
import appeng.items.materials.MaterialItem; import appeng.items.materials.MaterialItem;
import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.Platform;
public class QuartzKnifeContainer extends AEBaseContainer { public class QuartzKnifeContainer extends AEBaseContainer {
@@ -148,7 +147,7 @@ public class QuartzKnifeContainer extends AEBaseContainer {
} }
private void makePlate() { private void makePlate() {
if (Platform.isServer()) { if (isServer()) {
if (!this.getItemHandler().extractItem(0, 1, false).isEmpty()) { if (!this.getItemHandler().extractItem(0, 1, false).isEmpty()) {
final ItemStack item = QuartzKnifeContainer.this.toolInv.getItemStack(); final ItemStack item = QuartzKnifeContainer.this.toolInv.getItemStack();
final ItemStack before = item.copy(); final ItemStack before = item.copy();
@@ -35,7 +35,6 @@ import appeng.container.guisync.GuiSync;
import appeng.container.slot.OutputSlot; import appeng.container.slot.OutputSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.tile.spatial.SpatialIOPortTileEntity; import appeng.tile.spatial.SpatialIOPortTileEntity;
import appeng.util.Platform;
public class SpatialIOPortContainer extends AEBaseContainer { public class SpatialIOPortContainer extends AEBaseContainer {
@@ -65,7 +64,7 @@ public class SpatialIOPortContainer extends AEBaseContainer {
public SpatialIOPortContainer(int id, final PlayerInventory ip, final SpatialIOPortTileEntity spatialIOPort) { public SpatialIOPortContainer(int id, final PlayerInventory ip, final SpatialIOPortTileEntity spatialIOPort) {
super(TYPE, id, ip, spatialIOPort, null); super(TYPE, id, ip, spatialIOPort, null);
if (Platform.isServer()) { if (isServer()) {
this.network = spatialIOPort.getGridNode(AEPartLocation.INTERNAL).getGrid(); this.network = spatialIOPort.getGridNode(AEPartLocation.INTERNAL).getGrid();
} }
@@ -89,7 +88,7 @@ public class SpatialIOPortContainer extends AEBaseContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
this.delay++; this.delay++;
if (this.delay > 15 && this.network != null) { if (this.delay > 15 && this.network != null) {
this.delay = 0; this.delay = 0;
@@ -44,7 +44,6 @@ import appeng.container.slot.OptionalTypeOnlyFakeSlot;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.core.Api; import appeng.core.Api;
import appeng.parts.misc.StorageBusPart; import appeng.parts.misc.StorageBusPart;
import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil; import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.iterators.NullIterator; import appeng.util.iterators.NullIterator;
@@ -124,7 +123,7 @@ public class StorageBusContainer extends UpgradeableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE)); this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
this.setReadWriteMode( this.setReadWriteMode(
(AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS)); (AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS));
@@ -51,7 +51,6 @@ import appeng.container.slot.RestrictedInputSlot;
import appeng.items.contents.NetworkToolViewer; import appeng.items.contents.NetworkToolViewer;
import appeng.items.tools.NetworkToolItem; import appeng.items.tools.NetworkToolItem;
import appeng.parts.automation.ExportBusPart; import appeng.parts.automation.ExportBusPart;
import appeng.util.Platform;
public class UpgradeableContainer extends AEBaseContainer implements IOptionalSlotHost { public class UpgradeableContainer extends AEBaseContainer implements IOptionalSlotHost {
@@ -199,7 +198,7 @@ public class UpgradeableContainer extends AEBaseContainer implements IOptionalSl
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
final IConfigManager cm = this.getUpgradeable().getConfigManager(); final IConfigManager cm = this.getUpgradeable().getConfigManager();
this.loadSettingsFromHost(cm); this.loadSettingsFromHost(cm);
} }
@@ -29,7 +29,6 @@ import appeng.container.guisync.GuiSync;
import appeng.container.interfaces.IProgressProvider; import appeng.container.interfaces.IProgressProvider;
import appeng.container.slot.RestrictedInputSlot; import appeng.container.slot.RestrictedInputSlot;
import appeng.tile.misc.VibrationChamberTileEntity; import appeng.tile.misc.VibrationChamberTileEntity;
import appeng.util.Platform;
public class VibrationChamberContainer extends AEBaseContainer implements IProgressProvider { public class VibrationChamberContainer extends AEBaseContainer implements IProgressProvider {
@@ -65,7 +64,7 @@ public class VibrationChamberContainer extends AEBaseContainer implements IProgr
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (Platform.isServer()) { if (isServer()) {
this.remainingBurnTime = this.vibrationChamber.getMaxBurnTime() <= 0 ? 0 this.remainingBurnTime = this.vibrationChamber.getMaxBurnTime() <= 0 ? 0
: (int) (100.0 * this.vibrationChamber.getBurnTime() / this.vibrationChamber.getMaxBurnTime()); : (int) (100.0 * this.vibrationChamber.getBurnTime() / this.vibrationChamber.getMaxBurnTime());
this.burnSpeed = this.remainingBurnTime <= 0 ? 0 : this.vibrationChamber.getBurnSpeed(); this.burnSpeed = this.remainingBurnTime <= 0 ? 0 : this.vibrationChamber.getBurnSpeed();
@@ -28,7 +28,6 @@ import appeng.container.ContainerLocator;
import appeng.core.AEConfig; import appeng.core.AEConfig;
import appeng.core.localization.PlayerMessages; import appeng.core.localization.PlayerMessages;
import appeng.helpers.WirelessTerminalGuiObject; import appeng.helpers.WirelessTerminalGuiObject;
import appeng.util.Platform;
public class WirelessTermContainer extends MEPortableCellContainer { public class WirelessTermContainer extends MEPortableCellContainer {
@@ -57,7 +56,7 @@ public class WirelessTermContainer extends MEPortableCellContainer {
super.detectAndSendChanges(); super.detectAndSendChanges();
if (!this.wirelessTerminalGUIObject.rangeCheck()) { if (!this.wirelessTerminalGUIObject.rangeCheck()) {
if (Platform.isServer() && this.isValidContainer()) { if (isServer() && this.isValidContainer()) {
this.getPlayerInv().player.sendMessage(PlayerMessages.OutOfRange.get(), Util.DUMMY_UUID); this.getPlayerInv().player.sendMessage(PlayerMessages.OutOfRange.get(), Util.DUMMY_UUID);
} }
@@ -37,7 +37,7 @@ import appeng.container.AEBaseContainer;
import appeng.container.implementations.CellWorkbenchContainer; import appeng.container.implementations.CellWorkbenchContainer;
import appeng.container.implementations.CraftConfirmContainer; import appeng.container.implementations.CraftConfirmContainer;
import appeng.container.implementations.CraftingCPUContainer; import appeng.container.implementations.CraftingCPUContainer;
import appeng.container.implementations.CraftingStatusContainer; import appeng.container.implementations.CraftingCPUCyclingContainer;
import appeng.container.implementations.LevelEmitterContainer; import appeng.container.implementations.LevelEmitterContainer;
import appeng.container.implementations.NetworkToolContainer; import appeng.container.implementations.NetworkToolContainer;
import appeng.container.implementations.PatternTermContainer; import appeng.container.implementations.PatternTermContainer;
@@ -98,12 +98,9 @@ public class ConfigValuePacket extends BasePacket {
final ItemStack is = player.getHeldItem(hand); final ItemStack is = player.getHeldItem(hand);
final IMouseWheelItem si = (IMouseWheelItem) is.getItem(); final IMouseWheelItem si = (IMouseWheelItem) is.getItem();
si.onWheel(is, this.Value.equals("WheelUp")); si.onWheel(is, this.Value.equals("WheelUp"));
} else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftingStatusContainer) { } else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftingCPUCyclingContainer) {
final CraftingStatusContainer qk = (CraftingStatusContainer) c; final CraftingCPUCyclingContainer qk = (CraftingCPUCyclingContainer) c;
qk.cycleCpu(this.Value.equals("Next")); qk.cycleSelectedCPU(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.Start") && c instanceof CraftConfirmContainer) { } else if (this.Name.equals("Terminal.Start") && c instanceof CraftConfirmContainer) {
final CraftConfirmContainer qk = (CraftConfirmContainer) c; final CraftConfirmContainer qk = (CraftConfirmContainer) c;
qk.startJob(); qk.startJob();
@@ -118,13 +115,13 @@ public class ConfigValuePacket extends BasePacket {
sc.toggleSetting(this.Value, player); sc.toggleSetting(this.Value, player);
} else if (this.Name.equals("PriorityHost.Priority") && c instanceof PriorityContainer) { } else if (this.Name.equals("PriorityHost.Priority") && c instanceof PriorityContainer) {
final PriorityContainer pc = (PriorityContainer) c; 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) { } else if (this.Name.equals("LevelEmitter.Value") && c instanceof LevelEmitterContainer) {
final LevelEmitterContainer lvc = (LevelEmitterContainer) c; 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) { } else if (this.Name.equals("FluidLevelEmitter.Value") && c instanceof FluidLevelEmitterContainer) {
final FluidLevelEmitterContainer lvc = (FluidLevelEmitterContainer) c; 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) { } else if (this.Name.startsWith("PatternTerminal.") && c instanceof PatternTermContainer) {
final PatternTermContainer cpt = (PatternTermContainer) c; final PatternTermContainer cpt = (PatternTermContainer) c;
if (this.Name.equals("PatternTerminal.CraftMode")) { if (this.Name.equals("PatternTerminal.CraftMode")) {
@@ -192,9 +189,7 @@ public class ConfigValuePacket extends BasePacket {
public void clientPacketData(final INetworkInfo network, final PlayerEntity player) { public void clientPacketData(final INetworkInfo network, final PlayerEntity player) {
final Container c = player.openContainer; final Container c = player.openContainer;
if (this.Name.equals("CustomName") && c instanceof AEBaseContainer) { if (this.Name.startsWith("SyncDat.")) {
((AEBaseContainer) c).setCustomName(this.Value);
} else if (this.Name.startsWith("SyncDat.")) {
((AEBaseContainer) c).stringSync(Integer.parseInt(this.Name.substring(8)), this.Value); ((AEBaseContainer) c).stringSync(Integer.parseInt(this.Name.substring(8)), this.Value);
} else if (this.Name.equals("CraftingStatus") && this.Value.equals("Clear")) { } else if (this.Name.equals("CraftingStatus") && this.Value.equals("Clear")) {
final Screen gs = Minecraft.getInstance().currentScreen; final Screen gs = Minecraft.getInstance().currentScreen;
@@ -13,8 +13,6 @@ import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.client.gui.implementations.UpgradeableScreen; import appeng.client.gui.implementations.UpgradeableScreen;
import appeng.client.gui.widgets.ServerSettingToggleButton; import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.core.localization.GuiText; 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.client.gui.widgets.FluidSlotWidget;
import appeng.fluids.container.FluidLevelEmitterContainer; import appeng.fluids.container.FluidLevelEmitterContainer;
@@ -31,17 +29,24 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
public void init() { public void init() {
super.init(); super.init();
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_FLUID_VOLUME, this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_FLUID_VOLUME);
this::onLevelChange);
this.level.setTextFieldBounds(25, 44, 75); this.level.setTextFieldBounds(25, 44, 75);
container.setTextField(this.level);
this.level.addButtons(children::add, this::addButton); this.level.addButtons(children::add, this::addButton);
this.level.setValue(container.getReportingValue());
this.level.setOnChange(this::saveReportingValue);
this.level.setOnConfirm(this::closeScreen);
this.changeFocus(true);
final int y = 40; final int y = 40;
final int x = 80 + 57; final int x = 80 + 57;
this.guiSlots.add(new FluidSlotWidget(this.container.getFluidConfigInventory(), 0, 0, x, y)); this.guiSlots.add(new FluidSlotWidget(this.container.getFluidConfigInventory(), 0, 0, x, y));
} }
private void saveReportingValue() {
this.level.getLongValue().ifPresent(container::setReportingValue);
}
@Override @Override
protected void addButtons() { protected void addButtons() {
this.redstoneMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 28, this.redstoneMode = new ServerSettingToggleButton<>(this.guiLeft - 18, this.guiTop + 28,
@@ -82,8 +87,4 @@ public class FluidLevelEmitterScreen extends UpgradeableScreen<FluidLevelEmitter
protected void handleButtonVisibility() { protected void handleButtonVisibility() {
} }
private void onLevelChange(long level) {
NetworkHandler.instance().sendToServer(new ConfigValuePacket("FluidLevelEmitter.Value", String.valueOf(level)));
}
} }
@@ -71,7 +71,7 @@ public abstract class FluidConfigurableContainer extends UpgradeableContainer im
@Override @Override
protected void standardDetectAndSendChanges() { protected void standardDetectAndSendChanges() {
if (Platform.isServer()) { if (isServer()) {
this.getSyncHelper().sendDiff(this.listeners); this.getSyncHelper().sendDiff(this.listeners);
// clear out config items that are no longer valid (eg capacity upgrade removed) // clear out config items that are no longer valid (eg capacity upgrade removed)
@@ -81,7 +81,7 @@ public class FluidInterfaceContainer extends FluidConfigurableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
this.tankSync.sendDiff(this.listeners); this.tankSync.sendDiff(this.listeners);
} }
@@ -4,16 +4,14 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.config.RedstoneMode; import appeng.api.config.RedstoneMode;
import appeng.api.config.SecurityPermissions; import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings; import appeng.api.config.Settings;
import appeng.client.gui.implementations.NumberEntryWidget;
import appeng.container.ContainerLocator; import appeng.container.ContainerLocator;
import appeng.container.guisync.GuiSync;
import appeng.container.implementations.ContainerHelper; 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.parts.FluidLevelEmitterPart;
import appeng.fluids.util.IAEFluidTank; import appeng.fluids.util.IAEFluidTank;
import appeng.util.Platform; import appeng.util.Platform;
@@ -25,34 +23,41 @@ public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
FluidLevelEmitterContainer::new, FluidLevelEmitterPart.class, SecurityPermissions.BUILD); FluidLevelEmitterContainer::new, FluidLevelEmitterPart.class, SecurityPermissions.BUILD);
public static FluidLevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer buf) { public static FluidLevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer 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) { 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; private final FluidLevelEmitterPart lvlEmitter;
@OnlyIn(Dist.CLIENT) // Only synced once on container-open, and only used on client
private NumberEntryWidget textField; private long reportingValue;
@GuiSync(3)
public long EmitterValue = -1;
public FluidLevelEmitterContainer(int id, final PlayerInventory ip, final FluidLevelEmitterPart te) { public FluidLevelEmitterContainer(int id, final PlayerInventory ip, final FluidLevelEmitterPart te) {
super(TYPE, id, ip, te); super(TYPE, id, ip, te);
this.lvlEmitter = te; this.lvlEmitter = te;
} }
@OnlyIn(Dist.CLIENT) public long getReportingValue() {
public void setTextField(final NumberEntryWidget level) { return reportingValue;
this.textField = level;
this.textField.setValue(this.EmitterValue);
} }
public void setLevel(final long l, final PlayerEntity player) { public void setReportingValue(long reportingValue) {
this.lvlEmitter.setReportingValue(l); if (isClient()) {
this.EmitterValue = l; if (reportingValue != this.reportingValue) {
this.reportingValue = reportingValue;
NetworkHandler.instance()
.sendToServer(new ConfigValuePacket("FluidLevelEmitter.Value", String.valueOf(reportingValue)));
}
} else {
this.lvlEmitter.setReportingValue(reportingValue);
}
} }
@Override @Override
@@ -74,8 +79,7 @@ public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
this.EmitterValue = this.lvlEmitter.getReportingValue();
this.setRedStoneMode( this.setRedStoneMode(
(RedstoneMode) this.getUpgradeable().getConfigManager().getSetting(Settings.REDSTONE_EMITTER)); (RedstoneMode) this.getUpgradeable().getConfigManager().getSetting(Settings.REDSTONE_EMITTER));
} }
@@ -83,15 +87,6 @@ public class FluidLevelEmitterContainer extends FluidConfigurableContainer {
this.standardDetectAndSendChanges(); 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 @Override
public IAEFluidTank getFluidConfigInventory() { public IAEFluidTank getFluidConfigInventory() {
return this.lvlEmitter.getConfig(); return this.lvlEmitter.getConfig();
@@ -128,7 +128,7 @@ public class FluidStorageBusContainer extends FluidConfigurableContainer {
public void detectAndSendChanges() { public void detectAndSendChanges() {
this.verifyPermissions(SecurityPermissions.BUILD, false); this.verifyPermissions(SecurityPermissions.BUILD, false);
if (Platform.isServer()) { if (isServer()) {
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE)); this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
this.setReadWriteMode( this.setReadWriteMode(
(AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS)); (AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS));
@@ -119,7 +119,7 @@ public class FluidTerminalContainer extends AEBaseContainer
this.clientCM.registerSetting(Settings.SORT_BY, SortOrder.NAME); this.clientCM.registerSetting(Settings.SORT_BY, SortOrder.NAME);
this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING); this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING);
this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL); this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL);
if (Platform.isServer()) { if (isServer()) {
this.serverCM = terminal.getConfigManager(); this.serverCM = terminal.getConfigManager();
this.monitor = terminal this.monitor = terminal
.getInventory(Api.instance().storage().getStorageChannel(IFluidStorageChannel.class)); .getInventory(Api.instance().storage().getStorageChannel(IFluidStorageChannel.class));
@@ -191,7 +191,7 @@ public class FluidTerminalContainer extends AEBaseContainer
} }
private void queueInventory(final IContainerListener c) { private void queueInventory(final IContainerListener c) {
if (Platform.isServer() && c instanceof PlayerEntity && this.monitor != null) { if (isServer() && c instanceof PlayerEntity && this.monitor != null) {
try { try {
MEFluidInventoryUpdatePacket piu = new MEFluidInventoryUpdatePacket(); MEFluidInventoryUpdatePacket piu = new MEFluidInventoryUpdatePacket();
final IItemList<IAEFluidStack> monitorCache = this.monitor.getStorageList(); final IItemList<IAEFluidStack> monitorCache = this.monitor.getStorageList();
@@ -216,14 +216,14 @@ public class FluidTerminalContainer extends AEBaseContainer
@Override @Override
public IConfigManager getConfigManager() { public IConfigManager getConfigManager() {
if (Platform.isServer()) { if (isServer()) {
return this.serverCM; return this.serverCM;
} }
return this.clientCM; return this.clientCM;
} }
public void setTargetStack(final IAEFluidStack stack) { public void setTargetStack(final IAEFluidStack stack) {
if (Platform.isClient()) { if (isClient()) {
if (stack == null && this.clientRequestedTargetFluid == null) { if (stack == null && this.clientRequestedTargetFluid == null) {
return; return;
} }
@@ -246,7 +246,7 @@ public class FluidTerminalContainer extends AEBaseContainer
@Override @Override
public void detectAndSendChanges() { public void detectAndSendChanges() {
if (Platform.isServer()) { if (isServer()) {
if (this.monitor != this.terminal if (this.monitor != this.terminal
.getInventory(Api.instance().storage().getStorageChannel(IFluidStorageChannel.class))) { .getInventory(Api.instance().storage().getStorageChannel(IFluidStorageChannel.class))) {
this.setValidContainer(false); this.setValidContainer(false);
@@ -13,6 +13,14 @@ import appeng.core.AELog;
import appeng.util.Platform; import appeng.util.Platform;
public class AEFluidInventory implements IAEFluidTank { 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 IAEFluidStack[] fluids;
private final IAEFluidInventory handler; private final IAEFluidInventory handler;
private final int capacity; private final int capacity;
@@ -31,13 +39,13 @@ public class AEFluidInventory implements IAEFluidTank {
public void setFluidInSlot(final int slot, final IAEFluidStack fluid) { public void setFluidInSlot(final int slot, final IAEFluidStack fluid) {
if (slot >= 0 && slot < this.getSlots()) { if (slot >= 0 && slot < this.getSlots()) {
if (Objects.equals(this.fluids[slot], fluid)) { 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.fluids[slot].setStackSize(Math.min(fluid.getStackSize(), this.capacity));
this.onContentChanged(slot); this.onContentChanged(slot);
} }
} else { } else {
if (fluid == null) { if (fluid == EMPTY_AE_FLUIDSTACK) {
this.fluids[slot] = null; this.fluids[slot] = EMPTY_AE_FLUIDSTACK;
} else { } else {
this.fluids[slot] = fluid.copy(); this.fluids[slot] = fluid.copy();
this.fluids[slot].setStackSize(Math.min(fluid.getStackSize(), this.capacity)); this.fluids[slot].setStackSize(Math.min(fluid.getStackSize(), this.capacity));
@@ -59,7 +67,7 @@ public class AEFluidInventory implements IAEFluidTank {
if (slot >= 0 && slot < this.getSlots()) { if (slot >= 0 && slot < this.getSlots()) {
return this.fluids[slot]; return this.fluids[slot];
} }
return null; return EMPTY_AE_FLUIDSTACK;
} }
@Override @Override
@@ -78,12 +86,12 @@ public class AEFluidInventory implements IAEFluidTank {
if (tank < 0 || tank >= fluids.length) { if (tank < 0 || tank >= fluids.length) {
return FluidStack.EMPTY; return FluidStack.EMPTY;
} }
return fluids[tank] == null ? FluidStack.EMPTY : fluids[tank].getFluidStack(); return fluids[tank] == EMPTY_AE_FLUIDSTACK ? FluidStack.EMPTY : fluids[tank].getFluidStack();
} }
@Override @Override
public int getTankCapacity(int tank) { public int getTankCapacity(int tank) {
return Math.min(this.capacity, Integer.MAX_VALUE); return this.capacity;
} }
@Override @Override
@@ -98,20 +106,20 @@ public class AEFluidInventory implements IAEFluidTank {
final IAEFluidStack fluid = this.fluids[slot]; final IAEFluidStack fluid = this.fluids[slot];
if (fluid != null && !fluid.getFluidStack().equals(resource)) { if (fluid != EMPTY_AE_FLUIDSTACK && !fluid.getFluidStack().equals(resource)) {
return 0; return 0;
} }
int amountToStore = this.capacity; int amountToStore = this.capacity;
if (fluid != null) { if (fluid != EMPTY_AE_FLUIDSTACK) {
amountToStore -= fluid.getStackSize(); amountToStore -= fluid.getStackSize();
} }
amountToStore = Math.min(amountToStore, resource.getAmount()); amountToStore = Math.min(amountToStore, resource.getAmount());
if (doFill) { if (doFill) {
if (fluid == null) { if (fluid == EMPTY_AE_FLUIDSTACK) {
this.setFluidInSlot(slot, AEFluidStack.fromFluidStack(resource)); this.setFluidInSlot(slot, AEFluidStack.fromFluidStack(resource));
} else { } else {
fluid.setStackSize(fluid.getStackSize() + amountToStore); fluid.setStackSize(fluid.getStackSize() + amountToStore);
@@ -141,14 +149,14 @@ public class AEFluidInventory implements IAEFluidTank {
int amountToStore = this.capacity; int amountToStore = this.capacity;
if (fluid != null) { if (fluid != EMPTY_AE_FLUIDSTACK) {
amountToStore -= fluid.getStackSize(); amountToStore -= fluid.getStackSize();
} }
amountToStore = Math.min(amountToStore, resource.getAmount()); amountToStore = Math.min(amountToStore, resource.getAmount());
if (action == FluidAction.EXECUTE) { if (action == FluidAction.EXECUTE) {
if (fluid == null) { if (fluid == EMPTY_AE_FLUIDSTACK) {
this.setFluidInSlot(slot, AEFluidStack.fromFluidStack(resource)); this.setFluidInSlot(slot, AEFluidStack.fromFluidStack(resource));
} else { } else {
fluid.setStackSize(fluid.getStackSize() + amountToStore); fluid.setStackSize(fluid.getStackSize() + amountToStore);
@@ -170,7 +178,7 @@ public class AEFluidInventory implements IAEFluidTank {
FluidStack totalDrained = FluidStack.EMPTY; FluidStack totalDrained = FluidStack.EMPTY;
for (int slot = 0; slot < this.getSlots(); ++slot) { for (int slot = 0; slot < this.getSlots(); ++slot) {
FluidStack drain = this.drain(slot, resource, action == FluidAction.EXECUTE); FluidStack drain = this.drain(slot, resource, action == FluidAction.EXECUTE);
if (drain != null) { if (!drain.isEmpty()) {
if (totalDrained.isEmpty()) { if (totalDrained.isEmpty()) {
totalDrained = drain; totalDrained = drain;
} else { } else {
@@ -205,7 +213,7 @@ public class AEFluidInventory implements IAEFluidTank {
FluidStack copy = totalDrained.copy(); FluidStack copy = totalDrained.copy();
copy.setAmount(toDrain); copy.setAmount(toDrain);
FluidStack drain = this.drain(slot, copy, action == FluidAction.EXECUTE); FluidStack drain = this.drain(slot, copy, action == FluidAction.EXECUTE);
if (drain != null) { if (!drain.isEmpty()) {
totalDrained.setAmount(totalDrained.getAmount() + drain.getAmount()); totalDrained.setAmount(totalDrained.getAmount() + drain.getAmount());
toDrain -= drain.getAmount(); toDrain -= drain.getAmount();
} }
@@ -220,7 +228,7 @@ public class AEFluidInventory implements IAEFluidTank {
private int indexOfFluid(FluidStack resource) { private int indexOfFluid(FluidStack resource) {
for (int slot = 0; slot < fluids.length; slot++) { for (int slot = 0; slot < fluids.length; slot++) {
if (fluids[slot] != null && fluids[slot].getFluidStack().isFluidEqual(resource)) { if (fluids[slot] != EMPTY_AE_FLUIDSTACK && fluids[slot].getFluidStack().isFluidEqual(resource)) {
return slot; return slot;
} }
} }
@@ -229,7 +237,7 @@ public class AEFluidInventory implements IAEFluidTank {
private int indexOfEmptySlot() { private int indexOfEmptySlot() {
for (int slot = 0; slot < fluids.length; slot++) { for (int slot = 0; slot < fluids.length; slot++) {
if (fluids[slot] == null) { if (fluids[slot] == EMPTY_AE_FLUIDSTACK) {
return slot; return slot;
} }
} }
@@ -238,16 +246,16 @@ public class AEFluidInventory implements IAEFluidTank {
public FluidStack drain(final int slot, final FluidStack resource, final boolean doDrain) { public FluidStack drain(final int slot, final FluidStack resource, final boolean doDrain) {
final IAEFluidStack fluid = this.fluids[slot]; final IAEFluidStack fluid = this.fluids[slot];
if (resource.isEmpty() || fluid == null || !fluid.getFluidStack().equals(resource)) { if (resource.isEmpty() || fluid == EMPTY_AE_FLUIDSTACK || !fluid.getFluidStack().equals(resource)) {
return null; return FluidStack.EMPTY;
} }
return this.drain(slot, resource.getAmount(), doDrain); return this.drain(slot, resource.getAmount(), doDrain);
} }
public FluidStack drain(final int slot, final int maxDrain, boolean doDrain) { public FluidStack drain(final int slot, final int maxDrain, boolean doDrain) {
final IAEFluidStack fluid = this.fluids[slot]; final IAEFluidStack fluid = this.fluids[slot];
if (fluid == null || maxDrain <= 0) { if (fluid == EMPTY_AE_FLUIDSTACK || maxDrain <= 0) {
return null; return FluidStack.EMPTY;
} }
int drained = maxDrain; int drained = maxDrain;
@@ -259,7 +267,7 @@ public class AEFluidInventory implements IAEFluidTank {
if (doDrain) { if (doDrain) {
fluid.setStackSize(fluid.getStackSize() - drained); fluid.setStackSize(fluid.getStackSize() - drained);
if (fluid.getStackSize() <= 0) { if (fluid.getStackSize() <= 0) {
this.fluids[slot] = null; this.fluids[slot] = EMPTY_AE_FLUIDSTACK;
} }
this.onContentChanged(slot); this.onContentChanged(slot);
} }
@@ -277,7 +285,7 @@ public class AEFluidInventory implements IAEFluidTank {
try { try {
final CompoundNBT c = new CompoundNBT(); final CompoundNBT c = new CompoundNBT();
if (this.fluids[x] != null) { if (this.fluids[x] != EMPTY_AE_FLUIDSTACK) {
this.fluids[x].writeToNBT(c); this.fluids[x].writeToNBT(c);
} }
@@ -78,7 +78,7 @@ public class CraftingStorageTileEntity extends CraftingTileEntity {
return 0; return 0;
} }
final AbstractCraftingUnitBlock unit = (AbstractCraftingUnitBlock) this.world.getBlockState(this.pos) final AbstractCraftingUnitBlock<?> unit = (AbstractCraftingUnitBlock<?>) this.world.getBlockState(this.pos)
.getBlock(); .getBlock();
switch (unit.type) { switch (unit.type) {
default: default:
@@ -289,6 +289,8 @@
"gui.appliedenergistics2.With": "with", "gui.appliedenergistics2.With": "with",
"gui.appliedenergistics2.Yellow": "Yellow", "gui.appliedenergistics2.Yellow": "Yellow",
"gui.appliedenergistics2.Yes": "Yes", "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.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.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.", "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: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB