Feature: Pattern Repeater (#1000)

Co-authored-by: Martin Robertz <dream-master@gmx.net>
This commit is contained in:
lc-1337andMartin Robertz authored and GitHub committed 2026-01-08 20:05:06 +00:00
1 parent a0604b8ad1
commit 464b9e6f47
16 files changed
+591 -8

No files matched your search

@@ -111,4 +111,6 @@ public interface IParts {
IItemDefinition p2PTunnelGregtech();
IItemDefinition p2PTunnelMEInterface();
IItemDefinition patternRepeater();
}
@@ -101,4 +101,6 @@ public class Parts {
public AEItemDefinition partThroughputMonitor;
public AEItemDefinition partConversionMonitor;
public AEItemDefinition partPatternRepeater;
}
@@ -0,0 +1,6 @@
package appeng.api.networking.crafting;
public interface ICraftingPostPatternChangeListener {
void onPostPatternChange();
}
@@ -367,6 +367,7 @@ public final class Registration {
target.partStorageMonitor = this.converter.of(source.storageMonitor());
target.partThroughputMonitor = this.converter.of(source.throughputMonitor());
target.partConversionMonitor = this.converter.of(source.conversionMonitor());
target.partPatternRepeater = this.converter.of(source.patternRepeater());
}
/**
@@ -69,6 +69,7 @@ public final class ApiParts implements IParts {
private final IItemDefinition storageMonitor;
private final IItemDefinition conversionMonitor;
private final IItemDefinition throughputMonitor;
private final IItemDefinition patternRepeater;
public ApiParts(final DefinitionConstructor constructor, final IPartHelper partHelper) {
final ItemMultiPart itemMultiPart = new ItemMultiPart(partHelper);
@@ -121,6 +122,7 @@ public final class ApiParts implements IParts {
this.storageMonitor = new DamagedItemDefinition(itemMultiPart.createPart(PartType.StorageMonitor));
this.conversionMonitor = new DamagedItemDefinition(itemMultiPart.createPart(PartType.ConversionMonitor));
this.throughputMonitor = new DamagedItemDefinition(itemMultiPart.createPart(PartType.ThroughputMonitor));
this.patternRepeater = new DamagedItemDefinition(itemMultiPart.createPart(PartType.PatternRepeater));
}
@Override
@@ -351,4 +353,9 @@ public final class ApiParts implements IParts {
public IItemDefinition throughputMonitor() {
return this.throughputMonitor;
}
@Override
public IItemDefinition patternRepeater() {
return this.patternRepeater;
}
}
@@ -52,7 +52,9 @@ public enum PlayerMessages implements Localization {
MachineHighlighted,
MachineHighlightedNamed,
StorageInOtherDim,
StorageHighlighted;
StorageHighlighted,
PatternRepeaterProvider,
PatternRepeaterAccessor;
@Deprecated // kept for backward compat
public IChatComponent get() {
@@ -54,7 +54,11 @@ public enum WailaText implements Localization {
Id,
ConnectedTo,
Disconnected,
Singularity;
Singularity,
Waiting,
Provider,
Accessor;
private final String formatedName;
@@ -323,7 +323,6 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
this.unlockStacks.add(unlockStack);
}
addInterception();
} else {
this.unlockStacks = null;
}
@@ -596,6 +595,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.fluids.setInternal(new NullInventory<>());
}
this.addInterception();
this.notifyNeighbors();
}
@@ -1125,6 +1126,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
private void addInterception() {
if (unlockStacks == null || unlockStacks.isEmpty()) return;
boolean hasItems = false;
boolean hasFluids = false;
@@ -1134,6 +1137,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} else if (aes.isFluid()) {
hasFluids = true;
}
if (hasItems && hasFluids) break;
}
if (hasItems) {
@@ -1399,6 +1404,15 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
public void addDrops(final List<ItemStack> drops) {
try {
if (this.gridProxy.getStorage().getItemInventory() instanceof NetworkMonitor<?>nm) {
nm.removeStorageInterceptor(this);
}
if (this.gridProxy.getStorage().getFluidInventory() instanceof NetworkMonitor<?>nm) {
nm.removeStorageInterceptor(this);
}
} catch (GridAccessException ignored) {}
if (this.waitingToSend != null) {
for (final IAEStack<?> is : this.waitingToSend) {
if (is != null) {
@@ -31,6 +31,7 @@ import appeng.integration.modules.waila.part.IPartWailaDataProvider;
import appeng.integration.modules.waila.part.P2PStateWailaDataProvider;
import appeng.integration.modules.waila.part.PartAccessor;
import appeng.integration.modules.waila.part.PartInterfaceDataProvider;
import appeng.integration.modules.waila.part.PartPatternRepeaterDataProvider;
import appeng.integration.modules.waila.part.PowerStateWailaDataProvider;
import appeng.integration.modules.waila.part.StorageMonitorWailaDataProvider;
import appeng.integration.modules.waila.part.Tracer;
@@ -74,8 +75,16 @@ public final class PartWailaDataProvider implements IWailaDataProvider {
final IPartWailaDataProvider p2pState = new P2PStateWailaDataProvider();
final IPartWailaDataProvider partStack = new BasePartWailaDataProvider();
final IPartWailaDataProvider partInterface = new PartInterfaceDataProvider();
final IPartWailaDataProvider partPatternRepeater = new PartPatternRepeaterDataProvider();
this.providers = Lists.newArrayList(channel, storageMonitor, powerState, p2pState, partStack, partInterface);
this.providers = Lists.newArrayList(
channel,
storageMonitor,
powerState,
p2pState,
partStack,
partInterface,
partPatternRepeater);
}
@Override
@@ -0,0 +1,66 @@
package appeng.integration.modules.waila.part;
import java.util.List;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import appeng.api.parts.IPart;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.core.localization.WailaText;
import appeng.parts.misc.PartPatternRepeater;
import mcp.mobius.waila.api.IWailaConfigHandler;
import mcp.mobius.waila.api.IWailaDataAccessor;
public class PartPatternRepeaterDataProvider extends BasePartWailaDataProvider {
private static final String NBT_MODE = "provider";
private static final String NBT_WAITING_STACKS = "waitingStacks";
@Override
public List<String> getWailaBody(IPart part, List<String> currentToolTip, IWailaDataAccessor accessor,
IWailaConfigHandler config) {
if (part instanceof PartPatternRepeater) {
if (accessor.getNBTData().hasKey(NBT_MODE)) {
currentToolTip.add(accessor.getNBTData().getString(NBT_MODE));
if (accessor.getNBTData().hasKey(NBT_WAITING_STACKS)) {
currentToolTip.add(WailaText.Waiting.getLocal());
NBTTagList stackList = accessor.getNBTData().getTagList(NBT_WAITING_STACKS, 10);
for (int index = 0; index < stackList.tagCount(); index++) {
NBTTagCompound stackTag = stackList.getCompoundTagAt(index);
currentToolTip.add(stackTag.getString("q"));
}
}
}
}
return currentToolTip;
}
@Override
public NBTTagCompound getNBTData(EntityPlayerMP player, IPart part, TileEntity te, NBTTagCompound tag, World world,
int x, int y, int z) {
if (part instanceof PartPatternRepeater ppr) {
tag.setString(NBT_MODE, ppr.isProvider() ? WailaText.Provider.getLocal() : WailaText.Accessor.getLocal());
IItemList<IAEStack<?>> waitingStacks = ppr.getWaitingStacks();
if (!waitingStacks.isEmpty()) {
NBTTagList stackList = new NBTTagList();
for (IAEStack<?> stack : waitingStacks) {
NBTTagCompound stackTag = new NBTTagCompound();
stackTag.setString("q", "> " + stack.getStackSize() + "x " + stack.getDisplayName());
stackList.appendTag(stackTag);
}
tag.setTag(NBT_WAITING_STACKS, stackList);
}
}
return tag;
}
}
@@ -28,6 +28,7 @@ import appeng.parts.automation.PartLevelEmitter;
import appeng.parts.misc.PartCableAnchor;
import appeng.parts.misc.PartInterface;
import appeng.parts.misc.PartInvertedToggleBus;
import appeng.parts.misc.PartPatternRepeater;
import appeng.parts.misc.PartStorageBus;
import appeng.parts.misc.PartToggleBus;
import appeng.parts.networking.PartCableCovered;
@@ -201,7 +202,8 @@ public enum PartType {
PartPatternTerminalEx.class),
PartCreativeEnergy(690, EnumSet.of(AEFeature.Core), EnumSet.noneOf(IntegrationType.class),
PartCreativeEnergy.class);
PartCreativeEnergy.class),
PatternRepeater(473, EnumSet.of(AEFeature.Core), EnumSet.noneOf(IntegrationType.class), PartPatternRepeater.class),;
public final int baseDamage;
private final Set<AEFeature> features;
+18
View File
@@ -19,6 +19,7 @@ import static appeng.util.Platform.stackConvert;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
@@ -28,6 +29,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@@ -61,6 +63,7 @@ import appeng.api.networking.crafting.ICraftingJob;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.crafting.ICraftingMedium;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.crafting.ICraftingPostPatternChangeListener;
import appeng.api.networking.crafting.ICraftingProvider;
import appeng.api.networking.crafting.ICraftingProviderHelper;
import appeng.api.networking.crafting.ICraftingRequester;
@@ -125,6 +128,9 @@ public class CraftingGridCache
private static int pauseRebuilds = 0;
private static Set<CraftingGridCache> rebuildNeeded = new HashSet<>();
private final Set<ICraftingPostPatternChangeListener> postPatternChangeListeners = Collections
.newSetFromMap(new WeakHashMap<>());
public CraftingGridCache(final IGrid grid) {
this.grid = grid;
}
@@ -268,6 +274,10 @@ public class CraftingGridCache
StorageChannel.FLUIDS,
this.craftableItems.keySet().stream().filter(IAEStack::isFluid).collect(Collectors.toList()),
new BaseActionSource());
for (final ICraftingPostPatternChangeListener listener : this.postPatternChangeListeners) {
listener.onPostPatternChange();
}
}
/** Only for unit test usage */
@@ -684,6 +694,14 @@ public class CraftingGridCache
return this.interestManager;
}
public void addPostPatternChangeListeners(final ICraftingPostPatternChangeListener listener) {
this.postPatternChangeListeners.add(listener);
}
public void removePostPatternChangeListeners(final ICraftingPostPatternChangeListener listener) {
this.postPatternChangeListeners.remove(listener);
}
private static class ActiveCpuIterator implements Iterator<ICraftingCPU> {
private final Iterator<CraftingCPUCluster> iterator;
+4 -3
View File
@@ -11,13 +11,14 @@
package appeng.me.cache;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.WeakHashMap;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
@@ -68,7 +69,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T> {
@Nonnegative
private int localDepthSemaphore = 0;
private final Set<IStorageInterceptor> storageInterceptors = new HashSet<>();
private final Set<IStorageInterceptor> storageInterceptors = Collections.newSetFromMap(new WeakHashMap<>());
public NetworkMonitor(final GridStorageCache cache, final StorageChannel chan) {
this.myGridCache = cache;
@@ -160,7 +161,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T> {
if (isi.canAccept(input)) {
input = (T) isi.injectItems(input, mode, src);
if (isi.shouldRemoveInterceptor(input)) iterator.remove();
if (mode == Actionable.MODULATE && isi.shouldRemoveInterceptor(input)) iterator.remove();
if (input == null) return null;
}
@@ -0,0 +1,443 @@
/*
* This file is part of Applied Energistics 2. Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved. Applied
* Energistics 2 is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version. Applied Energistics 2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details. You should have received a copy of the GNU Lesser General Public License along with
* Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.parts.misc;
import static appeng.util.Platform.readAEStackListNBT;
import static appeng.util.Platform.writeAEStackListNBT;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.util.Vec3;
import net.minecraftforge.common.util.ForgeDirection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingMedium;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.crafting.ICraftingPostPatternChangeListener;
import appeng.api.networking.crafting.ICraftingProvider;
import appeng.api.networking.crafting.ICraftingProviderHelper;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkCraftingPatternChange;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.storage.IStorageInterceptor;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartRenderHelper;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.DimensionalCoord;
import appeng.client.texture.CableBusTextures;
import appeng.core.localization.PlayerMessages;
import appeng.helpers.Reflected;
import appeng.me.GridAccessException;
import appeng.me.cache.CraftingGridCache;
import appeng.me.cache.NetworkMonitor;
import appeng.me.helpers.AENetworkProxy;
import appeng.me.storage.MEMonitorPassThrough;
import appeng.me.storage.NullInventory;
import appeng.parts.PartBasicState;
import appeng.tile.networking.TileCableBus;
import appeng.util.Platform;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class PartPatternRepeater extends PartBasicState
implements ICraftingProvider, IStorageInterceptor, ICraftingPostPatternChangeListener {
private final List<ICraftingPatternDetails> craftingList = new ArrayList<>();
private IItemList<IAEStack<?>> waitingStacks = AEApi.instance().storage().createAEStackList();
private CraftingGridCache targetCraftingGrid = null;
private CraftingGridCache currentCraftingGrid = null;
private AENetworkProxy targetNetworkProxy = null;
private boolean provider = false;
private PartPatternRepeater pairPatternRepeater = null;
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>(
new NullInventory<IAEItemStack>(),
StorageChannel.ITEMS);
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>(
new NullInventory<IAEFluidStack>(),
StorageChannel.FLUIDS);
private final MachineSource actionSource;
@Reflected
public PartPatternRepeater(final ItemStack is) {
super(is);
this.actionSource = new MachineSource(this);
this.items.setChangeSource(actionSource);
this.fluids.setChangeSource(actionSource);
}
@Override
public void getBoxes(final IPartCollisionHelper bch) {
bch.addBox(2, 2, 14, 14, 14, 16);
bch.addBox(5, 5, 12, 11, 11, 14);
}
@MENetworkEventSubscribe
public void stateChange(final MENetworkChannelsChanged c) {
gridChanged();
}
@MENetworkEventSubscribe
public void stateChange(final MENetworkPowerStatusChange c) {
gridChanged();
}
@Override
@SideOnly(Side.CLIENT)
public void renderInventory(final IPartRenderHelper rh, final RenderBlocks renderer) {
rh.setTexture(
CableBusTextures.PartMonitorSides.getIcon(),
CableBusTextures.PartMonitorSides.getIcon(),
CableBusTextures.PartMonitorBack.getIcon(),
this.getItemStack().getIconIndex(),
CableBusTextures.PartMonitorSides.getIcon(),
CableBusTextures.PartMonitorSides.getIcon());
rh.setBounds(2, 2, 14, 14, 14, 16);
rh.renderInventoryBox(renderer);
rh.setBounds(5, 5, 12, 11, 11, 13);
rh.renderInventoryBox(renderer);
rh.setBounds(5, 5, 13, 11, 11, 14);
rh.renderInventoryBox(renderer);
}
@Override
public void gridChanged() {
this.init();
if (this.provider) {
try {
this.items.setInternal(this.getProxy().getStorage().getItemInventory());
this.fluids.setInternal(this.getProxy().getStorage().getFluidInventory());
} catch (final GridAccessException gae) {
this.items.setInternal(new NullInventory<>());
this.fluids.setInternal(new NullInventory<>());
}
} else if (this.pairPatternRepeater != null) {
this.pairPatternRepeater.addInterception();
}
}
@Override
@SideOnly(Side.CLIENT)
public void renderStatic(final int x, final int y, final int z, final IPartRenderHelper rh,
final RenderBlocks renderer) {
this.setRenderCache(rh.useSimplifiedRendering(x, y, z, this, this.getRenderCache()));
rh.setTexture(
CableBusTextures.PartMonitorSides.getIcon(),
CableBusTextures.PartMonitorSides.getIcon(),
CableBusTextures.PartMonitorBack.getIcon(),
this.getItemStack().getIconIndex(),
CableBusTextures.PartMonitorSides.getIcon(),
CableBusTextures.PartMonitorSides.getIcon());
rh.setBounds(2, 2, 14, 14, 14, 16);
rh.renderBlock(x, y, z, renderer);
rh.setTexture(
CableBusTextures.PartMonitorSides.getIcon(),
CableBusTextures.PartMonitorSides.getIcon(),
CableBusTextures.PartMonitorBack.getIcon(),
this.getItemStack().getIconIndex(),
CableBusTextures.PartMonitorSides.getIcon(),
CableBusTextures.PartMonitorSides.getIcon());
rh.setBounds(5, 5, 12, 11, 11, 13);
rh.renderBlock(x, y, z, renderer);
rh.setTexture(
CableBusTextures.PartMonitorSidesStatus.getIcon(),
CableBusTextures.PartMonitorSidesStatus.getIcon(),
CableBusTextures.PartMonitorBack.getIcon(),
this.getItemStack().getIconIndex(),
CableBusTextures.PartMonitorSidesStatus.getIcon(),
CableBusTextures.PartMonitorSidesStatus.getIcon());
rh.setBounds(5, 5, 13, 11, 11, 14);
rh.renderBlock(x, y, z, renderer);
this.renderLights(x, y, z, rh, renderer);
}
@Override
public int cableConnectionRenderTo() {
return 4;
}
@Override
public void onNeighborChanged() {
this.init();
}
@Override
public IIcon getBreakingTexture() {
return this.getItemStack().getIconIndex();
}
@Override
public void writeToNBT(NBTTagCompound data) {
data.setTag("waitingStacks", writeAEStackListNBT(this.waitingStacks));
data.setBoolean("provider", this.provider);
}
@Override
public void readFromNBT(NBTTagCompound data) {
this.waitingStacks = readAEStackListNBT((NBTTagList) data.getTag("waitingStacks"));
this.provider = data.getBoolean("provider");
}
@Override
public boolean pushPattern(final ICraftingPatternDetails patternDetails, final InventoryCrafting table) {
if (this.targetCraftingGrid != null) {
for (ICraftingMedium medium : this.targetCraftingGrid.getMediums(patternDetails)) {
if (medium.pushPattern(patternDetails, table)) {
for (IAEStack<?> outputStack : patternDetails.getCondensedAEOutputs()) {
this.waitingStacks.add(outputStack.copy());
}
this.addInterception();
return true;
}
}
}
return false;
}
@Override
public boolean isBusy() {
return false;
}
@Override
public void provideCrafting(final ICraftingProviderHelper craftingTracker) {
if (this.provider && this.getProxy().isActive() && this.craftingList != null) {
for (final ICraftingPatternDetails details : this.craftingList) {
craftingTracker.addCraftingOption(this, details);
}
}
}
public void init() {
this.craftingList.clear();
this.targetCraftingGrid = null;
this.targetNetworkProxy = null;
this.pairPatternRepeater = null;
this.currentCraftingGrid = null;
final TileEntity self = this.getHost().getTile();
final TileEntity target = self.getWorldObj().getTileEntity(
self.xCoord + this.getSide().offsetX,
self.yCoord + this.getSide().offsetY,
self.zCoord + this.getSide().offsetZ);
if (target instanceof TileCableBus tcb
&& tcb.getPart(this.getSide().getOpposite()) instanceof PartPatternRepeater ppr) {
this.pairPatternRepeater = ppr;
this.targetNetworkProxy = ppr.getProxy();
if (this.provider && !ppr.provider) {
final IGridNode gn = tcb.getGridNode(ForgeDirection.UNKNOWN);
if (gn == null) return;
this.targetCraftingGrid = gn.getGrid().getCache(ICraftingGrid.class);
final ImmutableSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> tempPatterns = this.targetCraftingGrid
.getCraftingPatterns().entrySet();
for (Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> entry : tempPatterns) {
this.craftingList.addAll(entry.getValue());
}
if (!this.craftingList.isEmpty()) {
try {
this.getProxy().getGrid()
.postEvent(new MENetworkCraftingPatternChange(this, this.getProxy().getNode()));
} catch (final GridAccessException e) {
// :P
}
}
} else {
final IGridNode gn = this.getGridNode(ForgeDirection.UNKNOWN);
if (gn == null) return;
this.currentCraftingGrid = gn.getGrid().getCache(ICraftingGrid.class);
this.currentCraftingGrid.addPostPatternChangeListeners(this);
}
}
}
@Override
public boolean onPartActivate(EntityPlayer player, Vec3 pos) {
if (Platform.isClient()) return true;
if (player.isSneaking()) {
this.waitingStacks.resetStatus();
return true;
}
final DimensionalCoord dc = this.getLocation();
if (Platform.isWrench(player, player.getHeldItem(), dc.x, dc.y, dc.z)) {
this.provider = !this.provider;
if (this.provider) player.addChatMessage(PlayerMessages.PatternRepeaterProvider.toChat());
else {
try {
this.getProxy().getGrid()
.postEvent(new MENetworkCraftingPatternChange(this, this.getProxy().getNode()));
} catch (final GridAccessException ignored) {}
player.addChatMessage(PlayerMessages.PatternRepeaterAccessor.toChat());
}
this.gridChanged();
return true;
}
return false;
}
@Override
public boolean canAccept(IAEStack<?> stack) {
return this.waitingStacks.findPrecise(stack) != null;
}
@Override
public IAEStack<?> injectItems(final IAEStack<?> input, final Actionable type, final BaseActionSource src) {
if (input == null) return null;
final IAEStack<?> waitingStack = this.waitingStacks.findPrecise(input);
final long inputSize = input.getStackSize();
final long waitingSize = waitingStack.getStackSize();
final IAEStack<?> tempStack = input.copy();
long leftOver = 0;
if (inputSize > waitingSize) {
leftOver = inputSize - waitingSize;
tempStack.setStackSize(waitingSize);
}
final long tempStackSize = tempStack.getStackSize();
final IAEStack<?> result;
if (tempStack instanceof IAEItemStack ais) result = this.items.injectItems(ais, type, this.actionSource);
else if (tempStack instanceof IAEFluidStack ifs) result = this.fluids.injectItems(ifs, type, this.actionSource);
else return input;
final long reducedSize;
if (result == null) reducedSize = 0;
else reducedSize = result.getStackSize();
final long returnSize = reducedSize + leftOver;
if (type == Actionable.MODULATE) waitingStack.setStackSize(waitingSize - tempStackSize + reducedSize);
return returnSize > 0 ? input.copy().setStackSize(returnSize) : null;
}
@Override
public boolean shouldRemoveInterceptor(IAEStack<?> stack) {
return this.waitingStacks.isEmpty();
}
private void addInterception() {
if (waitingStacks.isEmpty() || this.targetNetworkProxy == null) return;
boolean hasItems = false;
boolean hasFluids = false;
for (IAEStack<?> aes : this.waitingStacks) {
if (aes.isItem()) {
hasItems = true;
} else if (aes.isFluid()) {
hasFluids = true;
}
if (hasItems && hasFluids) break;
}
if (hasItems) {
try {
if (this.targetNetworkProxy.getStorage().getItemInventory() instanceof NetworkMonitor<?>nm) {
nm.addStorageInterceptor(this);
}
} catch (GridAccessException ignored) {}
}
if (hasFluids) {
try {
if (this.targetNetworkProxy.getStorage().getFluidInventory() instanceof NetworkMonitor<?>nm) {
nm.addStorageInterceptor(this);
}
} catch (GridAccessException ignored) {}
}
}
@Override
public void onPostPatternChange() {
if (!this.provider && pairPatternRepeater != null) pairPatternRepeater.init();
}
@Override
public void getDrops(List<ItemStack> drops, boolean wrenched) {
if (this.currentCraftingGrid != null) this.currentCraftingGrid.removePostPatternChangeListeners(this);
if (this.targetNetworkProxy != null) try {
if (this.targetNetworkProxy.getStorage().getItemInventory() instanceof NetworkMonitor<?>nm) {
nm.removeStorageInterceptor(this);
}
if (this.targetNetworkProxy.getStorage().getFluidInventory() instanceof NetworkMonitor<?>nm) {
nm.removeStorageInterceptor(this);
}
} catch (GridAccessException ignored) {}
super.getDrops(drops, wrenched);
}
public boolean isProvider() {
return this.provider;
}
public IItemList<IAEStack<?>> getWaitingStacks() {
return this.waitingStacks;
}
}
@@ -137,6 +137,8 @@ chat.appliedenergistics2.MachineHighlighted=The %d is now highlighted at %d, %d,
chat.appliedenergistics2.MachineHighlightedNamed=The %d "%d" is now highlighted at %d, %d, %d
chat.appliedenergistics2.StorageHighlighted=The %d containing %d %d is now highlighted at %d, %d, %d
chat.appliedenergistics2.StorageInOtherDim=%d containing %d %d is located in dimension: %d and cant be highlighted
chat.appliedenergistics2.PatternRepeaterProvider=§5Provider§r - will provide pattern to current system from in front §5Accessor§r.
chat.appliedenergistics2.PatternRepeaterAccessor=§5Accessor§r - will provide pattern to in front §5Provider§r.
# Creative Tabs
itemGroup.appliedenergistics2=Applied Energistics 2
@@ -684,6 +686,9 @@ waila.appliedenergistics2.Id=id
waila.appliedenergistics2.ConnectedTo=Connected to
waila.appliedenergistics2.Disconnected=Disconnected
waila.appliedenergistics2.Singularity=Singularity
waila.appliedenergistics2.Provider=§5Provider§r
waila.appliedenergistics2.Accessor=§5Accessor§r
waila.appliedenergistics2.Waiting=Waiting:
# Baubles Extended
slot.Terminal=§aTerminal§7
@@ -836,6 +841,7 @@ item.appliedenergistics2.ItemPart.InterfaceTerminal.name=ME Interface Terminal
item.appliedenergistics2.ItemPart.InvertedToggleBus.name=ME Inverted Toggle Bus
item.appliedenergistics2.ItemPart.ToggleBus.name=ME Toggle Bus
item.appliedenergistics2.ItemPart.CraftingMonitor.name=ME Crafting Monitor
item.appliedenergistics2.ItemPart.PatternRepeater.name=ME Pattern Repeater
item.appliedenergistics2.ItemSpatialStorageCell.128Cubed.name=128³ Spatial Storage Cell
item.appliedenergistics2.ItemSpatialStorageCell.16Cubed.name=16³ Spatial Storage Cell
Binary file not shown.

After

Width:  |  Height:  |  Size: 500 B