From fb18c4ea691718047de08571052fc0dd52c6612e Mon Sep 17 00:00:00 2001 From: GDCloud <93287602+GDCloudstrike@users.noreply.github.com> Date: Sun, 12 Jan 2025 06:45:07 +0100 Subject: [PATCH] Add NC hatches for PCB Factory and QFT (#3737) Co-authored-by: Martin Robertz Co-authored-by: Maya <10861407+serenibyss@users.noreply.github.com> --- src/main/java/gregtech/GTMod.java | 2 + .../java/gregtech/api/enums/ItemList.java | 3 + .../gregtech/api/enums/MetaTileEntityIDs.java | 2 + .../java/gregtech/api/enums/Textures.java | 7 +- .../MTEHatchBulkCatalystHousing.java | 72 +++ .../implementations/MTEHatchNanite.java | 81 ++++ .../MTEHatchNonConsumableBase.java | 451 ++++++++++++++++++ .../objects/AE2NonconsumableHatchHandler.java | 26 + .../java/gregtech/api/recipe/RecipeMaps.java | 31 ++ .../gregtech/api/util/GTRecipeConstants.java | 12 + .../machines/multi/MTEPCBFactory.java | 104 +++- .../preload/LoaderMetaTileEntities.java | 11 + src/main/java/gregtech/nei/NEIGTConfig.java | 1 + .../gtPlusPlus/api/recipe/GTPPRecipeMaps.java | 38 ++ .../java/gtPlusPlus/nei/NEIGTPPConfig.java | 4 + .../nbthandlers/MTEHatchCatalysts.java | 22 +- .../MTEQuantumForceTransformer.java | 123 +++-- .../resources/assets/gregtech/lang/en_US.lang | 2 + .../blocks/iconsets/OVERLAY_NANITE_HATCH.png | Bin 0 -> 492 bytes .../iconsets/OVERLAY_NANITE_HATCH_GLOW.png | Bin 0 -> 465 bytes 20 files changed, 944 insertions(+), 48 deletions(-) create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchBulkCatalystHousing.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchNanite.java create mode 100644 src/main/java/gregtech/api/metatileentity/implementations/MTEHatchNonConsumableBase.java create mode 100644 src/main/java/gregtech/api/objects/AE2NonconsumableHatchHandler.java create mode 100644 src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_NANITE_HATCH.png create mode 100644 src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_NANITE_HATCH_GLOW.png diff --git a/src/main/java/gregtech/GTMod.java b/src/main/java/gregtech/GTMod.java index 63e7d02c436..fe67bcb2a1f 100644 --- a/src/main/java/gregtech/GTMod.java +++ b/src/main/java/gregtech/GTMod.java @@ -65,6 +65,7 @@ import gregtech.api.gui.modularui.GTUIInfos; import gregtech.api.interfaces.internal.IGTMod; import gregtech.api.metatileentity.BaseMetaPipeEntity; +import gregtech.api.metatileentity.implementations.MTEHatchNonConsumableBase; import gregtech.api.objects.ItemData; import gregtech.api.objects.XSTR; import gregtech.api.registries.LHECoolantRegistry; @@ -513,6 +514,7 @@ public void onPostLoad(FMLPostInitializationEvent aEvent) { GTForestryCompat.transferSqueezerRecipes(); } MTEDigitalChestBase.registerAEIntegration(); + MTEHatchNonConsumableBase.registerAEIntegration(); ItemStack facade = AEApi.instance() .definitions() .items() diff --git a/src/main/java/gregtech/api/enums/ItemList.java b/src/main/java/gregtech/api/enums/ItemList.java index f80d13cc6ee..8c507ee0b77 100644 --- a/src/main/java/gregtech/api/enums/ItemList.java +++ b/src/main/java/gregtech/api/enums/ItemList.java @@ -2600,9 +2600,12 @@ public enum ItemList implements IItemContainer { Casing_AirFilter_Vent_T3, Casing_Pyrolyse, NameRemover, + Hatch_Nanite, + Hatch_Catalyst_Bulk, Machine_Multi_AirFilterT1, Machine_Multi_AirFilterT2, Machine_Multi_AirFilterT3, + // semicolon after the comment to reduce merge conflicts ; diff --git a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java index 887f972ea06..57ceda8f70e 100644 --- a/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java +++ b/src/main/java/gregtech/api/enums/MetaTileEntityIDs.java @@ -855,6 +855,8 @@ public enum MetaTileEntityIDs { PURIFICATION_UNIT_DEGASIFIER(9412), HATCH_DEGASIFIER_CONTROL(9413), PURIFICATION_UNIT_PARTICLE_EXTRACTOR(9414), + HATCH_NANITE(9415), + HATCH_CATALYST_BULK(9416), PLASMA_GENERATOR_ZPM(10752), PLASMA_GENERATOR_UV(10753), ALLOY_SMELTER_LuV(10760), diff --git a/src/main/java/gregtech/api/enums/Textures.java b/src/main/java/gregtech/api/enums/Textures.java index 39979445e51..77923258cf8 100644 --- a/src/main/java/gregtech/api/enums/Textures.java +++ b/src/main/java/gregtech/api/enums/Textures.java @@ -1460,7 +1460,12 @@ public enum BlockIcons implements IIconContainer, Runnable { NEUTRONIUM_STABLE_CASING, EXTREME_DENSITY_CASING, RADIATION_ABSORBENT_CASING, - HAWKING_GLASS; + HAWKING_GLASS, + OVERLAY_NANITE_HATCH, + OVERLAY_NANITE_HATCH_GLOW + + // semicolon after the comment to reduce merge conflicts + ; /** * Icon for Fresh CFoam diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchBulkCatalystHousing.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchBulkCatalystHousing.java new file mode 100644 index 00000000000..b721f721cc5 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchBulkCatalystHousing.java @@ -0,0 +1,72 @@ +package gregtech.api.metatileentity.implementations; + +import net.minecraft.item.ItemStack; + +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.render.TextureFactory; +import gtPlusPlus.core.util.minecraft.ItemUtils; +import gtPlusPlus.xmod.gregtech.common.blocks.textures.TexturesGtBlock; + +public class MTEHatchBulkCatalystHousing extends MTEHatchNonConsumableBase { + + private int catalystCapacity = 0; + + public MTEHatchBulkCatalystHousing(int ID, String name, String nameRegional, int tier, int itemCapacity) { + super(ID, name, nameRegional, tier, "Dedicated Catalyst Storage"); + catalystCapacity = itemCapacity; + } + + public MTEHatchBulkCatalystHousing(String name, String[] description, ITexture[][][] textures, int tier, + int itemCapacity) { + super(name, tier, description, textures); + catalystCapacity = itemCapacity; + } + + @Override + protected int getItemCapacity() { + return catalystCapacity; + } + + public int getStoredCatalystMeta() { + if (getItemStack() == null) return -1; + return getItemStack().getItemDamage(); + } + + @Override + protected boolean isValidItem(ItemStack item) { + return ItemUtils.isCatalyst(item); + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(TexturesGtBlock.Overlay_Bus_Catalyst) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(TexturesGtBlock.Overlay_Bus_Catalyst) + .extFacing() + .glow() + .build() }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(TexturesGtBlock.Overlay_Bus_Catalyst) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(TexturesGtBlock.Overlay_Bus_Catalyst) + .extFacing() + .glow() + .build() }; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchBulkCatalystHousing(mName, mDescriptionArray, mTextures, mTier, catalystCapacity); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchNanite.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchNanite.java new file mode 100644 index 00000000000..fa3cd6643c6 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchNanite.java @@ -0,0 +1,81 @@ +package gregtech.api.metatileentity.implementations; + +import net.minecraft.item.ItemStack; + +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.objects.ItemData; +import gregtech.api.render.TextureFactory; +import gregtech.api.util.GTOreDictUnificator; + +public class MTEHatchNanite extends MTEHatchNonConsumableBase { + + private int naniteCapacity = 0; + + public MTEHatchNanite(int ID, String name, String nameRegional, int tier, int itemCapacity) { + super(ID, name, nameRegional, tier, "Holds nanites for use in multiblocks"); + naniteCapacity = itemCapacity; + } + + public MTEHatchNanite(String name, String[] description, ITexture[][][] textures, int tier, int itemCapacity) { + super(name, tier, description, textures); + naniteCapacity = itemCapacity; + } + + @Override + protected int getItemCapacity() { + return naniteCapacity; + } + + public Materials getStoredNaniteMaterial() { + if (getItemStack() == null) return null; + ItemData data = GTOreDictUnificator.getAssociation(getItemStack()); + if (data == null) return null; + return data.mMaterial.mMaterial; + } + + @Override + protected boolean isValidItem(ItemStack item) { + ItemData data = GTOreDictUnificator.getAssociation(item); + if (data == null) { + return false; + } + OrePrefixes prefix = data.mPrefix; + return prefix == OrePrefixes.nanite; + } + + @Override + public ITexture[] getTexturesActive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_NANITE_HATCH) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_NANITE_HATCH_GLOW) + .extFacing() + .glow() + .build() }; + } + + @Override + public ITexture[] getTexturesInactive(ITexture aBaseTexture) { + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_NANITE_HATCH) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(Textures.BlockIcons.OVERLAY_NANITE_HATCH_GLOW) + .extFacing() + .glow() + .build() }; + } + + @Override + public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) { + return new MTEHatchNanite(mName, mDescriptionArray, mTextures, mTier, naniteCapacity); + } +} diff --git a/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchNonConsumableBase.java b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchNonConsumableBase.java new file mode 100644 index 00000000000..3126126f0d6 --- /dev/null +++ b/src/main/java/gregtech/api/metatileentity/implementations/MTEHatchNonConsumableBase.java @@ -0,0 +1,451 @@ +package gregtech.api.metatileentity.implementations; + +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; +import static net.minecraft.util.StatCollector.translateToLocal; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.common.util.ForgeDirection; + +import com.gtnewhorizons.modularui.api.drawable.UITexture; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.common.widget.ButtonWidget; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; +import com.gtnewhorizons.modularui.common.widget.TextWidget; + +import appeng.api.storage.IMEMonitor; +import appeng.api.storage.IMEMonitorHandlerReceiver; +import appeng.api.storage.StorageChannel; +import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IItemList; +import appeng.util.item.AEItemStack; +import appeng.util.item.ItemList; +import gregtech.api.enums.GTValues; +import gregtech.api.gui.modularui.GTUIInfos; +import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.modularui.IAddUIWidgets; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.objects.AE2NonconsumableHatchHandler; +import gregtech.api.util.GTLanguageManager; +import gregtech.api.util.GTUtility; + +public abstract class MTEHatchNonConsumableBase extends MTEHatch implements IMEMonitor, IAddUIWidgets { + + private ItemStack itemStack = null; + private int itemCount = 0; + private boolean isOutputSlotLocked = true; + private Map, Object> listeners = null; + + public MTEHatchNonConsumableBase(int ID, String name, String nameRegional, int tier, String description) { + super(ID, name, nameRegional, tier, 3, new String[] { description, "Will keep its contents when broken" }); + } + + public MTEHatchNonConsumableBase(String name, int tier, String[] description, ITexture[][][] textures) { + super(name, tier, 3, description, textures); + } + + @Override + public boolean isSimpleMachine() { + return true; + } + + @Override + public boolean isFacingValid(ForgeDirection facing) { + return true; + } + + public ItemStack getItemStack() { + return itemStack; + } + + protected void setItemStack(ItemStack stack) { + itemStack = stack; + } + + public int getItemCount() { + return itemCount; + } + + @Override + public void setItemCount(int amount) { + itemCount = amount; + } + + protected abstract int getItemCapacity(); + + protected abstract boolean isValidItem(ItemStack item); + + protected int clientItemCount; + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + builder.widget( + new DrawableWidget().setDrawable(GTUITextures.PICTURE_SCREEN_BLACK) + .setPos(7, 16) + .setSize(71, 45)) + .widget( + new SlotWidget(inventoryHandler, 0) + .setBackground(getGUITextureSet().getItemSlot(), GTUITextures.OVERLAY_SLOT_IN) + .setPos(79, 16)) + .widget( + new SlotWidget(inventoryHandler, 1).setAccess(true, false) + .setBackground(getGUITextureSet().getItemSlot(), GTUITextures.OVERLAY_SLOT_OUT) + .setPos(79, 52)) + .widget( + SlotWidget.phantom(inventoryHandler, 2) + .disableInteraction() + .setBackground(GTUITextures.TRANSPARENT) + .setPos(59, 42)) + .widget( + new TextWidget("Item Amount").setDefaultColor(COLOR_TEXT_WHITE.get()) + .setPos(10, 20)) + .widget( + new TextWidget().setStringSupplier(() -> numberFormat.format(clientItemCount)) + .setDefaultColor(COLOR_TEXT_WHITE.get()) + .setPos(10, 30)) + .widget( + new ButtonWidget().setOnClick((clickData, widget) -> { isOutputSlotLocked = !isOutputSlotLocked; }) + .setBackground( + () -> new UITexture[] { + isOutputSlotLocked ? GTUITextures.BUTTON_STANDARD_PRESSED : GTUITextures.BUTTON_STANDARD, + isOutputSlotLocked ? GTUITextures.OVERLAY_BUTTON_RECIPE_LOCKED + : GTUITextures.OVERLAY_BUTTON_RECIPE_UNLOCKED }) + .addTooltip(translateToLocal("GT5U.gui.button.toggle_output_slot_lock")) + .setTooltipShowUpDelay(TOOLTIP_DELAY) + .attachSyncer( + new FakeSyncWidget.BooleanSyncer(() -> isOutputSlotLocked, val -> isOutputSlotLocked = val), + builder) + .setPos(100, 52) + .setSize(18, 18)) + .widget(new FakeSyncWidget.IntegerSyncer(() -> itemCount, value -> clientItemCount = value)); + + } + + @Override + public void addAdditionalTooltipInformation(ItemStack stack, List tooltip) { + tooltip.add("Capacity: " + EnumChatFormatting.GOLD + getItemCapacity() + EnumChatFormatting.GRAY + " Items"); + if (stack.hasTagCompound() && stack.stackTagCompound.hasKey("itemStack")) { + final ItemStack tContents = ItemStack + .loadItemStackFromNBT(stack.stackTagCompound.getCompoundTag("itemStack")); + final int tSize = stack.stackTagCompound.getInteger("itemCount"); + if (tContents != null && tSize > 0) { + tooltip.add( + GTLanguageManager.addStringLocalization("TileEntity_CHEST_INFO", "Contains Item: ") + + EnumChatFormatting.YELLOW + + tContents.getDisplayName() + + EnumChatFormatting.GRAY); + tooltip.add( + GTLanguageManager.addStringLocalization("TileEntity_CHEST_AMOUNT", "Item Amount: ") + + EnumChatFormatting.GREEN + + GTUtility.formatNumbers(tSize) + + EnumChatFormatting.GRAY); + } + } + } + + public static void registerAEIntegration() { + appeng.api.AEApi.instance() + .registries() + .externalStorage() + .addExternalStorageInterface(new AE2NonconsumableHatchHandler()); + } + + @Override + public void addListener(IMEMonitorHandlerReceiver meMonitorHandlerReceiver, Object o) { + if (listeners == null) listeners = new HashMap<>(); + listeners.put(meMonitorHandlerReceiver, o); + } + + @Override + public void removeListener(IMEMonitorHandlerReceiver meMonitorHandlerReceiver) { + if (listeners == null) listeners = new HashMap<>(); + listeners.remove(meMonitorHandlerReceiver); + } + + @Override + public appeng.api.config.AccessRestriction getAccess() { + return appeng.api.config.AccessRestriction.READ_WRITE; + } + + @Override + public boolean isPrioritized(IAEItemStack aeItemStack) { + ItemStack s = getItemStack(); + if (s == null || aeItemStack == null) return false; + return aeItemStack.isSameType(s); + } + + @Override + public boolean canAccept(IAEItemStack aeItemStack) { + ItemStack s = getItemStack(); + if (s == null || aeItemStack == null) return true; + return aeItemStack.isSameType(s); + } + + @Override + public int getPriority() { + return 0; + } + + @Override + public int getSlot() { + return 0; + } + + @Override + public boolean validForPass(int i) { + return true; + } + + @SuppressWarnings("unchecked") + @Override + public IItemList getAvailableItems(final IItemList out, int iteration) { + ItemStack storedStack = getItemStack(); + if (storedStack != null) { + AEItemStack s = AEItemStack.create(storedStack); + s.setStackSize(getItemCount()); + out.add(s); + } + return out; + } + + @Override + public IItemList getStorageList() { + IItemList res = new ItemList(); + ItemStack storedStack = getItemStack(); + if (storedStack != null) { + AEItemStack s = AEItemStack.create(storedStack); + s.setStackSize(getItemCount()); + res.add(s); + } + return res; + } + + @Override + public IAEItemStack injectItems(final IAEItemStack input, final appeng.api.config.Actionable mode, + final appeng.api.networking.security.BaseActionSource src) { + if (getBaseMetaTileEntity() == null) return input; + + final ItemStack inputStack = input.getItemStack(); + final int maxCapacity = getItemCapacity(); + final int itemCount = getItemCount(); + final long toAdd = input.getStackSize(); + final ItemStack storedStack = getItemStack(); + + if (storedStack != null && !GTUtility.areStacksEqual(storedStack, inputStack)) { + // Can't stack with existing item, just return the input. + return input; + } + + if (storedStack == null && !isValidItem(inputStack)) { + // Invalid item, return input. + return input; + } + + // Number of items not added because there's too much to add. + final long notAdded = itemCount + toAdd - maxCapacity; + + if (mode == appeng.api.config.Actionable.MODULATE) { + final int newCount = (int) Math.min(maxCapacity, itemCount + toAdd); + + if (storedStack == null) { + setItemStack(inputStack.copy()); + } + setItemCount(newCount); + getBaseMetaTileEntity().markDirty(); + } + + if (notAdded <= 0) { + return null; + } else { + return input.copy() + .setStackSize(notAdded); + } + + } + + @Override + public IAEItemStack extractItems(final IAEItemStack request, final appeng.api.config.Actionable mode, + final appeng.api.networking.security.BaseActionSource src) { + if (request.isSameType(getItemStack())) { + if (getBaseMetaTileEntity() == null) return null; + if (mode != appeng.api.config.Actionable.SIMULATE) getBaseMetaTileEntity().markDirty(); + if (request.getStackSize() >= getItemCount()) { + AEItemStack result = AEItemStack.create(getItemStack()); + result.setStackSize(getItemCount()); + if (mode != appeng.api.config.Actionable.SIMULATE) setItemCount(0); + return result; + } else { + if (mode != appeng.api.config.Actionable.SIMULATE) + setItemCount(getItemCount() - (int) request.getStackSize()); + return request.copy(); + } + } + return null; + } + + private void notifyListeners(int count, ItemStack stack) { + if (listeners == null) { + listeners = new HashMap<>(); + return; + } + if (count == 0 || stack == null) return; + ItemList change = new ItemList(); + AEItemStack s = AEItemStack.create(stack); + s.setStackSize(count); + change.add(s); + listeners.forEach((l, o) -> { + if (l.isValid(o)) l.postChange(this, change, null); + else removeListener(l); + }); + } + + private boolean hasActiveMEConnection() { + if (listeners == null || listeners.isEmpty()) return false; + for (Map.Entry, Object> e : listeners.entrySet()) { + if ((e.getKey() instanceof appeng.api.parts.IPart)) { + appeng.api.networking.IGridNode n = ((appeng.api.parts.IPart) e.getKey()).getGridNode(); + if (n != null && n.isActive()) return true; + } + } + // if there are no active storage buses - clear the listeners + listeners.clear(); + return false; + } + + @Override + public StorageChannel getChannel() { + return StorageChannel.ITEMS; + } + + @Override + public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTimer) { + + if (getBaseMetaTileEntity().isServerSide() && getBaseMetaTileEntity().isAllowedToWork()) { + if ((getItemCount() <= 0)) { + setItemStack(null); + setItemCount(0); + } + if (getItemStack() == null && mInventory[0] != null && isValidItem(mInventory[0])) { + setItemStack(mInventory[0].copy()); + } + int count = getItemCount(); + ItemStack stack = getItemStack(); + int savedCount = count; + + if ((mInventory[0] != null) && ((count < getItemCapacity())) + && GTUtility.areStacksEqual(mInventory[0], stack)) { + count += mInventory[0].stackSize; + if (count <= getItemCapacity()) { + mInventory[0] = null; + } else { + mInventory[0].stackSize = (count - getItemCapacity()); + count = getItemCapacity(); + } + } + if (mInventory[1] == null && stack != null && !isOutputSlotLocked) { + mInventory[1] = stack.copy(); + mInventory[1].stackSize = Math.min(stack.getMaxStackSize(), count); + count -= mInventory[1].stackSize; + } else if ((count > 0) && GTUtility.areStacksEqual(mInventory[1], stack) + && mInventory[1].getMaxStackSize() > mInventory[1].stackSize + && !isOutputSlotLocked) { + int tmp = Math.min(count, mInventory[1].getMaxStackSize() - mInventory[1].stackSize); + mInventory[1].stackSize += tmp; + count -= tmp; + } + setItemCount(count); + if (stack != null) { + mInventory[2] = stack.copy(); + mInventory[2].stackSize = Math.min(stack.getMaxStackSize(), count); + } else { + mInventory[2] = null; + } + + notifyListeners(count - savedCount, stack); + if (count != savedCount) getBaseMetaTileEntity().markDirty(); + } + } + + @Override + public boolean isAccessAllowed(EntityPlayer aPlayer) { + return true; + } + + @Override + public boolean onRightclick(IGregTechTileEntity aBaseMetaTileEntity, EntityPlayer aPlayer) { + GTUIInfos.openGTTileEntityUI(aBaseMetaTileEntity, aPlayer); + return true; + } + + @Override + public void setItemNBT(NBTTagCompound aNBT) { + NBTTagList invData = new NBTTagList(); + boolean hasInvData = false; + for (int i = 0; i < 3; i++) { + if (mInventory[i] != null) { + NBTTagCompound tNBT = new NBTTagCompound(); + tNBT.setByte("count", (byte) mInventory[i].stackSize); + tNBT.setShort("damage", (short) mInventory[i].getItemDamage()); + tNBT.setShort("id", (short) Item.getIdFromItem(mInventory[i].getItem())); + tNBT.setInteger("intSlot", i); + if (mInventory[i].hasTagCompound()) { + tNBT.setTag("tag", mInventory[i].getTagCompound()); + } + invData.appendTag(tNBT); + hasInvData = true; + } + } + if (getItemStack() != null) aNBT.setTag("itemStack", getItemStack().writeToNBT(new NBTTagCompound())); + if (hasInvData) aNBT.setTag("inventory", invData); + if (getItemCount() > 0) aNBT.setInteger("itemCount", getItemCount()); + + super.setItemNBT(aNBT); + } + + @Override + public void saveNBTData(NBTTagCompound aNBT) { + aNBT.setInteger("itemCount", getItemCount()); + if (getItemStack() != null) aNBT.setTag("itemStack", getItemStack().writeToNBT(new NBTTagCompound())); + } + + @Override + public void loadNBTData(NBTTagCompound aNBT) { + if (aNBT.hasKey("itemCount")) setItemCount(aNBT.getInteger("itemCount")); + if (aNBT.hasKey("itemStack")) + setItemStack(ItemStack.loadItemStackFromNBT((NBTTagCompound) aNBT.getTag("itemStack"))); + } + + @Override + public boolean allowPullStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + if (GTValues.disableDigitalChestsExternalAccess && hasActiveMEConnection()) return false; + return aIndex == 1; + } + + @Override + public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, ForgeDirection side, + ItemStack aStack) { + if (GTValues.disableDigitalChestsExternalAccess && hasActiveMEConnection()) return false; + if (aIndex != 0) return false; + if ((mInventory[0] != null && !GTUtility.areStacksEqual(mInventory[0], aStack))) return false; + if (getItemStack() == null) return mInventory[1] == null || GTUtility.areStacksEqual(mInventory[1], aStack); + return GTUtility.areStacksEqual(getItemStack(), aStack); + } + + @Override + public ItemStack[] getStoredItemData() { + return mInventory; + } +} diff --git a/src/main/java/gregtech/api/objects/AE2NonconsumableHatchHandler.java b/src/main/java/gregtech/api/objects/AE2NonconsumableHatchHandler.java new file mode 100644 index 00000000000..62307c8ce91 --- /dev/null +++ b/src/main/java/gregtech/api/objects/AE2NonconsumableHatchHandler.java @@ -0,0 +1,26 @@ +package gregtech.api.objects; + +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; + +import gregtech.api.metatileentity.BaseMetaTileEntity; +import gregtech.api.metatileentity.implementations.MTEHatchNonConsumableBase; + +public class AE2NonconsumableHatchHandler implements appeng.api.storage.IExternalStorageHandler { + + @Override + public boolean canHandle(final TileEntity te, final ForgeDirection d, final appeng.api.storage.StorageChannel chan, + final appeng.api.networking.security.BaseActionSource mySrc) { + return chan == appeng.api.storage.StorageChannel.ITEMS && te instanceof BaseMetaTileEntity + && ((BaseMetaTileEntity) te).getMetaTileEntity() instanceof MTEHatchNonConsumableBase; + } + + @Override + public appeng.api.storage.IMEInventory getInventory(final TileEntity te, final ForgeDirection d, + final appeng.api.storage.StorageChannel chan, final appeng.api.networking.security.BaseActionSource src) { + if (chan == appeng.api.storage.StorageChannel.ITEMS) { + return ((MTEHatchNonConsumableBase) (((BaseMetaTileEntity) te).getMetaTileEntity())); + } + return null; + } +} diff --git a/src/main/java/gregtech/api/recipe/RecipeMaps.java b/src/main/java/gregtech/api/recipe/RecipeMaps.java index d3f107123de..6c7fbe7b48f 100644 --- a/src/main/java/gregtech/api/recipe/RecipeMaps.java +++ b/src/main/java/gregtech/api/recipe/RecipeMaps.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.List; import java.util.Optional; import net.minecraft.init.Blocks; @@ -1101,11 +1102,18 @@ && isArrayEmptyOrNull(b.getFluidOutputs()) .minInputs(3, 1) .progressBar(GTUITextures.PROGRESSBAR_ASSEMBLE) .disableOptimize() + .neiHandlerInfo(builder -> builder.setDisplayStack(ItemList.PCBFactory.get(1))) .neiRecipeComparator( Comparator .comparing(recipe -> recipe.getMetadataOrDefault(PCBFactoryTierKey.INSTANCE, 1)) .thenComparing(GTRecipe::compareTo)) .build(); + public static final RecipeMap pcbFactoryRecipesNoNanites = RecipeMapBuilder + .of("gt.recipe.pcbfactorynonanites") + .maxIO(6, 9, 3, 0) + .minInputs(3, 1) + .disableOptimize() + .build(); public static final RecipeMap purificationClarifierRecipes = RecipeMapBuilder .of("gt.recipe.purificationplantclarifier") .maxIO(1, 4, 1, 1) @@ -1228,5 +1236,28 @@ && isArrayEmptyOrNull(b.getFluidOutputs()) b.copy() .duration(1 * TICK) .eut(TierEU.RECIPE_UEV)))); + RecipeMaps.pcbFactoryRecipes.addDownstream(IRecipeMap.newRecipeMap(b -> { + b = b.copy(); + List itemInputs = new ArrayList<>(); + + Materials naniteMaterial = null; + for (int i = 0; i < b.getItemInputsBasic().length; i++) { + ItemStack stack = b.getItemInputBasic(i); + if (stack == null) continue; + ItemData data = GTOreDictUnificator.getAssociation(stack); + if (data != null && data.mPrefix != null && data.mPrefix.equals(OrePrefixes.nanite)) { + naniteMaterial = data.mMaterial.mMaterial; + continue; + } + itemInputs.add(stack); + } + + if (naniteMaterial != null) { + b.metadata(GTRecipeConstants.PCB_NANITE_MATERIAL, naniteMaterial); + } + return RecipeMaps.pcbFactoryRecipesNoNanites.doAdd( + b.itemInputs(itemInputs.toArray(new ItemStack[0])) + .hidden()); + })); } } diff --git a/src/main/java/gregtech/api/util/GTRecipeConstants.java b/src/main/java/gregtech/api/util/GTRecipeConstants.java index a719edba387..0edba4df3f7 100644 --- a/src/main/java/gregtech/api/util/GTRecipeConstants.java +++ b/src/main/java/gregtech/api/util/GTRecipeConstants.java @@ -117,6 +117,12 @@ public class GTRecipeConstants { public static final RecipeMetadataKey NANO_FORGE_TIER = SimpleRecipeMetadataKey .create(Integer.class, "nano_forge_tier"); + /** + * PCB Factory nanite material + */ + public static final RecipeMetadataKey PCB_NANITE_MATERIAL = SimpleRecipeMetadataKey + .create(Materials.class, "pcb_nanite_material"); + /** * FOG Exotic recipe tier. */ @@ -159,6 +165,12 @@ public class GTRecipeConstants { public static final RecipeMetadataKey QFT_FOCUS_TIER = SimpleRecipeMetadataKey .create(Integer.class, "qft_focus_tier"); + /** + * QFT catalyst meta. + */ + public static final RecipeMetadataKey QFT_CATALYST_META = SimpleRecipeMetadataKey + .create(Integer.class, "qft_catalyst_meta"); + /** * Tier of advanced compression (HIP/black hole) */ diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/MTEPCBFactory.java b/src/main/java/gregtech/common/tileentities/machines/multi/MTEPCBFactory.java index 189bdd4640f..11ecfbddb60 100644 --- a/src/main/java/gregtech/common/tileentities/machines/multi/MTEPCBFactory.java +++ b/src/main/java/gregtech/common/tileentities/machines/multi/MTEPCBFactory.java @@ -19,6 +19,8 @@ import static gregtech.api.util.GTStructureUtility.ofFrame; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import javax.annotation.Nonnull; @@ -61,10 +63,10 @@ import gregtech.api.GregTechAPI; import gregtech.api.enums.Materials; import gregtech.api.enums.Mods; -import gregtech.api.enums.OrePrefixes; import gregtech.api.enums.SoundResource; import gregtech.api.enums.Textures.BlockIcons; import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.IHatchElement; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; @@ -73,7 +75,7 @@ import gregtech.api.metatileentity.implementations.MTEExtendedPowerMultiBlockBase; import gregtech.api.metatileentity.implementations.MTEHatch; import gregtech.api.metatileentity.implementations.MTEHatchInput; -import gregtech.api.objects.ItemData; +import gregtech.api.metatileentity.implementations.MTEHatchNanite; import gregtech.api.recipe.RecipeMap; import gregtech.api.recipe.RecipeMaps; import gregtech.api.recipe.check.CheckRecipeResult; @@ -84,9 +86,10 @@ import gregtech.api.recipe.metadata.PCBFactoryUpgradeKey; import gregtech.api.render.TextureFactory; import gregtech.api.util.GTModHandler; -import gregtech.api.util.GTOreDictUnificator; import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeConstants; import gregtech.api.util.GTUtility; +import gregtech.api.util.IGTHatchAdder; import gregtech.api.util.MultiblockTooltipBuilder; import gregtech.api.util.OverclockCalculator; import gregtech.api.util.ParallelHelper; @@ -113,6 +116,7 @@ public class MTEPCBFactory extends MTEExtendedPowerMultiBlockBase private final int[] mOCTier1Offsets = new int[] { 2, -11 }; private final int[] mOCTier2Offsets = new int[] { 2, -11 }; private MTEHatchInput mCoolantInputHatch; + private final ArrayList naniteBuses = new ArrayList<>(); private static final int mBioRotateBitMap = 0b1000000; private static final int mOCTier2BitMap = 0b100000; private static final int mOCTier1BitMap = 0b10000; @@ -236,7 +240,13 @@ public class MTEPCBFactory extends MTEExtendedPowerMultiBlockBase .addElement( 'P', buildHatchAdder(MTEPCBFactory.class) - .atLeast(InputHatch, OutputBus, InputBus, Maintenance, Energy.or(ExoticEnergy)) + .atLeast( + InputHatch, + OutputBus, + InputBus, + Maintenance, + Energy.or(ExoticEnergy), + SpecialHatchElement.NaniteBus) .dot(1) .casingIndex(((BlockCasings8) GregTechAPI.sBlockCasings8).getTextureIndex(11)) .buildAndChain(GregTechAPI.sBlockCasings8, 11)) @@ -247,7 +257,13 @@ public class MTEPCBFactory extends MTEExtendedPowerMultiBlockBase .addElement( 'J', buildHatchAdder(MTEPCBFactory.class) - .atLeast(InputHatch, OutputBus, InputBus, Maintenance, Energy.or(ExoticEnergy)) + .atLeast( + InputHatch, + OutputBus, + InputBus, + Maintenance, + Energy.or(ExoticEnergy), + SpecialHatchElement.NaniteBus) .dot(1) .casingIndex(((BlockCasings8) GregTechAPI.sBlockCasings8).getTextureIndex(13)) .buildAndChain(GregTechAPI.sBlockCasings8, 13)) @@ -458,6 +474,7 @@ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack a mTier = 0; mUpgradesInstalled = 0; mCoolantInputHatch = null; + naniteBuses.clear(); if (mSetTier < 3) { if (!checkPiece(tier1, 3, 5, 0)) { return false; @@ -537,7 +554,7 @@ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack a @Override public RecipeMap getRecipeMap() { - return RecipeMaps.pcbFactoryRecipes; + return RecipeMaps.pcbFactoryRecipesNoNanites; } @Override @@ -549,13 +566,24 @@ protected ProcessingLogic createProcessingLogic() { protected CheckRecipeResult validateRecipe(@Nonnull GTRecipe recipe) { // Here we check the dynamic parallels, which depend on the recipe int numberOfNanites = 0; - ItemStack aNanite = recipe.getRepresentativeInput(1); - ItemData naniteData = GTOreDictUnificator.getAssociation(aNanite); - if (naniteData != null && naniteData.mPrefix != null && naniteData.mPrefix.equals(OrePrefixes.nanite)) { - for (ItemStack aItem : inputItems) { - if (aItem != null && aItem.isItemEqual(aNanite)) { - numberOfNanites += aItem.stackSize; + Materials naniteMaterial = recipe.getMetadata(GTRecipeConstants.PCB_NANITE_MATERIAL); + if (naniteMaterial != null) { + if (naniteBuses.isEmpty()) { + return SimpleCheckRecipeResult.ofFailure("nanites_missing"); + } + boolean nanitesFound = false; + for (MTEHatchNanite naniteBus : naniteBuses) { + ItemStack storedNanites = naniteBus.getItemStack(); + Materials storedNaniteMaterial = naniteBus.getStoredNaniteMaterial(); + if (storedNanites == null || storedNaniteMaterial != naniteMaterial) { + continue; } + numberOfNanites = naniteBus.getItemCount(); + nanitesFound = true; + break; + } + if (!nanitesFound) { + return SimpleCheckRecipeResult.ofFailure("nanites_missing"); } } maxParallel = (int) Math.min(Math.max(Math.ceil(Math.pow(numberOfNanites, 0.75)), 1), 256); @@ -846,6 +874,7 @@ protected MultiblockTooltipBuilder createTooltip() { .addInfo("Each tier and upgrade requires additional structures.") .addInfo("Power consumption is multiplied by Sqrt(structures).") .addInfo("Tier 2 and 3 allow parallel by using extra nanites.") + .addInfo("Nanites have to be placed in a Nanite Containment Bus.") .addInfo("The formula for parallels is the amount of nanites^0.75, rounded up.") .addInfo("Maximum parallel is 256.") .addInfo("Recipes require a cooling upgrade to be overclocked.") @@ -872,7 +901,14 @@ protected MultiblockTooltipBuilder createTooltip() { .addOutputBus(EnumChatFormatting.GOLD + "0" + EnumChatFormatting.GRAY + "+", 1) .addInputHatch(EnumChatFormatting.GOLD + "0" + EnumChatFormatting.GRAY + "+", 1) .addStructureInfo( - "Coolant Hatch (Input Hatch): " + EnumChatFormatting.GOLD + EnumChatFormatting.WHITE + "Nanite Containment Bus: " + + EnumChatFormatting.GOLD + + "0" + + EnumChatFormatting.GRAY + + "+") + .addStructureInfo( + EnumChatFormatting.WHITE + "Coolant Hatch (Input Hatch): " + + EnumChatFormatting.GOLD + "1" + EnumChatFormatting.GRAY + " Center of the Liquid Cooling/Thermosink") @@ -1006,7 +1042,7 @@ public byte getUpdateData() { data += mTier1BitMap; } else if (mSetTier == 2) { data += mTier2BitMap; - } else { + } else if (mSetTier == 3) { data += mTier3BitMap; } @@ -1262,6 +1298,46 @@ protected ModularWindow createConfigurationWindow(final EntityPlayer player) { return builder.build(); } + public boolean addNaniteBusToMachineList(IGregTechTileEntity tileEntity, int baseCasingIndex) { + if (tileEntity == null) return false; + IMetaTileEntity metaTileEntity = tileEntity.getMetaTileEntity(); + if (metaTileEntity instanceof MTEHatchNanite naniteBus) { + naniteBus.updateTexture(baseCasingIndex); + this.naniteBuses.add(naniteBus); + return true; + } + return false; + } + + private enum SpecialHatchElement implements IHatchElement { + + NaniteBus(MTEPCBFactory::addNaniteBusToMachineList, MTEHatchNanite.class) { + + @Override + public long count(MTEPCBFactory gtMetaTileEntityPCBFactory) { + return gtMetaTileEntityPCBFactory.naniteBuses.size(); + } + }; + + private final List> mteClasses; + private final IGTHatchAdder adder; + + @SafeVarargs + SpecialHatchElement(IGTHatchAdder adder, Class... mteClasses) { + this.mteClasses = Collections.unmodifiableList(Arrays.asList(mteClasses)); + this.adder = adder; + } + + @Override + public List> mteClasses() { + return mteClasses; + } + + public IGTHatchAdder adder() { + return adder; + } + } + @Override public boolean supportsVoidProtection() { return true; diff --git a/src/main/java/gregtech/loaders/preload/LoaderMetaTileEntities.java b/src/main/java/gregtech/loaders/preload/LoaderMetaTileEntities.java index b4bcce38d3d..964b3029513 100644 --- a/src/main/java/gregtech/loaders/preload/LoaderMetaTileEntities.java +++ b/src/main/java/gregtech/loaders/preload/LoaderMetaTileEntities.java @@ -947,6 +947,7 @@ import gregtech.api.metatileentity.implementations.MTECable; import gregtech.api.metatileentity.implementations.MTEFluid; import gregtech.api.metatileentity.implementations.MTEFrame; +import gregtech.api.metatileentity.implementations.MTEHatchBulkCatalystHousing; import gregtech.api.metatileentity.implementations.MTEHatchDataAccess; import gregtech.api.metatileentity.implementations.MTEHatchDynamo; import gregtech.api.metatileentity.implementations.MTEHatchEnergy; @@ -956,6 +957,7 @@ import gregtech.api.metatileentity.implementations.MTEHatchMaintenance; import gregtech.api.metatileentity.implementations.MTEHatchMuffler; import gregtech.api.metatileentity.implementations.MTEHatchMultiInput; +import gregtech.api.metatileentity.implementations.MTEHatchNanite; import gregtech.api.metatileentity.implementations.MTEHatchOutput; import gregtech.api.metatileentity.implementations.MTEHatchOutputBus; import gregtech.api.metatileentity.implementations.MTEHatchQuadrupleHumongous; @@ -12997,6 +12999,15 @@ public void run() { ItemList.Hatch_LensIndicator.set( new MTEHatchLensIndicator(HATCH_LENS_INDICATOR.ID, "hatch.lensindicator", "Lens Indicator Hatch", 8) .getStackForm(1L)); + ItemList.Hatch_Nanite.set( + new MTEHatchNanite(HATCH_NANITE.ID, "hatch.nanite", "Nanite Containment Bus", 9, 2048).getStackForm(1)); + ItemList.Hatch_Catalyst_Bulk.set( + new MTEHatchBulkCatalystHousing( + HATCH_CATALYST_BULK.ID, + "hatch.catalystbulk", + "Bulk Catalyst Housing", + 10, + Integer.MAX_VALUE).getStackForm(1)); generateWiresAndPipes(); } diff --git a/src/main/java/gregtech/nei/NEIGTConfig.java b/src/main/java/gregtech/nei/NEIGTConfig.java index ab81530e1fe..ec0bd165d17 100644 --- a/src/main/java/gregtech/nei/NEIGTConfig.java +++ b/src/main/java/gregtech/nei/NEIGTConfig.java @@ -103,6 +103,7 @@ private void registerCatalysts() { API.addRecipeCatalyst( GTModHandler.getIC2Item("nuclearReactor", 1, null), RecipeMaps.ic2NuclearFakeRecipes.unlocalizedName); + API.addRecipeCatalyst(ItemList.PCBFactory.get(1), RecipeMaps.pcbFactoryRecipes.unlocalizedName); } private void registerItemEntries() { diff --git a/src/main/java/gtPlusPlus/api/recipe/GTPPRecipeMaps.java b/src/main/java/gtPlusPlus/api/recipe/GTPPRecipeMaps.java index 0ac958df4f3..2ee6ff219a6 100644 --- a/src/main/java/gtPlusPlus/api/recipe/GTPPRecipeMaps.java +++ b/src/main/java/gtPlusPlus/api/recipe/GTPPRecipeMaps.java @@ -1,15 +1,20 @@ package gtPlusPlus.api.recipe; import static gregtech.api.util.GTRecipeConstants.LFTR_OUTPUT_POWER; +import static gregtech.api.util.GTRecipeConstants.QFT_CATALYST_META; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import net.minecraft.item.ItemStack; import net.minecraft.util.StatCollector; import com.gtnewhorizons.modularui.common.widget.ProgressBar; import gregtech.api.gui.modularui.GTUITextures; +import gregtech.api.interfaces.IRecipeMap; import gregtech.api.recipe.RecipeMap; import gregtech.api.recipe.RecipeMapBackend; import gregtech.api.recipe.RecipeMapBuilder; @@ -22,6 +27,7 @@ import gregtech.nei.formatter.SimpleSpecialValueFormatter; import gtPlusPlus.core.util.math.MathUtils; import gtPlusPlus.core.util.minecraft.ItemUtils; +import gtPlusPlus.xmod.gregtech.api.enums.GregtechItemList; import gtPlusPlus.xmod.gregtech.api.gui.GTPPUITextures; import gtPlusPlus.xmod.gregtech.common.tileentities.machines.multi.production.MTETreeFarm; @@ -50,10 +56,17 @@ public class GTPPRecipeMaps { .maxIO(6, 6, 6, 6) .minInputs(1, 0) .progressBar(GTUITextures.PROGRESSBAR_ARROW_MULTIPLE) + .neiHandlerInfo(builder -> builder.setDisplayStack(GregtechItemList.QuantumForceTransformer.get(1))) .neiSpecialInfoFormatter(new SimpleSpecialValueFormatter("GT5U.nei.tier")) .frontend(QuantumForceTransformerFrontend::new) .disableOptimize() .build(); + public static final RecipeMap quantumForceTransformerRecipesNoCatalysts = RecipeMapBuilder + .of("gtpp.recipe.quantumforcesmelternocatalysts") + .maxIO(6, 6, 6, 6) + .minInputs(0, 0) + .disableOptimize() + .build(); public static final RecipeMap chemicalDehydratorRecipes = RecipeMapBuilder .of("gtpp.recipe.chemicaldehydrator") .maxIO(2, 9, 1, 1) @@ -241,4 +254,29 @@ public class GTPPRecipeMaps { .maxIO(2, 1, 0, 0) .disableRegisterNEI() .build(); + + static { + GTPPRecipeMaps.quantumForceTransformerRecipes.addDownstream(IRecipeMap.newRecipeMap(b -> { + b = b.copy(); + List itemInputs = new ArrayList<>(); + + int meta = -1; + for (int i = 0; i < b.getItemInputsBasic().length; i++) { + ItemStack stack = b.getItemInputBasic(i); + if (stack == null) continue; + if (ItemUtils.isCatalyst(stack)) { + meta = stack.getItemDamage(); + continue; + } + itemInputs.add(stack); + } + + if (meta != -1) { + b.metadata(QFT_CATALYST_META, meta); + } + return GTPPRecipeMaps.quantumForceTransformerRecipesNoCatalysts.doAdd( + b.itemInputs(itemInputs.toArray(new ItemStack[0])) + .hidden()); + })); + } } diff --git a/src/main/java/gtPlusPlus/nei/NEIGTPPConfig.java b/src/main/java/gtPlusPlus/nei/NEIGTPPConfig.java index 05d0991e4c5..9c0d933cf70 100644 --- a/src/main/java/gtPlusPlus/nei/NEIGTPPConfig.java +++ b/src/main/java/gtPlusPlus/nei/NEIGTPPConfig.java @@ -68,6 +68,10 @@ public synchronized void loadConfig() { API.addItemListEntry(GregtechItemList.VOLUMETRIC_FLASK_32k.get(1)); API.addItemListEntry(GregtechItemList.KLEIN_BOTTLE.get(1)); } + // QFT + API.addRecipeCatalyst( + GregtechItemList.QuantumForceTransformer.get(1), + GTPPRecipeMaps.quantumForceTransformerRecipes.unlocalizedName); sIsAdded = true; } diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/nbthandlers/MTEHatchCatalysts.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/nbthandlers/MTEHatchCatalysts.java index ca8624a7d28..fcaec57ba25 100644 --- a/src/main/java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/nbthandlers/MTEHatchCatalysts.java +++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/metatileentity/implementations/nbthandlers/MTEHatchCatalysts.java @@ -10,7 +10,7 @@ import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.MetaTileEntity; -import gregtech.api.objects.GTRenderedTexture; +import gregtech.api.render.TextureFactory; import gtPlusPlus.core.lib.GTPPCore; import gtPlusPlus.core.util.minecraft.ItemUtils; import gtPlusPlus.xmod.gregtech.common.blocks.textures.TexturesGtBlock; @@ -27,12 +27,28 @@ public MTEHatchCatalysts(String aName, String[] aDescription, ITexture[][][] aTe @Override public ITexture[] getTexturesActive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, new GTRenderedTexture(TexturesGtBlock.Overlay_Bus_Catalyst) }; + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(TexturesGtBlock.Overlay_Bus_Catalyst) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(TexturesGtBlock.Overlay_Bus_Catalyst) + .extFacing() + .glow() + .build() }; } @Override public ITexture[] getTexturesInactive(ITexture aBaseTexture) { - return new ITexture[] { aBaseTexture, new GTRenderedTexture(TexturesGtBlock.Overlay_Bus_Catalyst) }; + return new ITexture[] { aBaseTexture, TextureFactory.builder() + .addIcon(TexturesGtBlock.Overlay_Bus_Catalyst) + .extFacing() + .build(), + TextureFactory.builder() + .addIcon(TexturesGtBlock.Overlay_Bus_Catalyst) + .extFacing() + .glow() + .build() }; } @Override diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/multi/production/MTEQuantumForceTransformer.java b/src/main/java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/multi/production/MTEQuantumForceTransformer.java index 58525e1d806..4744595302d 100644 --- a/src/main/java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/multi/production/MTEQuantumForceTransformer.java +++ b/src/main/java/gtPlusPlus/xmod/gregtech/common/tileentities/machines/multi/production/MTEQuantumForceTransformer.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import javax.annotation.Nonnull; @@ -56,12 +57,14 @@ import gregtech.api.enums.SoundResource; import gregtech.api.enums.TAE; import gregtech.api.enums.Textures; +import gregtech.api.interfaces.IHatchElement; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.logic.ProcessingLogic; import gregtech.api.metatileentity.implementations.MTEExtendedPowerMultiBlockBase; import gregtech.api.metatileentity.implementations.MTEHatch; +import gregtech.api.metatileentity.implementations.MTEHatchBulkCatalystHousing; import gregtech.api.metatileentity.implementations.MTEHatchInput; import gregtech.api.objects.ItemData; import gregtech.api.recipe.RecipeMap; @@ -70,14 +73,15 @@ import gregtech.api.recipe.check.SimpleCheckRecipeResult; import gregtech.api.render.TextureFactory; import gregtech.api.util.GTRecipe; +import gregtech.api.util.GTRecipeConstants; import gregtech.api.util.GTUtility; +import gregtech.api.util.IGTHatchAdder; import gregtech.api.util.MultiblockTooltipBuilder; import gregtech.api.util.ParallelHelper; import gregtech.api.util.shutdown.ShutDownReasonRegistry; import gtPlusPlus.api.recipe.GTPPRecipeMaps; import gtPlusPlus.core.block.ModBlocks; import gtPlusPlus.core.material.MaterialsElements; -import gtPlusPlus.core.util.minecraft.ItemUtils; import gtPlusPlus.xmod.gregtech.common.blocks.textures.TexturesGtBlock; @SuppressWarnings("SpellCheckingInspection") @@ -94,6 +98,7 @@ public class MTEQuantumForceTransformer extends MTEExtendedPowerMultiBlockBase catalystHounsings = new ArrayList<>(); private static final IStructureDefinition STRUCTURE_DEFINITION = StructureDefinition .builder() .addShape( @@ -200,7 +205,12 @@ public class MTEQuantumForceTransformer extends MTEExtendedPowerMultiBlockBase ++x.mCasing, ofBlock(ModBlocks.blockCasings2Misc, 12)))) @@ -245,15 +255,16 @@ protected MultiblockTooltipBuilder createTooltip() { tt.addMachineType("Quantum Force Transformer, QFT") .addInfo("Allows Complex chemical lines to be performed instantly in one step") .addInfo("Every recipe requires a catalyst, each catalyst adds 1 parallel and lasts forever") + .addInfo("Catalysts have to be placed in a Bulk Catalyst Housing") .addInfo("All inputs go on the bottom, all outputs go on the top") .addInfo("Put a circuit in the controller to specify the focused output") - .addInfo("Check NEI to see the order of outputs, and which circuit number you need.") + .addInfo("Check NEI to see the order of outputs, and which circuit number you need") .addInfo("If separate input busses are enabled put the circuit in the circuit slot of the bus") .addInfo("Uses FocusTier*4*sqrt(parallels) Neptunium Plasma if focusing") .addInfo("Can use FocusTier*4*sqrt(parallels) Fermium Plasma for additional chance output") .addInfo("Use a screwdriver to enable Fluid mode") .addInfo( - "Fluid mode turns all possible outputs into their fluid variant, those which can't are left as they were.") + "Fluid mode turns all possible outputs into their fluid variant, those which can't are left as they were") .addInfo("This multi gets improved when all casings of some types are upgraded") .addInfo("Casing functions:") .addInfo("Pulse Manipulators: Recipe Tier Allowed (check NEI for the tier of each recipe)") @@ -272,6 +283,12 @@ protected MultiblockTooltipBuilder createTooltip() { .addOutputHatch(EnumChatFormatting.AQUA + "Top" + EnumChatFormatting.GRAY + " Layer", 5) .addOutputBus(EnumChatFormatting.AQUA + "Top" + EnumChatFormatting.GRAY + " Layer", 5) .addEnergyHatch(EnumChatFormatting.BLUE + "Bottom" + EnumChatFormatting.GRAY + " Layer", 4) + .addStructureInfo( + EnumChatFormatting.WHITE + "Bulk Catalyst Housing: " + + EnumChatFormatting.BLUE + + "Bottom" + + EnumChatFormatting.GRAY + + " Layer") .addStructureInfo( EnumChatFormatting.WHITE + "Neptunium Plasma Hatch: " + EnumChatFormatting.GREEN @@ -298,6 +315,7 @@ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack a this.mCasing = 0; this.mCraftingTier = 0; this.mFocusingTier = 0; + catalystHounsings.clear(); if (!checkPiece(MAIN_PIECE, 7, 20, 4)) { return false; } @@ -420,7 +438,7 @@ protected int getCasingTextureId() { @Override public RecipeMap getRecipeMap() { - return GTPPRecipeMaps.quantumForceTransformerRecipes; + return GTPPRecipeMaps.quantumForceTransformerRecipesNoCatalysts; } @Override @@ -441,26 +459,31 @@ protected CheckRecipeResult validateRecipe(@NotNull GTRecipe recipe) { if (recipe.mSpecialValue > getCraftingTier()) { return CheckRecipeResultRegistry.insufficientMachineTier(recipe.mSpecialValue); } - ItemStack catalyst = null; - for (ItemStack item : recipe.mInputs) { - if (ItemUtils.isCatalyst(item)) { - catalyst = item; + + int numberOfCatalyst = 0; + int catalystMeta = recipe.getMetadataOrDefault(GTRecipeConstants.QFT_CATALYST_META, -1); + if (catalystMeta != -1) { + if (catalystHounsings.isEmpty()) { + return SimpleCheckRecipeResult.ofFailure("no_catalyst"); + } + boolean catalystsFound = false; + for (MTEHatchBulkCatalystHousing catalystHousing : catalystHounsings) { + ItemStack storedCatalysts = catalystHousing.getItemStack(); + int storedCatalystMeta = catalystHousing.getStoredCatalystMeta(); + if (storedCatalysts == null || storedCatalystMeta != catalystMeta) { + continue; + } + numberOfCatalyst = catalystHousing.getItemCount(); + catalystsFound = true; break; } - } - - if (catalyst == null) { - return SimpleCheckRecipeResult.ofFailure("no_catalyst"); - } - - maxParallel = 0; - for (ItemStack item : inputItems) { - if (ItemUtils.isCatalyst(item) && item.isItemEqual(catalyst)) { - maxParallel += item.stackSize; + if (!catalystsFound) { + return SimpleCheckRecipeResult.ofFailure("no_catalyst"); } } - mMaxParallel = maxParallel; + mMaxParallel = numberOfCatalyst; + maxParallel = mMaxParallel; doFermium = false; doNeptunium = false; @@ -734,6 +757,48 @@ public boolean addFermiumHatch(IGregTechTileEntity aTileEntity, short aBaseCasin return false; } + public boolean addCatalystHousingToMachineList(IGregTechTileEntity tileEntity, int baseCasingIndex) { + if (tileEntity == null) return false; + IMetaTileEntity metaTileEntity = tileEntity.getMetaTileEntity(); + if (metaTileEntity instanceof MTEHatchBulkCatalystHousing catalystHousing) { + catalystHousing.updateTexture(baseCasingIndex); + this.catalystHounsings.add(catalystHousing); + return true; + } + return false; + } + + private enum SpecialHatchElement implements IHatchElement { + + CatalystHousing(MTEQuantumForceTransformer::addCatalystHousingToMachineList, + MTEHatchBulkCatalystHousing.class) { + + @Override + public long count(MTEQuantumForceTransformer gtMetaTileEntityQFT) { + return gtMetaTileEntityQFT.catalystHounsings.size(); + } + }; + + private final List> mteClasses; + private final IGTHatchAdder adder; + + @SafeVarargs + SpecialHatchElement(IGTHatchAdder adder, + Class... mteClasses) { + this.mteClasses = Collections.unmodifiableList(Arrays.asList(mteClasses)); + this.adder = adder; + } + + @Override + public List> mteClasses() { + return mteClasses; + } + + public IGTHatchAdder adder() { + return adder; + } + } + public Block getCasingBlock1() { return ModBlocks.blockCasings5Misc; } @@ -771,22 +836,20 @@ public ITexture[] getTexture(IGregTechTileEntity aBaseMetaTileEntity, ForgeDirec int aColorIndex, boolean aActive, boolean aRedstone) { if (side == facing) { if (aActive) { - return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(TAE.GTPP_INDEX(15)), - TextureFactory.builder() - .addIcon(TexturesGtBlock.oMCAQFTActive) - .extFacing() - .build(), + return new ITexture[] { getCasingTexture(), TextureFactory.builder() + .addIcon(TexturesGtBlock.oMCAQFTActive) + .extFacing() + .build(), TextureFactory.builder() .addIcon(TexturesGtBlock.oMCAQFTActiveGlow) .extFacing() .glow() .build() }; } - return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(TAE.GTPP_INDEX(15)), - TextureFactory.builder() - .addIcon(TexturesGtBlock.oMCAQFT) - .extFacing() - .build(), + return new ITexture[] { getCasingTexture(), TextureFactory.builder() + .addIcon(TexturesGtBlock.oMCAQFT) + .extFacing() + .build(), TextureFactory.builder() .addIcon(TexturesGtBlock.oMCAQFTGlow) .extFacing() diff --git a/src/main/resources/assets/gregtech/lang/en_US.lang b/src/main/resources/assets/gregtech/lang/en_US.lang index 2478fdc8188..a9bd88ba310 100644 --- a/src/main/resources/assets/gregtech/lang/en_US.lang +++ b/src/main/resources/assets/gregtech/lang/en_US.lang @@ -553,6 +553,7 @@ GT5U.gui.button.drone_name=Sort by §3name GT5U.gui.button.drone_distance=Sort by §3distance GT5U.gui.button.drone_error=Sort by §3shutdown status GT5U.gui.button.drone_showLocalName=Show localized name +GT5U.gui.button.toggle_output_slot_lock=Toggle output slot GT5U.gui.text.success=§aProcessing recipe GT5U.gui.text.generating=§aGenerating power GT5U.gui.text.no_recipe=§7No valid recipe found @@ -568,6 +569,7 @@ GT5U.gui.text.cycle_idle=§6Waiting for cycle to start GT5U.gui.text.fuel_quality_too_high=§7Fuel quality too high to run without boost GT5U.gui.text.no_data_sticks=§7No Data Sticks found GT5U.gui.text.bio_upgrade_missing=§7Recipe needs Bio Upgrade to start +GT5U.gui.text.nanites_missing=§7Missing nanites GT5U.gui.text.electromagnet_missing=§7Needs an Electromagnet to run GT5U.gui.text.electromagnet_insufficient=§7Electromagnet too weak to handle multi-amp energy hatches GT5U.gui.text.laser_insufficient=§7Laser source is too weak to run this recipe diff --git a/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_NANITE_HATCH.png b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_NANITE_HATCH.png new file mode 100644 index 0000000000000000000000000000000000000000..38a9b800f611209ed640f5036780da92f9eebf88 GIT binary patch literal 492 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G|&0G|+7Nl8g{T?YYS88InUp~?G&dbSF-tl}@5`I>>@G6TalpfU!A$WXgx zAjMM>=PdAuEM{Qf76xHPhFNnYfPxYwt`Q}{`DrEPiAAXl0g0J; zC3=3YAqu8?hI)ocTZ4FjYPO|Dc&2%JYB6vCIjjs)jI0cdK$aH}OGDWpUuiHhgTmdKI;Vst0CW#@7ytkO literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_NANITE_HATCH_GLOW.png b/src/main/resources/assets/gregtech/textures/blocks/iconsets/OVERLAY_NANITE_HATCH_GLOW.png new file mode 100644 index 0000000000000000000000000000000000000000..ed48ca6cecaeae4ddf410e19105e4debd48c93d0 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL5ULAh?3y^w370~qEv=}#LT=BJwMkF1yemk zJ;S7}K|DY;+fpMu(>y)37&w3&Rt70XRt82O%L|C5p=^+AG#Ht|;!HrcAtMvmbx}Ze zW;+X5JPXJMfdn81>4(v1mNGCiFic=)U;(NyFfuk^TmUf@q=R(<#H1-eHV7~Q&0zwo z46?KUvY@&Q4GciC(j}LtT;XWr1~MBwT^vI!{F5cp9Ad9Ow72T@<#7q-HE_x_V3=9= z`4gkt!jr!hxBdCUw(Q^kA6(1sUvDuybftl{fN=+-N5lRcwZ!F%f4?`q@aePz&(kKx zT~cZqy`p;<9vv4@%WM$Qf57LGz;K9(pXFa|)%gz_wdd||P?0{s#4+=j8r!0F-h>1O YhEF#=rybUqT?ulRr>mdKI;Vst0F