Merge branch 'master' into fix/restore-cable-replacable

This commit is contained in:
Martin Robertz authored and GitHub committed 2026-10-01 07:30:21 +02:00
commit 2c0895b948
7 files changed
+156 -18

No files matched your search

@@ -34,13 +34,17 @@ public class GuiAdvancedInscriber extends AEBaseGui {
super(new ContainerAdvancedInscriber(inventoryPlayer, te));
this.container = (ContainerAdvancedInscriber) this.inventorySlots;
this.ySize = 176;
this.xSize = this.hasToolbox() ? 246 : 211;
this.xSize = !this.hasToolbox() ? 211 : this.getToolboxSize() == 5 ? 317 : 246;
}
private boolean hasToolbox() {
return ((ContainerUpgradeable) this.inventorySlots).hasToolbox();
}
private int getToolboxSize() {
return ((ContainerUpgradeable) this.inventorySlots).getToolboxSize();
}
@Override
public void initGui() {
super.initGui();
@@ -90,7 +94,10 @@ public class GuiAdvancedInscriber extends AEBaseGui {
this.bindTexture("guis/mac.png");
this.drawTexturedModalRect(offsetX + 179, offsetY, 179, 0, 32, 104);
if (this.hasToolbox()) {
if (this.hasToolbox() && this.getToolboxSize() == 5) {
this.bindTexture("guis/advanced_toolbox.png");
this.drawTexturedModalRect(offsetX + 213, offsetY + 64, 0, 0, 104, 104);
} else if (this.hasToolbox()) {
this.bindTexture("guis/inscriber.png");
this.drawTexturedModalRect(offsetX + 178, offsetY + 105, 178, this.ySize - 90, 68, 68);
}
@@ -18,13 +18,17 @@ public class GuiCrystalGrowthChamber extends AEBaseGui {
super(new ContainerCrystalGrowthChamber(inventoryPlayer, te));
cg = (ContainerCrystalGrowthChamber) this.inventorySlots;
ySize = 166;
xSize = hasToolbox() ? 246 : 211;
xSize = !hasToolbox() ? 211 : getToolboxSize() == 5 ? 290 : 246;
}
private boolean hasToolbox() {
return ((ContainerUpgradeable) this.inventorySlots).hasToolbox();
}
private int getToolboxSize() {
return ((ContainerUpgradeable) this.inventorySlots).getToolboxSize();
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
fontRendererObj.drawString(
@@ -46,7 +50,10 @@ public class GuiCrystalGrowthChamber extends AEBaseGui {
if (drawUpgrades()) {
drawTexturedModalRect(offsetX + 177, offsetY, 177, 0, 35, 14 + cg.availableUpgrades() * 18);
}
if (hasToolbox()) {
if (hasToolbox() && getToolboxSize() == 5) {
bindTexture("guis/advanced_toolbox.png");
drawTexturedModalRect(offsetX + 178, offsetY + ySize - 90 - 7, 0, 0, 104, 104);
} else if (hasToolbox()) {
drawTexturedModalRect(offsetX + 178, offsetY + ySize - 90, 178, ySize - 90, 68, 68);
}
}
@@ -30,13 +30,17 @@ public class GuiInscriber extends AEBaseGui {
super(new ContainerInscriber(inventoryPlayer, te));
this.cvc = (ContainerInscriber) this.inventorySlots;
this.ySize = 176;
this.xSize = this.hasToolbox() ? 246 : 211;
this.xSize = !this.hasToolbox() ? 211 : this.getToolboxSize() == 5 ? 290 : 246;
}
private boolean hasToolbox() {
return ((ContainerUpgradeable) this.inventorySlots).hasToolbox();
}
private int getToolboxSize() {
return ((ContainerUpgradeable) this.inventorySlots).getToolboxSize();
}
@Override
public void initGui() {
super.initGui();
@@ -72,7 +76,10 @@ public class GuiInscriber extends AEBaseGui {
if (this.drawUpgrades()) {
this.drawTexturedModalRect(offsetX + 177, offsetY, 177, 0, 35, 14 + this.cvc.availableUpgrades() * 18);
}
if (this.hasToolbox()) {
if (this.hasToolbox() && this.getToolboxSize() == 5) {
this.bindTexture("guis/advanced_toolbox.png");
this.drawTexturedModalRect(offsetX + 178, offsetY + this.ySize - 90 - 7, 0, 0, 104, 104);
} else if (this.hasToolbox()) {
this.drawTexturedModalRect(offsetX + 178, offsetY + this.ySize - 90, 178, this.ySize - 90, 68, 68);
}
}
@@ -64,7 +64,13 @@ public class ContainerAdvancedInscriber extends ContainerUpgradeable implements
@Override
protected int getToolboxY() {
return 113;
// The 5x5 toolbox does not fit below the upgrade strip, so it is placed next to it instead
return this.getToolboxSize() == 5 ? 79 : 113;
}
@Override
protected int getToolboxX() {
return this.getToolboxSize() == 5 ? 221 : 186;
}
@Override
@@ -100,6 +100,7 @@ public abstract class ContainerUpgradeable extends AEBaseContainer implements IO
// For advanced toolbox to move down a little bit
int yBias = size == 3 ? 0 : 7;
int toolboxY = this.getToolboxY();
int toolboxX = this.getToolboxX();
for (int v = 0; v < size; v++) {
for (int u = 0; u < size; u++) {
this.addSlotToContainer(
@@ -107,7 +108,7 @@ public abstract class ContainerUpgradeable extends AEBaseContainer implements IO
SlotRestrictedInput.PlacableItemType.UPGRADES,
this.tbInventory,
u + v * size,
186 + u * 18,
toolboxX + u * 18,
toolboxY - yBias + v * 18,
this.getInventoryPlayer())).setPlayerSide());
}
@@ -139,6 +140,10 @@ public abstract class ContainerUpgradeable extends AEBaseContainer implements IO
return this.getHeight() - 82;
}
protected int getToolboxX() {
return 186;
}
protected void setupConfig() {
this.setupUpgrades();
}
@@ -5,22 +5,32 @@ import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.play.server.S09PacketHeldItemChange;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.security.PlayerSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEInventoryHandler;
import appeng.api.parts.ICraftingTerminal;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.container.PrimaryGui;
import appeng.container.implementations.ContainerCraftAmount;
import appeng.core.localization.PlayerMessages;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.GuiBridge;
import appeng.core.sync.network.INetworkInfo;
import appeng.util.Platform;
import appeng.util.PlayerInventoryUtil;
import baubles.api.BaublesApi;
import cpw.mods.fml.common.Optional;
import cpw.mods.fml.common.network.ByteBufUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -78,12 +88,8 @@ public class PacketPickBlock extends AppEngPacket {
return;
}
// 3. If there are no partial stacks and the player's inventory is full,
// then return since we cannot add a retrieved stack to a full inventory
// 3. Find a slot for retrieved items. A full inventory can still request a craft.
int nextEmptySlot = sender.inventory.getFirstEmptyStack();
if (partialStackSlotsList.isEmpty() && nextEmptySlot == -1) {
return;
}
// 4. Consolidate all partial stacks of target block into 1 ItemStack.
// If a full stack is obtained, set it as the active slot and return.
@@ -126,7 +132,13 @@ public class PacketPickBlock extends AppEngPacket {
sender.addChatMessage(PlayerMessages.PickBlockTerminalNotFound.toChat());
return;
}
var wirelessInventory = getWirelessItemInventory(sender, wirelessTerminal);
var wirelessGrid = getWirelessGrid(wirelessTerminal, sender);
if (wirelessGrid == null) {
movePickBlockItemStack(sender, pickBlockSlot);
return;
}
var wirelessInventory = getWirelessItemInventory(wirelessGrid);
if (wirelessInventory == null) {
movePickBlockItemStack(sender, pickBlockSlot);
return;
@@ -141,6 +153,16 @@ public class PacketPickBlock extends AppEngPacket {
return;
}
if (pickBlockItemStack == null
&& isMissingFromStorage(wirelessInventory.getStorageList().findPrecise(targetAeItemStack))
&& openCraftAmountGui(sender, wirelessTerminal, targetAeItemStack, wirelessGrid)) {
return;
}
if (pickBlockSlot < 0) {
return;
}
// 6. Extract items from the network
PlayerSource source = new PlayerSource(player, null);
IAEStack<IAEItemStack> extractedStack = wirelessInventory
@@ -168,8 +190,7 @@ public class PacketPickBlock extends AppEngPacket {
movePickBlockItemStack(sender, pickBlockSlot);
}
private IMEInventoryHandler<IAEItemStack> getWirelessItemInventory(EntityPlayer player,
ItemStack wirelessTerminal) {
private IGrid getWirelessGrid(ItemStack wirelessTerminal, EntityPlayer player) {
if (wirelessTerminal == null) {
return null;
}
@@ -204,6 +225,10 @@ public class PacketPickBlock extends AppEngPacket {
return null;
}
return wirelessGrid;
}
private IMEMonitor<IAEItemStack> getWirelessItemInventory(IGrid wirelessGrid) {
IStorageGrid wirelessGridCache = wirelessGrid.getCache(IStorageGrid.class);
if (wirelessGridCache == null) {
return null;
@@ -212,6 +237,72 @@ public class PacketPickBlock extends AppEngPacket {
return wirelessGridCache.getItemInventory();
}
private boolean openCraftAmountGui(EntityPlayerMP player, ItemStack wirelessTerminal, IAEItemStack itemToCraft,
IGrid wirelessGrid) {
ICraftingGrid craftingGrid = wirelessGrid.getCache(ICraftingGrid.class);
if (craftingGrid == null || craftingGrid.getCraftingFor(itemToCraft, null, -1, player.worldObj).isEmpty()) {
return false;
}
int terminalSlot = getInventorySlot(player, wirelessTerminal);
if (terminalSlot < 0) {
return false;
}
Platform.openGUI(player, null, null, GuiBridge.GUI_CRAFTING_AMOUNT, terminalSlot);
if (!(player.openContainer instanceof ContainerCraftAmount craftAmount)) {
return false;
}
// Unlike terminal clicks, pick block has no parent container to supply the return context.
// PacketCraftRequest passes this to the confirmation screen; a null context cancels the job.
PrimaryGui primaryGui = new PrimaryGui(
craftAmount.getTarget() instanceof ICraftingTerminal ? GuiBridge.GUI_CRAFTING_TERMINAL
: GuiBridge.GUI_ME,
wirelessTerminal.copy(),
null,
ForgeDirection.UNKNOWN);
primaryGui.setSlotIndex(terminalSlot);
craftAmount.setPrimaryGui(primaryGui);
craftAmount.setItemToCraft(itemToCraft);
craftAmount.setInitialCraftAmount(1);
craftAmount.detectAndSendChanges();
return true;
}
static boolean isMissingFromStorage(IAEItemStack stored) {
return stored == null || stored.getStackSize() <= 0;
}
private int getInventorySlot(EntityPlayerMP player, ItemStack item) {
// Match getFirstWirelessTerminal: equipped terminals take priority over inventory terminals.
if (Platform.isBaublesLoaded) {
int slot = getBaublesSlot(player, item);
if (slot >= 0) return slot;
}
for (int slot = 0; slot < player.inventory.mainInventory.length; slot++) {
if (player.inventory.mainInventory[slot] == item) {
return slot;
}
}
return -1;
}
@Optional.Method(modid = "Baubles|Expanded")
private int getBaublesSlot(EntityPlayerMP player, ItemStack item) {
return findSlot(BaublesApi.getBaubles(player), item, Platform.baublesSlotsOffset);
}
static int findSlot(IInventory inventory, ItemStack item, int offset) {
if (inventory != null && item != null) {
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
if (inventory.getStackInSlot(slot) == item) return offset + slot;
}
}
return -1;
}
/**
* Set the position of the pick block ItemStack. If it is in the hotbar, set the active slot to the pick block slot.
* If it is not in the hotbar, move it to the first empty slot in the hotbar and set it as active slot. If there is
@@ -221,7 +312,7 @@ public class PacketPickBlock extends AppEngPacket {
* @param pickBlockInventorySlot the inventory slot of the ItemStack to move
*/
private void movePickBlockItemStack(EntityPlayerMP player, int pickBlockInventorySlot) {
if (player.inventory.getStackInSlot(pickBlockInventorySlot) == null) {
if (pickBlockInventorySlot < 0 || player.inventory.getStackInSlot(pickBlockInventorySlot) == null) {
return;
}
var firstEmptyHotbarSlot = PlayerInventoryUtil.getFirstEmptyHotbarSlot(player);
@@ -53,6 +53,7 @@ import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartRenderHelper;
import appeng.api.parts.ISimplifiedBundle;
import appeng.api.parts.PartItemStack;
import appeng.api.storage.ITerminalTypeFilterProvider;
import appeng.api.storage.StorageName;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
@@ -73,6 +74,7 @@ import appeng.parts.networking.PartCable;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.IAEStackInventory;
import appeng.tile.inventory.IIAEStackInventory;
import appeng.util.AEStackTypeFilter;
import appeng.util.Platform;
import appeng.util.SettingsFrom;
import cpw.mods.fml.relauncher.Side;
@@ -439,6 +441,11 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
if (player.isSneaking()) {
final NBTTagCompound data = this.downloadSettings(SettingsFrom.MEMORY_CARD);
if (data != null && !data.hasNoTags()) {
if (this instanceof ITerminalTypeFilterProvider provider) {
final AEStackTypeFilter filters = new AEStackTypeFilter();
filters.getFiltersMap().putAll(provider.getTypeFilter(player));
filters.writeToNBT(data);
}
memoryCard.setMemoryCardContents(memCardIS, name, data);
if (this.getInventoryByName("upgrades") instanceof UpgradeInventory ui)
@@ -462,6 +469,14 @@ public abstract class AEBasePart implements IPart, IGridProxyable, IActionHost,
// Apply settings after insertUpgrades to preserve upgrade-gated settings, such as ore filters.
this.uploadSettings(SettingsFrom.MEMORY_CARD, data);
if (this instanceof ITerminalTypeFilterProvider provider
&& data.hasKey(AEStackTypeFilter.NBT_FILTERS, NBT.TAG_LIST)) {
final AEStackTypeFilter filters = new AEStackTypeFilter();
filters.readFromNBT(data);
provider.getTypeFilter(player).putAll(filters.getFiltersMap());
provider.saveTypeFilter();
}
// After insertUpgrades for the same reason as above
if (this instanceof IInterfaceHost iHost) {
ToolMemoryCard.insertPatterns(data, player, iHost);