mirror of
https://github.com/GTNewHorizons/Applied-Energistics-2-Unofficial.git
synced 2026-11-14 01:14:11 +00:00
1254 lines
48 KiB
Java
1254 lines
48 KiB
Java
/*
|
|
* 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.implementations;
|
|
|
|
import static appeng.util.item.AEItemStackType.ITEM_STACK_TYPE;
|
|
|
|
import java.io.IOException;
|
|
import java.text.NumberFormat;
|
|
import java.util.EnumSet;
|
|
import java.util.IdentityHashMap;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.gui.GuiButton;
|
|
import net.minecraft.client.gui.GuiScreen;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.entity.player.InventoryPlayer;
|
|
import net.minecraft.inventory.Slot;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.util.EnumChatFormatting;
|
|
import net.minecraft.util.IIcon;
|
|
import net.minecraft.util.ResourceLocation;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.lwjgl.input.Keyboard;
|
|
import org.lwjgl.input.Mouse;
|
|
|
|
import appeng.api.config.ActionItems;
|
|
import appeng.api.config.CraftingStatus;
|
|
import appeng.api.config.PinSectionOrder;
|
|
import appeng.api.config.PinsRows;
|
|
import appeng.api.config.SearchBoxFocusPriority;
|
|
import appeng.api.config.SearchBoxMode;
|
|
import appeng.api.config.Settings;
|
|
import appeng.api.config.TerminalFontSize;
|
|
import appeng.api.config.TerminalStyle;
|
|
import appeng.api.config.ViewItems;
|
|
import appeng.api.config.YesNo;
|
|
import appeng.api.implementations.tiles.IViewCellStorage;
|
|
import appeng.api.storage.ITerminalHost;
|
|
import appeng.api.storage.ITerminalPins;
|
|
import appeng.api.storage.ITerminalTypeFilterProvider;
|
|
import appeng.api.storage.data.AEStackTypeRegistry;
|
|
import appeng.api.storage.data.IAEItemStack;
|
|
import appeng.api.storage.data.IAEStack;
|
|
import appeng.api.storage.data.IAEStackType;
|
|
import appeng.api.util.IConfigManager;
|
|
import appeng.api.util.IConfigurableObject;
|
|
import appeng.client.ActionKey;
|
|
import appeng.client.gui.AEBaseGui;
|
|
import appeng.client.gui.slots.VirtualMEMonitorableSlot;
|
|
import appeng.client.gui.slots.VirtualMEPatternSlot;
|
|
import appeng.client.gui.slots.VirtualMEPinSlot;
|
|
import appeng.client.gui.slots.VirtualMESlot;
|
|
import appeng.client.gui.widgets.GuiImgButton;
|
|
import appeng.client.gui.widgets.GuiScrollbar;
|
|
import appeng.client.gui.widgets.GuiTabButton;
|
|
import appeng.client.gui.widgets.IDropToFillTextField;
|
|
import appeng.client.gui.widgets.ISortSource;
|
|
import appeng.client.gui.widgets.MEGuiTextField;
|
|
import appeng.client.gui.widgets.TypeToggleButton;
|
|
import appeng.client.me.ItemRepo;
|
|
import appeng.container.AEBaseContainer;
|
|
import appeng.container.implementations.ContainerMEMonitorable;
|
|
import appeng.container.slot.AppEngSlot;
|
|
import appeng.container.slot.SlotCraftingMatrix;
|
|
import appeng.container.slot.SlotFakeCraftingMatrix;
|
|
import appeng.container.slot.SlotRestrictedInput;
|
|
import appeng.core.AEConfig;
|
|
import appeng.core.AELog;
|
|
import appeng.core.CommonHelper;
|
|
import appeng.core.localization.ButtonToolTips;
|
|
import appeng.core.localization.ColorUtils;
|
|
import appeng.core.localization.GuiText;
|
|
import appeng.core.sync.GuiBridge;
|
|
import appeng.core.sync.network.NetworkHandler;
|
|
import appeng.core.sync.packets.PacketInventoryAction;
|
|
import appeng.core.sync.packets.PacketMonitorableAction;
|
|
import appeng.core.sync.packets.PacketMonitorableTypeFilter;
|
|
import appeng.core.sync.packets.PacketPinsUpdate;
|
|
import appeng.core.sync.packets.PacketSwitchGuis;
|
|
import appeng.core.sync.packets.PacketValueConfig;
|
|
import appeng.helpers.IPinsHandler;
|
|
import appeng.helpers.InventoryAction;
|
|
import appeng.helpers.MonitorableAction;
|
|
import appeng.integration.IntegrationRegistry;
|
|
import appeng.integration.IntegrationType;
|
|
import appeng.integration.modules.NEI;
|
|
import appeng.items.storage.ItemViewCell;
|
|
import appeng.me.cache.ItemFlowGridCache.FlowRate;
|
|
import appeng.util.AEStackTypeFilter;
|
|
import appeng.util.FlowRateFormatter;
|
|
import appeng.util.IConfigManagerHost;
|
|
import appeng.util.Platform;
|
|
import appeng.util.item.AEItemStack;
|
|
import it.unimi.dsi.fastutil.objects.Reference2BooleanMap;
|
|
|
|
public class GuiMEMonitorable extends AEBaseGui
|
|
implements ISortSource, IConfigManagerHost, IDropToFillTextField, IPinsHandler {
|
|
|
|
public static int craftingGridOffsetX;
|
|
public static int craftingGridOffsetY;
|
|
|
|
// Keybind use can be keyboard or mouse, both redirect to this.handleVirtualSlotClick
|
|
// if key/mouseButton == this.mc.gameSettings.keyBindPickBlock.getKeyCode()
|
|
public static final int keyBindPickBlockAction = 1_000_101;
|
|
|
|
private static String memoryText = "";
|
|
private final ItemRepo repo;
|
|
protected int offsetRepoX = 9;
|
|
protected int offsetRepoY = 18;
|
|
private final int MAGIC_HEIGHT_NUMBER = 114 + 1;
|
|
private final int lowerTextureOffset = 0;
|
|
private final IConfigManager configSrc;
|
|
private final boolean viewCell;
|
|
private final ItemStack[] myCurrentViewCells = new ItemStack[5];
|
|
private final ContainerMEMonitorable monitorableContainer;
|
|
private GuiTabButton craftingStatusBtn;
|
|
private GuiImgButton craftingStatusImgBtn;
|
|
protected final MEGuiTextField searchField;
|
|
private GuiText myName;
|
|
private int perRow = 9;
|
|
private int reservedSpace = 0;
|
|
private boolean customSortOrder = true;
|
|
protected int rows = 0;
|
|
private int standardSize;
|
|
private GuiImgButton ViewBox;
|
|
private GuiImgButton SortByBox;
|
|
private GuiImgButton SortDirBox;
|
|
private GuiImgButton searchBoxSettings;
|
|
private GuiImgButton terminalStyleBox;
|
|
private GuiImgButton searchStringSave;
|
|
private GuiImgButton pinsStateButton;
|
|
private final Map<TypeToggleButton, IAEStackType<?>> typeToggleButtons = new IdentityHashMap<>();
|
|
private boolean canBeAutoFocused = false;
|
|
private boolean isAutoFocused = false;
|
|
protected int currentMouseX = 0;
|
|
protected int currentMouseY = 0;
|
|
private PinsRows craftingPinsRows;
|
|
private PinsRows playerPinsRows;
|
|
public final boolean hasPinHost;
|
|
private boolean enableShiftPause = true;
|
|
private boolean needsViewUpdate = false;
|
|
private int scrollBarRepoSize = -1;
|
|
|
|
protected VirtualMEPinSlot[] pinSlots = null;
|
|
protected VirtualMEMonitorableSlot[] monitorableSlots = null;
|
|
@Nullable
|
|
protected AEStackTypeFilter typeFilters;
|
|
|
|
public GuiMEMonitorable(final InventoryPlayer inventoryPlayer, final ITerminalHost te) {
|
|
this(inventoryPlayer, te, new ContainerMEMonitorable(inventoryPlayer, te));
|
|
}
|
|
|
|
public GuiMEMonitorable(final InventoryPlayer inventoryPlayer, final ITerminalHost te,
|
|
final ContainerMEMonitorable c) {
|
|
|
|
super(c);
|
|
|
|
final GuiScrollbar scrollbar = new GuiScrollbar();
|
|
this.setScrollBar(scrollbar);
|
|
this.repo = new ItemRepo(scrollbar, this);
|
|
|
|
this.xSize = 195;
|
|
this.ySize = 204;
|
|
|
|
this.standardSize = this.xSize;
|
|
|
|
this.configSrc = ((IConfigurableObject) this.inventorySlots).getConfigManager();
|
|
|
|
craftingPinsRows = PinsRows.DISABLED;
|
|
playerPinsRows = PinsRows.DISABLED;
|
|
|
|
(this.monitorableContainer = (ContainerMEMonitorable) this.inventorySlots).setGui(this);
|
|
|
|
this.viewCell = te instanceof IViewCellStorage;
|
|
|
|
this.myName = te.getHostName();
|
|
|
|
hasPinHost = te instanceof ITerminalPins;
|
|
|
|
this.searchField = new MEGuiTextField(90, 12, ButtonToolTips.SearchStringTooltip.getLocal()) {
|
|
|
|
@Override
|
|
public void onTextChange(final String oldText) {
|
|
final String text = getText();
|
|
repo.setSearchString(text.trim());
|
|
repo.updateView();
|
|
|
|
if (AEConfig.instance.preserveSearchBar) monitorableContainer.saveSearchString(this.getText());
|
|
}
|
|
};
|
|
|
|
NEI.searchField.putFormatter(this.searchField);
|
|
|
|
if (te instanceof ITerminalTypeFilterProvider) {
|
|
this.typeFilters = new AEStackTypeFilter();
|
|
}
|
|
}
|
|
|
|
public void postUpdate(final List<IAEStack<?>> list) {
|
|
for (final IAEStack<?> is : list) {
|
|
this.repo.postUpdate(is);
|
|
}
|
|
|
|
this.needsViewUpdate = true;
|
|
}
|
|
|
|
public void updateFlowRates(final Map<IAEStack<?>, FlowRate> rates) {
|
|
this.repo.updateFlowRates(rates);
|
|
this.needsViewUpdate = true;
|
|
}
|
|
|
|
private void setScrollBar() {
|
|
this.scrollBarRepoSize = this.repo.size();
|
|
this.getScrollBar().setTop(this.offsetRepoY).setLeft(166 + this.offsetRepoX).setHeight(this.rows * 18 - 2);
|
|
int totalPinRows = craftingPinsRows.ordinal() + playerPinsRows.ordinal();
|
|
this.getScrollBar().setRange(
|
|
0,
|
|
(this.repo.size() + totalPinRows * 9 + this.perRow - 1) / this.perRow - this.rows,
|
|
Math.max(1, this.rows / 6));
|
|
}
|
|
|
|
@Override
|
|
protected void actionPerformed(final GuiButton btn) {
|
|
if (btn instanceof final TypeToggleButton tbtn) {
|
|
final IAEStackType<?> type = this.typeToggleButtons.get(tbtn);
|
|
if (type != null && this.typeFilters != null) {
|
|
// Optimistic client-side feedback; server will sync authoritative state shortly.
|
|
final boolean next = !this.typeFilters.isEnabled(type);
|
|
this.typeFilters.setEnabled(type, next);
|
|
tbtn.setEnabled(next);
|
|
this.repo.updateView();
|
|
|
|
try {
|
|
NetworkHandler.instance
|
|
.sendToServer(new PacketMonitorableTypeFilter(this.typeFilters.getImmutableFilters(), this.inventorySlots.windowId));
|
|
} catch (final IOException e) {
|
|
AELog.debug(e);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (actionPerformedCustomButtons(btn)) return;
|
|
|
|
if (btn == this.craftingStatusBtn || btn == this.craftingStatusImgBtn) {
|
|
NetworkHandler.instance.sendToServer(new PacketSwitchGuis(GuiBridge.GUI_CRAFTING_STATUS));
|
|
}
|
|
|
|
if (btn == this.pinsStateButton) {
|
|
try {
|
|
boolean rmb = Mouse.isButtonDown(1);
|
|
boolean ctrl = GuiScreen.isCtrlKeyDown();
|
|
int maxC = AEConfig.instance.maxCraftingPinRows;
|
|
int maxP = AEConfig.instance.maxPlayerPinRows;
|
|
int c = Math.min(craftingPinsRows.ordinal(), maxC);
|
|
int p = Math.min(playerPinsRows.ordinal(), maxP);
|
|
if (ctrl) {
|
|
if (rmb) c = Math.max(0, c - 1);
|
|
else c = Math.min(maxC, c + 1);
|
|
} else {
|
|
if (rmb) p = Math.max(0, p - 1);
|
|
else p = Math.min(maxP, p + 1);
|
|
}
|
|
if (c + p >= rows) return;
|
|
NetworkHandler.instance.sendToServer(new PacketPinsUpdate(
|
|
PinsRows.fromOrdinal(c), PinsRows.fromOrdinal(p)));
|
|
} catch (final IOException e) {
|
|
AELog.debug(e);
|
|
}
|
|
reinitalize();
|
|
return;
|
|
}
|
|
|
|
if (!(btn instanceof GuiImgButton iBtn) || iBtn.getSetting() == Settings.ACTIONS) return;
|
|
|
|
final Enum cv = iBtn.getCurrentValue();
|
|
final boolean backwards = Mouse.isButtonDown(1);
|
|
|
|
EnumSet<?> validOptions = iBtn.getSetting().getPossibleValues();
|
|
if (btn == this.ViewBox && !this.monitorableContainer.flowTrackingActive) {
|
|
validOptions = EnumSet.copyOf(validOptions);
|
|
validOptions.remove(ViewItems.FLOWING);
|
|
}
|
|
|
|
final Enum next = Platform.rotateEnum(cv, backwards, validOptions);
|
|
|
|
if (btn == this.terminalStyleBox) {
|
|
AEConfig.instance.settings.putSetting(iBtn.getSetting(), next);
|
|
} else if (btn == this.searchBoxSettings) {
|
|
AEConfig.instance.settings.putSetting(iBtn.getSetting(), next);
|
|
} else if (btn == this.searchStringSave) {
|
|
AEConfig.instance.preserveSearchBar = next == YesNo.YES;
|
|
} else {
|
|
try {
|
|
NetworkHandler.instance.sendToServer(new PacketValueConfig(iBtn.getSetting().name(), next.name()));
|
|
} catch (final IOException e) {
|
|
AELog.debug(e);
|
|
}
|
|
}
|
|
|
|
iBtn.set(next);
|
|
|
|
if (next.getClass() == SearchBoxMode.class || next.getClass() == TerminalStyle.class) {
|
|
this.reinitalize();
|
|
}
|
|
}
|
|
|
|
private int createPinSection(int slotIdx, int sectionRows, int pinsPerRow, int rowOffset, boolean isCrafting) {
|
|
int baseIndex = isCrafting ? 0 : appeng.items.contents.PinList.PLAYER_OFFSET;
|
|
for (int y = 0; y < sectionRows; y++) {
|
|
for (int x = 0; x < pinsPerRow; x++) {
|
|
VirtualMEPinSlot slot = new VirtualMEPinSlot(
|
|
this.offsetRepoX + x * 18,
|
|
(rowOffset + y) * 18 + this.offsetRepoY,
|
|
this.repo,
|
|
baseIndex + y * pinsPerRow + x,
|
|
this::checkTypeFilter,
|
|
isCrafting);
|
|
this.pinSlots[slotIdx++] = slot;
|
|
this.registerVirtualSlots(slot);
|
|
}
|
|
}
|
|
return slotIdx;
|
|
}
|
|
|
|
private void adjustPinsSize() {
|
|
final int pinMaxSize = rows - 1;
|
|
int craft = Math.min(craftingPinsRows.ordinal(), AEConfig.instance.maxCraftingPinRows);
|
|
int player = Math.min(playerPinsRows.ordinal(), AEConfig.instance.maxPlayerPinRows);
|
|
int totalPinRows = craft + player;
|
|
if (totalPinRows <= pinMaxSize) return;
|
|
|
|
try {
|
|
if (player > pinMaxSize) {
|
|
player = pinMaxSize;
|
|
craft = 0;
|
|
} else {
|
|
craft = Math.min(craft, pinMaxSize - player);
|
|
}
|
|
NetworkHandler.instance
|
|
.sendToServer(new PacketPinsUpdate(PinsRows.fromOrdinal(craft), PinsRows.fromOrdinal(player)));
|
|
} catch (final IOException e) {
|
|
AELog.debug(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void reinitalize() {
|
|
memoryText = this.searchField.getText();
|
|
super.reinitalize();
|
|
}
|
|
|
|
private boolean checkTypeFilter(IAEStackType<?> type) {
|
|
return this.typeFilters == null || this.typeFilters.isEnabled(type);
|
|
}
|
|
|
|
@Override
|
|
public void initGui() {
|
|
Keyboard.enableRepeatEvents(true);
|
|
|
|
this.perRow = AEConfig.instance.getConfigManager().getSetting(Settings.TERMINAL_STYLE) != TerminalStyle.FULL ? 9
|
|
: 9 + ((this.width - this.standardSize) / 18);
|
|
this.rows = calculateRowsCount();
|
|
|
|
// make sure we have space at least for one row of normal slots, because pins not adjusted by scroll bar
|
|
adjustPinsSize();
|
|
|
|
super.initGui();
|
|
|
|
int maxCrafting = AEConfig.instance.maxCraftingPinRows;
|
|
int maxPlayer = AEConfig.instance.maxPlayerPinRows;
|
|
int craftingRows = Math.min(craftingPinsRows.ordinal(), maxCrafting);
|
|
int playerRows = Math.min(playerPinsRows.ordinal(), maxPlayer);
|
|
int pinMaxSize = Math.max(0, this.rows - 1);
|
|
int totalRequested = craftingRows + playerRows;
|
|
if (totalRequested > pinMaxSize) {
|
|
if (playerRows > pinMaxSize) {
|
|
playerRows = pinMaxSize;
|
|
craftingRows = 0;
|
|
} else {
|
|
craftingRows = Math.min(craftingRows, pinMaxSize - playerRows);
|
|
}
|
|
}
|
|
int pinsRows = craftingRows + playerRows;
|
|
final int pinsPerRow = 9;
|
|
this.pinSlots = new VirtualMEPinSlot[craftingRows * pinsPerRow + playerRows * pinsPerRow];
|
|
int slotIdx = 0;
|
|
boolean playerFirst = AEConfig.instance.pinSectionOrder == PinSectionOrder.PLAYER_FIRST;
|
|
int firstRows = playerFirst ? playerRows : craftingRows;
|
|
int secondRows = playerFirst ? craftingRows : playerRows;
|
|
boolean firstIsCrafting = !playerFirst;
|
|
slotIdx = createPinSection(slotIdx, firstRows, pinsPerRow, 0, firstIsCrafting);
|
|
slotIdx = createPinSection(slotIdx, secondRows, pinsPerRow, firstRows, !firstIsCrafting);
|
|
|
|
int normalSlotRows = Math.max(0, this.rows - pinsRows);
|
|
this.monitorableSlots = new VirtualMEMonitorableSlot[normalSlotRows * this.perRow];
|
|
for (int y = 0; y < normalSlotRows; y++) {
|
|
for (int x = 0; x < this.perRow; x++) {
|
|
VirtualMEMonitorableSlot slot = new VirtualMEMonitorableSlot(
|
|
this.offsetRepoX + x * 18,
|
|
this.offsetRepoY + y * 18 + pinsRows * 18,
|
|
this.repo,
|
|
y * this.perRow + x,
|
|
this::checkTypeFilter);
|
|
this.monitorableSlots[y * this.perRow + x] = slot;
|
|
this.registerVirtualSlots(slot);
|
|
}
|
|
}
|
|
|
|
if (AEConfig.instance.getConfigManager().getSetting(Settings.TERMINAL_STYLE) != TerminalStyle.FULL) {
|
|
this.xSize = this.standardSize + ((this.perRow - 9) * 18);
|
|
} else {
|
|
this.xSize = this.standardSize;
|
|
}
|
|
|
|
// full size : 204
|
|
// extra slots : 72
|
|
// slot 18
|
|
|
|
this.ySize = MAGIC_HEIGHT_NUMBER + this.rows * 18 + this.reservedSpace;
|
|
final int unusedSpace = this.height - this.ySize;
|
|
this.guiTop = (int) Math.floor(unusedSpace / (unusedSpace < 0 ? 3.8f : 2.0f));
|
|
|
|
int offset = this.guiTop + 8;
|
|
|
|
buttonList.clear();
|
|
|
|
initTypeToggleButtons(this.guiLeft - 36, offset);
|
|
|
|
if (this.customSortOrder) {
|
|
this.buttonList.add(
|
|
this.SortByBox = new GuiImgButton(
|
|
this.guiLeft - 18,
|
|
offset,
|
|
Settings.SORT_BY,
|
|
this.configSrc.getSetting(Settings.SORT_BY)));
|
|
offset += 20;
|
|
}
|
|
|
|
if (this.viewCell) {
|
|
this.buttonList.add(
|
|
this.ViewBox = new GuiImgButton(
|
|
this.guiLeft - 18,
|
|
offset,
|
|
Settings.VIEW_MODE,
|
|
this.configSrc.getSetting(Settings.VIEW_MODE)));
|
|
offset += 20;
|
|
}
|
|
|
|
this.buttonList.add(
|
|
this.SortDirBox = new GuiImgButton(
|
|
this.guiLeft - 18,
|
|
offset,
|
|
Settings.SORT_DIRECTION,
|
|
this.configSrc.getSetting(Settings.SORT_DIRECTION)));
|
|
offset += 20;
|
|
|
|
this.buttonList.add(
|
|
this.searchBoxSettings = new GuiImgButton(
|
|
this.guiLeft - 18,
|
|
offset,
|
|
Settings.SEARCH_MODE,
|
|
AEConfig.instance.settings.getSetting(Settings.SEARCH_MODE)));
|
|
offset += 20;
|
|
|
|
this.buttonList.add(
|
|
this.searchStringSave = new GuiImgButton(
|
|
this.guiLeft - 18,
|
|
offset,
|
|
Settings.SAVE_SEARCH,
|
|
AEConfig.instance.preserveSearchBar ? YesNo.YES : YesNo.NO));
|
|
offset += 20;
|
|
|
|
if (!(this instanceof GuiMEPortableCell)) {
|
|
this.buttonList.add(
|
|
this.terminalStyleBox = new GuiImgButton(
|
|
this.guiLeft - 18,
|
|
offset,
|
|
Settings.TERMINAL_STYLE,
|
|
AEConfig.instance.settings.getSetting(Settings.TERMINAL_STYLE)));
|
|
offset += 20;
|
|
}
|
|
|
|
initCustomButtons(this.guiLeft - 18, offset);
|
|
|
|
if (this.viewCell) {
|
|
if (AEConfig.instance.getConfigManager().getSetting(Settings.CRAFTING_STATUS)
|
|
.equals(CraftingStatus.BUTTON)) {
|
|
this.buttonList.add(
|
|
this.craftingStatusImgBtn = new GuiImgButton(
|
|
this.guiLeft - 18,
|
|
offset,
|
|
Settings.CRAFTING_STATUS,
|
|
AEConfig.instance.settings.getSetting(Settings.CRAFTING_STATUS)));
|
|
} else {
|
|
this.buttonList.add(
|
|
this.craftingStatusBtn = new GuiTabButton(
|
|
this.guiLeft + 170,
|
|
this.guiTop - 4,
|
|
2 + 11 * 16,
|
|
GuiText.CraftingStatus.getLocal(),
|
|
itemRender));
|
|
this.craftingStatusBtn.setHideEdge(13); // GuiTabButton implementation //
|
|
}
|
|
}
|
|
|
|
if (hasPinHost) {
|
|
this.buttonList.add(
|
|
this.pinsStateButton = new GuiImgButton(
|
|
getPinButtonX(),
|
|
getPinButtonY(),
|
|
Settings.ACTIONS,
|
|
ActionItems.PINS));
|
|
this.repo.setVisiblePinRows(this.craftingPinsRows.ordinal(), this.playerPinsRows.ordinal());
|
|
}
|
|
|
|
// Enum setting = AEConfig.INSTANCE.getSetting( "Terminal", SearchBoxMode.class, SearchBoxMode.AUTOSEARCH );
|
|
final Enum searchMode = AEConfig.instance.settings.getSetting(Settings.SEARCH_MODE);
|
|
this.canBeAutoFocused = SearchBoxMode.AUTOSEARCH == searchMode || SearchBoxMode.NEI_AUTOSEARCH == searchMode;
|
|
|
|
this.searchField.x = this.guiLeft + this.offsetRepoX + 71;
|
|
this.searchField.y = this.guiTop + 4;
|
|
this.searchField.setFocused(this.canBeAutoFocused);
|
|
this.isAutoFocused = this.canBeAutoFocused;
|
|
|
|
if (this.isSubGui()) {
|
|
this.searchField.setText(memoryText);
|
|
} else if (AEConfig.instance.preserveSearchBar) {
|
|
final String localMemoryText = this.monitorableContainer.getSavedSearchString();
|
|
final String mem = localMemoryText == null ? memoryText : localMemoryText;
|
|
this.searchField.setText(mem, true);
|
|
repo.setSearchString(mem);
|
|
}
|
|
this.searchField.setCursorPositionEnd();
|
|
|
|
this.setScrollBar();
|
|
|
|
craftingGridOffsetX = Integer.MAX_VALUE;
|
|
craftingGridOffsetY = Integer.MAX_VALUE;
|
|
|
|
for (final Object s : this.inventorySlots.inventorySlots) {
|
|
if (s instanceof AppEngSlot) {
|
|
if (((Slot) s).xDisplayPosition < 197) {
|
|
this.repositionSlot((AppEngSlot) s);
|
|
}
|
|
}
|
|
|
|
if (s instanceof SlotCraftingMatrix || s instanceof SlotFakeCraftingMatrix) {
|
|
final Slot g = (Slot) s;
|
|
if (g.xDisplayPosition > 0 && g.yDisplayPosition > 0) {
|
|
craftingGridOffsetX = Math.min(craftingGridOffsetX, g.xDisplayPosition);
|
|
craftingGridOffsetY = Math.min(craftingGridOffsetY, g.yDisplayPosition);
|
|
}
|
|
}
|
|
}
|
|
|
|
craftingGridOffsetX -= 25;
|
|
craftingGridOffsetY -= 6;
|
|
|
|
this.enableShiftPause = AEConfig.instance.settings.getSetting(Settings.PAUSE_WHEN_HOLDING_SHIFT) == YesNo.YES;
|
|
}
|
|
|
|
private void initTypeToggleButtons(final int x, final int yStart) {
|
|
this.typeToggleButtons.clear();
|
|
if (this.typeFilters == null) return;
|
|
|
|
int y = yStart;
|
|
for (final IAEStackType<?> type : AEStackTypeRegistry.getSortedTypes()) {
|
|
final ResourceLocation texture = type.getButtonTexture();
|
|
final IIcon icon = type.getButtonIcon();
|
|
if (texture == null || icon == null) continue;
|
|
|
|
final TypeToggleButton btn = new TypeToggleButton(x, y, texture, icon, type.getDisplayName());
|
|
|
|
btn.setEnabled(this.typeFilters.isEnabled(type));
|
|
this.typeToggleButtons.put(btn, type);
|
|
this.buttonList.add(btn);
|
|
|
|
y += 20;
|
|
}
|
|
}
|
|
|
|
protected int calculateRowsCount() {
|
|
final boolean hasNEI = IntegrationRegistry.INSTANCE.isEnabled(IntegrationType.NEI);
|
|
final int NEIPadding = hasNEI ? 22
|
|
/** input */
|
|
+ 20
|
|
/** top panel */
|
|
: 0;
|
|
final int extraSpace = this.height - MAGIC_HEIGHT_NUMBER - NEIPadding - this.reservedSpace;
|
|
|
|
return Math.max(3, Math.min(this.getMaxRows(), (int) Math.floor(extraSpace / 18)));
|
|
}
|
|
|
|
protected int getPinButtonX() {
|
|
return this.guiLeft + 178;
|
|
}
|
|
|
|
protected int getPinButtonY() {
|
|
return this.guiTop + 18 + (rows * 18) + 25;
|
|
}
|
|
|
|
@Override
|
|
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
|
|
this.fontRendererObj.drawString(
|
|
this.getGuiDisplayName(this.myName.getLocal()),
|
|
8,
|
|
6,
|
|
ColorUtils.guiTextColorGray.getColor());
|
|
this.fontRendererObj.drawString(
|
|
GuiText.inventory.getLocal(),
|
|
8,
|
|
this.ySize - 96 + 3,
|
|
ColorUtils.guiTextColorGray.getColor());
|
|
|
|
VirtualMEPinSlot.drawSlotsBackground(this.pinSlots, this.mc, this.zLevel);
|
|
|
|
this.currentMouseX = mouseX;
|
|
this.currentMouseY = mouseY;
|
|
}
|
|
|
|
@Override
|
|
public List<String> handleItemTooltip(ItemStack stack, int mouseX, int mouseY, List<String> currentToolTip) {
|
|
super.handleItemTooltip(stack, mouseX, mouseY, currentToolTip);
|
|
VirtualMESlot hoveredSlot = this.getVirtualMESlotUnderMouse();
|
|
|
|
final boolean isMonitorableSlot = hoveredSlot instanceof VirtualMEMonitorableSlot;
|
|
if (isMonitorableSlot || hoveredSlot instanceof VirtualMEPatternSlot) {
|
|
IAEStack<?> aes = hoveredSlot.getAEStack();
|
|
final int threshold = AEConfig.instance.getTerminalFontSize() == TerminalFontSize.SMALL ? 9999 : 999;
|
|
|
|
if (aes != null) {
|
|
|
|
if (aes.getStackSize() > threshold) {
|
|
final String local = isMonitorableSlot ? ButtonToolTips.ItemsStored.getLocal()
|
|
: ButtonToolTips.ItemCount.getLocal();
|
|
final String formattedAmount = NumberFormat.getNumberInstance(Locale.US).format(aes.getStackSize());
|
|
currentToolTip.add(EnumChatFormatting.GRAY + String.format(local, formattedAmount));
|
|
}
|
|
|
|
final FlowRate rate = this.repo.getFlowRate(aes);
|
|
if (rate != null && (rate.in() != 0 || rate.out() != 0)) {
|
|
currentToolTip.add(EnumChatFormatting.GRAY + FlowRateFormatter.formatTooltipLine(rate));
|
|
}
|
|
}
|
|
}
|
|
|
|
return currentToolTip;
|
|
}
|
|
|
|
@Override
|
|
protected void mouseClicked(final int xCoord, final int yCoord, final int btn) {
|
|
searchField.mouseClicked(xCoord, yCoord, btn);
|
|
isAutoFocused = false;
|
|
|
|
if (handleViewCellClick(xCoord, yCoord, btn)) return;
|
|
|
|
super.mouseClicked(xCoord, yCoord, btn);
|
|
}
|
|
|
|
private void sendAction(MonitorableAction action, @Nullable IAEStack<?> stack, int custom) {
|
|
((AEBaseContainer) this.inventorySlots).setTargetStack(stack);
|
|
final PacketMonitorableAction p = new PacketMonitorableAction(action, custom);
|
|
NetworkHandler.instance.sendToServer(p);
|
|
}
|
|
|
|
@Override
|
|
protected boolean handleVirtualSlotClick(VirtualMESlot virtualSlot, final int mouseButton) {
|
|
if (this.handleMonitorableSlotClick(virtualSlot, mouseButton)) return true;
|
|
else return super.handleVirtualSlotClick(virtualSlot, mouseButton);
|
|
}
|
|
|
|
@Override
|
|
protected boolean canDragVirtualSlot(VirtualMESlot slot, @Nullable ItemStack holding) {
|
|
return ((Keyboard.isKeyDown(Keyboard.KEY_SPACE) || isShiftKeyDown())
|
|
&& slot instanceof VirtualMEMonitorableSlot) || super.canDragVirtualSlot(slot, holding);
|
|
}
|
|
|
|
@Override
|
|
protected void handleDragVirtualSlot(VirtualMESlot slot, int mouseButton) {
|
|
if ((!Keyboard.isKeyDown(Keyboard.KEY_SPACE) && !isShiftKeyDown())
|
|
|| !this.handleMonitorableSlotClick(slot, mouseButton)) {
|
|
super.handleDragVirtualSlot(slot, mouseButton);
|
|
}
|
|
}
|
|
|
|
private boolean handleMonitorableSlotClick(VirtualMESlot virtualSlot, final int mouseButton) {
|
|
if (!(virtualSlot instanceof VirtualMEMonitorableSlot slot)) return false;
|
|
IAEItemStack slotStack = slot.getAEStack() instanceof IAEItemStack ais ? ais : null;
|
|
|
|
if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
|
|
if (slotStack != null) {
|
|
this.sendAction(MonitorableAction.MOVE_REGION, slotStack, -1);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
final EntityPlayer player = Minecraft.getMinecraft().thePlayer;
|
|
|
|
final boolean isLShiftDown = isShiftKeyDown();
|
|
final boolean isLControlDown = isCtrlKeyDown();
|
|
final boolean nonItemInteraction = isLControlDown
|
|
|| (this.typeFilters != null && !this.typeFilters.isEnabled(ITEM_STACK_TYPE));
|
|
|
|
switch (mouseButton) {
|
|
case 0 -> { // left click
|
|
if (slot instanceof VirtualMEPinSlot pinSlot) {
|
|
if (this.handleSetPinAction(pinSlot)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (nonItemInteraction) {
|
|
this.sendAction(
|
|
isLShiftDown ? MonitorableAction.FILL_CONTAINERS : MonitorableAction.FILL_SINGLE_CONTAINER,
|
|
slot.getAEStack(),
|
|
-1);
|
|
return true;
|
|
}
|
|
|
|
if (isLShiftDown) {
|
|
this.sendAction(MonitorableAction.SHIFT_CLICK, slotStack, -1);
|
|
return true;
|
|
}
|
|
|
|
if (slot.getAEStack() != null && slot.getAEStack().getStackSize() == 0
|
|
&& player.inventory.getItemStack() == null) {
|
|
this.sendAction(MonitorableAction.AUTO_CRAFT, slot.getAEStack(), -1);
|
|
return true;
|
|
}
|
|
this.sendAction(MonitorableAction.PICKUP_OR_SET_DOWN, slotStack, -1);
|
|
return true;
|
|
}
|
|
case 1 -> { // right click
|
|
if (slot instanceof VirtualMEPinSlot pinSlot) {
|
|
if (isLShiftDown && player.inventory.getItemStack() == null) {
|
|
this.sendAction(MonitorableAction.UNSET_PIN, null, slot.getSlotIndex());
|
|
return true;
|
|
}
|
|
|
|
if (this.handleSetPinAction(pinSlot)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (nonItemInteraction) {
|
|
this.sendAction(
|
|
isLShiftDown ? MonitorableAction.DRAIN_CONTAINERS
|
|
: MonitorableAction.DRAIN_SINGLE_CONTAINER,
|
|
slot.getAEStack(),
|
|
-1);
|
|
return true;
|
|
}
|
|
|
|
if (isLShiftDown) {
|
|
this.sendAction(MonitorableAction.PICKUP_SINGLE, slotStack, -1);
|
|
return true;
|
|
}
|
|
|
|
this.sendAction(MonitorableAction.SPLIT_OR_PLACE_SINGLE, slotStack, -1);
|
|
return true;
|
|
}
|
|
case keyBindPickBlockAction -> {
|
|
if (player.inventory.getItemStack() != null) {
|
|
// middle click while holding an item; conflict with other feature like MatterManipulator pick
|
|
// block.
|
|
return false;
|
|
}
|
|
|
|
if (slot.getAEStack() != null && slot.getAEStack().isCraftable()) {
|
|
this.sendAction(MonitorableAction.AUTO_CRAFT, slot.getAEStack(), -1);
|
|
return true;
|
|
} else if (player.capabilities.isCreativeMode) {
|
|
this.sendAction(MonitorableAction.CREATIVE_DUPLICATE, slotStack, -1);
|
|
return true;
|
|
}
|
|
}
|
|
default -> {}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private boolean handleViewCellClick(final int xCoord, final int yCoord, final int btn) {
|
|
if (this.viewCell && monitorableContainer.canAccessViewCells && btn == 1) {
|
|
Slot slot = getSlot(xCoord, yCoord);
|
|
if (slot instanceof SlotRestrictedInput cvs) {
|
|
// if it has an item
|
|
if (!cvs.getHasStack()) return false;
|
|
// if its a view cell
|
|
if (!(cvs.getStack().getItem() instanceof ItemViewCell)) return false;
|
|
|
|
// update the view cell
|
|
this.monitorableContainer.toggleViewCellAction.send(cvs.getSlotIndex());
|
|
|
|
// eat the right-click input if a view cell was successfully toggled
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
protected boolean mouseWheelEvent(int x, int y, int wheel) {
|
|
VirtualMESlot slot = this.getVirtualMESlotUnderMouse();
|
|
if (!isShiftKeyDown() || !(slot instanceof VirtualMEMonitorableSlot)) return false;
|
|
|
|
final MonitorableAction direction = wheel > 0 ? MonitorableAction.ROLL_DOWN : MonitorableAction.ROLL_UP;
|
|
if (direction == MonitorableAction.ROLL_DOWN
|
|
&& Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) {
|
|
return false;
|
|
}
|
|
if (direction == MonitorableAction.ROLL_UP && !(slot.getAEStack() instanceof IAEItemStack)) {
|
|
return false;
|
|
}
|
|
|
|
((AEBaseContainer) this.inventorySlots).setTargetStack(slot.getAEStack());
|
|
final int times = Math.abs(wheel);
|
|
for (int i = 0; i < times; i++) {
|
|
final PacketMonitorableAction p = new PacketMonitorableAction(direction, -1);
|
|
NetworkHandler.instance.sendToServer(p);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onGuiClosed() {
|
|
super.onGuiClosed();
|
|
memoryText = this.searchField.getText();
|
|
// Reacquire focus on reopening so native text input restarts after a screen change.
|
|
this.searchField.setFocused(false);
|
|
Keyboard.enableRepeatEvents(false);
|
|
}
|
|
|
|
@Override
|
|
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
|
|
|
|
this.bindTexture(this.getBackground());
|
|
final int x_width = 195;
|
|
this.drawTexturedModalRect(offsetX, offsetY, 0, 0, x_width, 18);
|
|
|
|
if (this.viewCell || (this instanceof GuiSecurity)) {
|
|
this.drawTexturedModalRect(offsetX + x_width, offsetY, x_width, 0, 47, 128);
|
|
}
|
|
|
|
for (int x = 0; x < this.rows; x++) {
|
|
this.drawTexturedModalRect(offsetX, offsetY + 18 + x * 18, 0, 18, x_width, 18);
|
|
}
|
|
|
|
this.drawTexturedModalRect(
|
|
offsetX,
|
|
offsetY + 16 + this.rows * 18 + this.lowerTextureOffset,
|
|
0,
|
|
106 - 18 - 18,
|
|
x_width,
|
|
99 + this.reservedSpace - this.lowerTextureOffset);
|
|
|
|
this.searchField.drawTextBox();
|
|
|
|
this.updateViewCells();
|
|
}
|
|
|
|
protected String getBackground() {
|
|
return "guis/terminal.png";
|
|
}
|
|
|
|
protected void updateViewCells() {
|
|
if (this.viewCell) {
|
|
boolean update = false;
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
if (this.myCurrentViewCells[i] != this.monitorableContainer.getCellViewSlot(i).getStack()) {
|
|
update = true;
|
|
this.myCurrentViewCells[i] = this.monitorableContainer.getCellViewSlot(i).getStack();
|
|
}
|
|
}
|
|
|
|
if (update) {
|
|
this.repo.setViewCell(this.myCurrentViewCells);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected int getMaxRows() {
|
|
return AEConfig.instance.getConfigManager().getSetting(Settings.TERMINAL_STYLE) == TerminalStyle.SMALL
|
|
? AEConfig.instance.MEMonitorableSmallSize
|
|
: Integer.MAX_VALUE;
|
|
}
|
|
|
|
protected void repositionSlot(final AppEngSlot s) {
|
|
s.yDisplayPosition = s.getY() + this.ySize - 78 - 5;
|
|
}
|
|
|
|
public boolean isSearchFieldManuallyFocused() {
|
|
return searchField.isFocused() && !isAutoFocused;
|
|
}
|
|
|
|
@Override
|
|
protected void keyTyped(final char character, final int key) {
|
|
// Opening NEI can leave text events queued for this now-hidden terminal.
|
|
if (this.mc.currentScreen != this) {
|
|
return;
|
|
}
|
|
|
|
if (!searchField.isFocused() && (!NEI.searchField.existsSearchField() || !NEI.searchField.focused())
|
|
&& CommonHelper.proxy.isActionKey(ActionKey.TOGGLE_FOCUS, key)) {
|
|
searchField.setFocused(true);
|
|
isAutoFocused = false;
|
|
return;
|
|
}
|
|
|
|
if (NEI.searchField.existsSearchField()) {
|
|
if (NEI.searchField.focused() || searchField.isFocused()) {
|
|
|
|
if (CommonHelper.proxy.isActionKey(ActionKey.TOGGLE_FOCUS, key)) {
|
|
final boolean focused = searchField.isFocused();
|
|
searchField.setFocused(!focused);
|
|
NEI.searchField.setFocus(focused);
|
|
isAutoFocused = false;
|
|
return;
|
|
}
|
|
|
|
if (NEI.searchField.focused()) {
|
|
return;
|
|
}
|
|
|
|
} else {
|
|
|
|
if (CommonHelper.proxy.isActionKey(ActionKey.SEARCH_CONNECTED_INVENTORIES, key)) {
|
|
final VirtualMESlot slot = this.getVirtualMESlotUnderMouse();
|
|
if (slot instanceof VirtualMEMonitorableSlot monitorableSlot) {
|
|
IAEStack<?> stack = monitorableSlot.getAEStack();
|
|
this.monitorableContainer.setTargetStack(stack);
|
|
if (stack != null) {
|
|
final PacketInventoryAction p = new PacketInventoryAction(
|
|
InventoryAction.FIND_ITEMS,
|
|
this.getInventorySlots().size(),
|
|
0);
|
|
NetworkHandler.instance.sendToServer(p);
|
|
this.closeGui();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (CommonHelper.proxy.isActionKey(ActionKey.LOCATE_ITEM_FLOW, key)) {
|
|
final VirtualMESlot slot = this.getVirtualMESlotUnderMouse();
|
|
if (slot instanceof VirtualMEMonitorableSlot monitorableSlot) {
|
|
IAEStack<?> stack = monitorableSlot.getAEStack();
|
|
this.monitorableContainer.setTargetStack(stack);
|
|
|
|
if (stack != null) {
|
|
final PacketInventoryAction p = new PacketInventoryAction(
|
|
InventoryAction.LOCATE_ITEM_FLOW,
|
|
this.getInventorySlots().size(),
|
|
0);
|
|
NetworkHandler.instance.sendToServer(p);
|
|
this.closeGui();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (searchField.isFocused() && (key == Keyboard.KEY_RETURN || key == Keyboard.KEY_NUMPADENTER)) {
|
|
searchField.setFocused(false);
|
|
isAutoFocused = false;
|
|
return;
|
|
}
|
|
|
|
boolean skipHotbarCheck = searchField.isFocused()
|
|
&& (AEConfig.instance.searchBoxFocusPriority == SearchBoxFocusPriority.ALWAYS
|
|
|| (AEConfig.instance.searchBoxFocusPriority == SearchBoxFocusPriority.NO_AUTOSEARCH
|
|
&& !isAutoFocused));
|
|
|
|
if (!skipHotbarCheck && checkHotbarKeys(key)) {
|
|
return;
|
|
}
|
|
|
|
final boolean mouseInGui = this
|
|
.isPointInRegion(0, 0, this.xSize, this.ySize, this.currentMouseX, this.currentMouseY);
|
|
|
|
if (this.canBeAutoFocused && !searchField.isFocused() && mouseInGui) {
|
|
searchField.setFocused(true);
|
|
isAutoFocused = true;
|
|
}
|
|
|
|
if (!searchField.textboxKeyTyped(character, key)) {
|
|
super.keyTyped(character, key);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void updateScreen() {
|
|
this.repo.setPowered(this.monitorableContainer.isPowered());
|
|
super.updateScreen();
|
|
}
|
|
|
|
@Override
|
|
public Enum getSortBy() {
|
|
return this.configSrc.getSetting(Settings.SORT_BY);
|
|
}
|
|
|
|
@Override
|
|
public Enum getSortDir() {
|
|
return this.configSrc.getSetting(Settings.SORT_DIRECTION);
|
|
}
|
|
|
|
@Override
|
|
@Nullable
|
|
public Reference2BooleanMap<IAEStackType<?>> getTypeFilter() {
|
|
return this.typeFilters == null ? null : this.typeFilters.getFiltersMap();
|
|
}
|
|
|
|
@Override
|
|
public Enum getSortDisplay() {
|
|
return this.configSrc.getSetting(Settings.VIEW_MODE);
|
|
}
|
|
|
|
@Override
|
|
public void updateSetting(final IConfigManager manager, final Enum settingName, final Enum newValue) {
|
|
if (this.SortByBox != null) {
|
|
this.SortByBox.set(this.configSrc.getSetting(Settings.SORT_BY));
|
|
}
|
|
|
|
if (this.SortDirBox != null) {
|
|
this.SortDirBox.set(this.configSrc.getSetting(Settings.SORT_DIRECTION));
|
|
}
|
|
|
|
if (this.ViewBox != null) {
|
|
this.ViewBox.set(this.configSrc.getSetting(Settings.VIEW_MODE));
|
|
}
|
|
|
|
this.repo.updateView();
|
|
}
|
|
|
|
public void updateTypeFilters(Reference2BooleanMap<IAEStackType<?>> map) {
|
|
if (this.typeFilters == null) return;
|
|
|
|
for (Reference2BooleanMap.Entry<IAEStackType<?>> entry : map.reference2BooleanEntrySet()) {
|
|
this.typeFilters.setEnabled(entry.getKey(), entry.getBooleanValue());
|
|
}
|
|
|
|
// Update Buttons
|
|
for (final Map.Entry<TypeToggleButton, IAEStackType<?>> entry : this.typeToggleButtons.entrySet()) {
|
|
final boolean enabled = this.typeFilters.isEnabled(entry.getValue());
|
|
entry.getKey().setEnabled(enabled);
|
|
}
|
|
|
|
this.repo.updateView();
|
|
}
|
|
|
|
@SuppressWarnings("SameParameterValue")
|
|
protected boolean isPointInRegion(int rectX, int rectY, int rectWidth, int rectHeight, int pointX, int pointY) {
|
|
pointX -= this.guiLeft;
|
|
pointY -= this.guiTop;
|
|
return pointX >= rectX - 1 && pointX < rectX + rectWidth + 1
|
|
&& pointY >= rectY - 1
|
|
&& pointY < rectY + rectHeight + 1;
|
|
}
|
|
|
|
protected int getReservedSpace() {
|
|
return this.reservedSpace;
|
|
}
|
|
|
|
protected void setReservedSpace(final int reservedSpace) {
|
|
this.reservedSpace = reservedSpace;
|
|
}
|
|
|
|
public boolean isCustomSortOrder() {
|
|
return this.customSortOrder;
|
|
}
|
|
|
|
void setCustomSortOrder(final boolean customSortOrder) {
|
|
this.customSortOrder = customSortOrder;
|
|
}
|
|
|
|
public int getStandardSize() {
|
|
return this.standardSize;
|
|
}
|
|
|
|
void setStandardSize(final int standardSize) {
|
|
this.standardSize = standardSize;
|
|
}
|
|
|
|
@Override
|
|
public void drawScreen(final int mouseX, final int mouseY, final float btn) {
|
|
if (this.needsViewUpdate) {
|
|
this.needsViewUpdate = false;
|
|
this.repo.updateViewIfChanged();
|
|
}
|
|
if (this.repo.size() != this.scrollBarRepoSize) this.setScrollBar();
|
|
|
|
handleTooltip(mouseX, mouseY, searchField);
|
|
|
|
super.drawScreen(mouseX, mouseY, btn);
|
|
}
|
|
|
|
public boolean isOverTextField(final int mousex, final int mousey) {
|
|
return searchField.isMouseIn(mousex, mousey);
|
|
}
|
|
|
|
public void setTextFieldValue(final String displayName, final int mousex, final int mousey, final ItemStack stack) {
|
|
searchField.setText(NEI.searchField.getEscapedSearchText(displayName));
|
|
}
|
|
|
|
@Override
|
|
protected void handleMouseClick(Slot slot, int slotIdx, int clickedButton, int clickType) {
|
|
|
|
// Hack for view cells, because they are outside the container
|
|
if (slot != null && clickType == 4 && slot.xDisplayPosition > this.xSize) {
|
|
clickType = 0;
|
|
}
|
|
|
|
super.handleMouseClick(slot, slotIdx, clickedButton, clickType);
|
|
}
|
|
|
|
@Override
|
|
protected boolean handleClickOrDragSlot(@NotNull Slot slot, @org.jetbrains.annotations.Nullable ItemStack stack,
|
|
int mouseButton) {
|
|
|
|
if (isCtrlKeyDown() && mouseButton == 0
|
|
&& stack == null
|
|
&& slot instanceof AppEngSlot appEngSlot
|
|
&& appEngSlot.isPlayerSide()) {
|
|
ItemStack stackInSlot = appEngSlot.getStack();
|
|
if (stackInSlot != null) {
|
|
for (IAEStackType<?> type : AEStackTypeRegistry.getAllTypes()) {
|
|
if (type.isContainerItemForType(stackInSlot)) {
|
|
this.sendAction(MonitorableAction.CONTAINER_QUICK_TRANSFER, null, slot.slotNumber);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return super.handleClickOrDragSlot(slot, stack, mouseButton);
|
|
}
|
|
|
|
@Override
|
|
public void handleKeyboardInput() {
|
|
super.handleKeyboardInput();
|
|
|
|
// Pause the terminal when holding shift
|
|
if (enableShiftPause) this.repo.setPaused(isShiftKeyDown());
|
|
}
|
|
|
|
public boolean hideItemPanelSlot(int tx, int ty, int tw, int th) {
|
|
|
|
if (this.viewCell) {
|
|
int rw = 33;
|
|
int rh = 14 + myCurrentViewCells.length * 18;
|
|
if (monitorableContainer.isAPatternTerminal()) rh += 21;
|
|
|
|
if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
|
|
return false;
|
|
}
|
|
|
|
int rx = this.guiLeft + this.xSize;
|
|
int ry = this.guiTop + 0;
|
|
|
|
rw += rx;
|
|
rh += ry;
|
|
tw += tx;
|
|
th += ty;
|
|
|
|
// overflow || intersect
|
|
return (rw < rx || rw > tx) && (rh < ry || rh > ty) && (tw < tx || tw > rx) && (th < ty || th > ry);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void setAEPins(IAEStack<?>[] pins) {
|
|
repo.setAEPins(pins);
|
|
}
|
|
|
|
@Override
|
|
public void setPinsRows(PinsRows craftingRows, PinsRows playerRows) {
|
|
if (this.pinsStateButton != null) {
|
|
if (craftingRows != craftingPinsRows || playerRows != playerPinsRows) {
|
|
craftingPinsRows = craftingRows;
|
|
playerPinsRows = playerRows;
|
|
reinitalize();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return true if this click was handled as a pin-setting action, false if normal slot handling should continue
|
|
*/
|
|
private boolean handleSetPinAction(VirtualMEPinSlot pinSlot) {
|
|
ItemStack itemStack = this.getStackFromHand();
|
|
|
|
if (itemStack == null) return false;
|
|
|
|
final boolean isRealItem = this.mc.thePlayer.inventory.getItemStack() != null;
|
|
final boolean nonItemInteraction = isCtrlKeyDown()
|
|
|| (this.typeFilters != null && !this.typeFilters.isEnabled(ITEM_STACK_TYPE));
|
|
|
|
if (nonItemInteraction) {
|
|
for (IAEStackType<?> type : AEStackTypeRegistry.getAllTypes()) {
|
|
if (type.isContainerItemForType(itemStack)) {
|
|
IAEStack<?> stackInContainer = type.getStackFromContainerItem(itemStack);
|
|
IAEStack<?> stackInSlot = pinSlot.getAEStack();
|
|
|
|
if (isRealItem && stackInSlot != null
|
|
&& stackInSlot.getStackType() == type
|
|
&& (stackInContainer == null || stackInSlot.equals(stackInContainer))) {
|
|
return false;
|
|
}
|
|
|
|
if (stackInContainer == null) return true;
|
|
|
|
this.sendAction(MonitorableAction.SET_PIN, stackInContainer, pinSlot.getSlotIndex());
|
|
return true;
|
|
}
|
|
}
|
|
return true;
|
|
} else {
|
|
IAEStack<?> stackInSlot = pinSlot.getAEStack();
|
|
if (isRealItem && stackInSlot instanceof IAEItemStack ais && ais.getItemStack().isItemEqual(itemStack)) {
|
|
return false;
|
|
}
|
|
this.sendAction(MonitorableAction.SET_PIN, AEItemStack.create(itemStack), pinSlot.getSlotIndex());
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public void memoryTextUpdated() {
|
|
this.reinitalize();
|
|
}
|
|
}
|