Backport lock crafting function for ME Interface (#423)

This commit is contained in:
Zengyj
2024-05-24 23:36:17 +11:00
committed by NotMyWing
parent a65b5015e6
commit a13f9955f2
25 changed files with 332 additions and 21 deletions
@@ -0,0 +1,26 @@
package appeng.api.config;
public enum LockCraftingMode {
/**
* Crafting is never locked.
*/
NONE,
/**
* After pushing a pattern to an adjacent machine, the pattern provider will not accept further crafts until a
* redstone pulse is received.
*/
LOCK_UNTIL_PULSE,
/**
* Crafting is locked while the pattern provider is receiving a redstone signal.
*/
LOCK_WHILE_HIGH,
/**
* Crafting is locked while the pattern provider is not receiving a redstone signal.
*/
LOCK_WHILE_LOW,
/**
* After pushing a pattern to an adjacent machine, the pattern provider will not accept further crafts until the
* primary pattern result is returned to the network through the pattern provider.
*/
LOCK_UNTIL_RESULT
}
@@ -57,6 +57,8 @@ public enum Settings
IO_DIRECTION( EnumSet.of( RelativeDirection.LEFT, RelativeDirection.RIGHT ) ),
UNLOCK(EnumSet.allOf(LockCraftingMode.class)),
BLOCK( EnumSet.of( YesNo.YES, YesNo.NO ) ),
OPERATION_MODE( EnumSet.allOf( OperationMode.class ) ),
@@ -77,6 +77,14 @@ public interface ICraftingPatternDetails
*/
IAEItemStack[] getCondensedOutputs();
/**
* The primary output of this pattern. The pattern will only be used to craft the primary output; the others are
* just byproducts.
*/
default IAEItemStack getPrimaryOutput() {
return getOutputs()[0];
}
/**
* @return a list of the outputs, will include nulls.
*/
@@ -25,12 +25,14 @@ import appeng.block.AEBaseTileBlock;
import appeng.core.sync.GuiBridge;
import appeng.tile.misc.TileInterface;
import appeng.util.Platform;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
@@ -93,4 +95,12 @@ public class BlockInterface extends AEBaseTileBlock {
((TileInterface) rotatable).setSide(axis);
}
}
@Override
public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) {
TileEntity tileEntity = this.getTileEntity(worldIn, pos);
if (tileEntity != null) {
((TileInterface) tileEntity).updateRedstoneState();
}
}
}
@@ -19,6 +19,7 @@
package appeng.client.gui.implementations;
import appeng.api.config.LockCraftingMode;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.client.gui.widgets.GuiImgButton;
@@ -41,6 +42,7 @@ import java.io.IOException;
public class GuiInterface extends GuiUpgradeable {
private GuiTabButton priority;
private GuiImgButton UnlockMode;
private GuiImgButton BlockMode;
private GuiToggleButton interfaceMode;
@@ -57,7 +59,10 @@ public class GuiInterface extends GuiUpgradeable {
this.BlockMode = new GuiImgButton(this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO);
this.buttonList.add(this.BlockMode);
this.interfaceMode = new GuiToggleButton(this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal());
this.UnlockMode = new GuiImgButton(this.guiLeft - 18,this.guiTop + 26 ,Settings.UNLOCK, LockCraftingMode.NONE);
this.buttonList.add(this.UnlockMode);
this.interfaceMode = new GuiToggleButton(this.guiLeft - 18, this.guiTop + 44, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal());
this.buttonList.add(this.interfaceMode);
}
@@ -67,6 +72,10 @@ public class GuiInterface extends GuiUpgradeable {
this.BlockMode.set(((ContainerInterface) this.cvb).getBlockingMode());
}
if (this.UnlockMode != null) {
this.UnlockMode.set(((ContainerInterface) this.cvb).getUnlockMode());
}
if (this.interfaceMode != null) {
this.interfaceMode.setState(((ContainerInterface) this.cvb).getInterfaceTerminalMode() == YesNo.YES);
}
@@ -106,6 +115,10 @@ public class GuiInterface extends GuiUpgradeable {
if (btn == this.BlockMode) {
NetworkHandler.instance().sendToServer(new PacketConfigButton(this.BlockMode.getSetting(), backwards));
}
if (btn == this.UnlockMode) {
NetworkHandler.instance.sendToServer(new PacketConfigButton(this.UnlockMode.getSetting(), backwards));
}
}
}
@@ -160,6 +160,12 @@ public class GuiImgButton extends GuiButton implements ITooltip {
this.registerApp(16 * 15, Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeDefault);
this.registerApp(16 * 15 + 1, Settings.SCHEDULING_MODE, SchedulingMode.ROUNDROBIN, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRoundRobin);
this.registerApp(16 * 15 + 2, Settings.SCHEDULING_MODE, SchedulingMode.RANDOM, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRandom);
this.registerApp(10, Settings.UNLOCK,LockCraftingMode.NONE,ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingModeNone);
this.registerApp(7, Settings.UNLOCK,LockCraftingMode.LOCK_UNTIL_RESULT,ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingUntilResultReturned);
this.registerApp(0, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_LOW, ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingWhileRedstoneLow);
this.registerApp(1, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_HIGH, ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingWhileRedstoneHigh);
this.registerApp(2, Settings.UNLOCK, LockCraftingMode.LOCK_UNTIL_PULSE, ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingUntilRedstonePulse);
}
}
@@ -19,10 +19,7 @@
package appeng.container.implementations;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.api.config.*;
import appeng.api.util.IConfigManager;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.*;
@@ -40,6 +37,9 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
public YesNo bMode = YesNo.NO;
@GuiSync(4)
public LockCraftingMode lMode = LockCraftingMode.NONE;
@GuiSync(5)
public YesNo iTermMode = YesNo.YES;
@GuiSync(7)
@@ -107,9 +107,14 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
@Override
protected void loadSettingsFromHost(final IConfigManager cm) {
this.setBlockingMode((YesNo) cm.getSetting(Settings.BLOCK));
this.setUnlockMode((LockCraftingMode) cm.getSetting(Settings.UNLOCK));
this.setInterfaceTerminalMode((YesNo) cm.getSetting(Settings.INTERFACE_TERMINAL));
}
public LockCraftingMode getUnlockMode() {return this.lMode;}
public void setUnlockMode(final LockCraftingMode mode) {this.lMode = mode;}
public YesNo getBlockingMode() {
return this.bMode;
}
@@ -98,6 +98,13 @@ public enum ButtonToolTips {
Blocking,
NonBlocking,
LockCraftingMode,
LockCraftingModeNone,
LockCraftingUntilRedstonePulse,
LockCraftingWhileRedstoneHigh,
LockCraftingWhileRedstoneLow,
LockCraftingUntilResultReturned,
LevelType,
LevelType_Energy,
LevelType_Item,
@@ -48,6 +48,7 @@ import appeng.api.util.IConfigManager;
import appeng.capabilities.Capabilities;
import appeng.core.settings.TickRates;
import appeng.fluids.util.AEFluidInventory;
import appeng.fluids.util.AEFluidStack;
import appeng.fluids.util.IAEFluidInventory;
import appeng.fluids.util.IAEFluidTank;
import appeng.helpers.ICustomNameObject;
@@ -473,7 +474,12 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
}
@Override
public void onFluidInventoryChanged(final IAEFluidTank inventory, final int slot) {
public void onFluidInventoryChanged(IAEFluidTank inv, int slot) {
onFluidInventoryChanged(inv, slot, null, null, null);
}
@Override
public void onFluidInventoryChanged(final IAEFluidTank inventory, final int slot, InvOperation operation, FluidStack added, FluidStack removed) {
if (this.isWorking == slot) {
return;
}
@@ -486,6 +492,9 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
this.notifyNeighbors();
}
} else if (inventory == this.tanks) {
if (added != null) {
iHost.onStackReturnNetwork(AEFluidStack.fromFluidStack(added));
}
this.saveChanges();
final boolean had = this.hasWorkToDo();
@@ -21,9 +21,11 @@ package appeng.fluids.helper;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.networking.security.IActionHost;
import appeng.api.storage.data.IAEFluidStack;
import appeng.me.helpers.IGridProxyable;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.fluids.FluidStack;
import java.util.EnumSet;
@@ -36,4 +38,7 @@ public interface IFluidInterfaceHost extends IActionHost, IGridProxyable, IUpgra
TileEntity getTileEntity();
void saveChanges();
default void onStackReturnNetwork(IAEFluidStack stack) {
}
}
@@ -29,6 +29,7 @@ import appeng.me.storage.MEInventoryHandler;
import appeng.parts.automation.PartAbstractFormationPlane;
import appeng.parts.automation.PlaneModels;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.prioritylist.PrecisePriorityList;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
@@ -36,6 +36,7 @@ import appeng.parts.PartModel;
import appeng.parts.automation.PartUpgradeable;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -46,6 +47,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import java.util.Random;
@@ -63,6 +63,7 @@ import appeng.parts.automation.PartUpgradeable;
import appeng.tile.networking.TileCableBus;
import appeng.util.ConfigManager;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.prioritylist.FuzzyPriorityList;
import appeng.util.prioritylist.PrecisePriorityList;
import net.minecraft.entity.player.EntityPlayer;
@@ -75,6 +76,7 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
@@ -543,6 +545,7 @@ public class PartFluidStorageBus extends PartUpgradeable implements IGridTickabl
}
// TODO: 1/28/2024 Unify both methods.
/**
* Filters the changes to only include items that pass the storage filter.
* Optimally, this should be handled by the underlying monitor.
@@ -4,6 +4,7 @@ package appeng.fluids.util;
import appeng.api.storage.data.IAEFluidStack;
import appeng.core.AELog;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
@@ -37,24 +38,27 @@ public class AEFluidInventory implements IAEFluidTank {
if (Objects.equals(this.fluids[slot], fluid)) {
if (fluid != null && fluid.getStackSize() != this.fluids[slot].getStackSize()) {
this.fluids[slot].setStackSize(fluid.getStackSize());
this.onContentChanged(slot);
this.onContentChanged(slot, InvOperation.SET, fluid.getFluidStack(), null);
}
} else {
if (fluid == null) {
IAEFluidStack removeStack = this.fluids[slot].copy();
this.fluids[slot] = null;
this.onContentChanged(slot, InvOperation.SET, null, removeStack.getFluidStack());
} else {
IAEFluidStack removeStack = this.fluids[slot];
this.fluids[slot] = fluid.copy();
this.fluids[slot].setStackSize(fluid.getStackSize());
this.onContentChanged(slot, InvOperation.SET, fluid.getFluidStack(), removeStack == null ? null : removeStack.getFluidStack());
}
this.onContentChanged(slot);
}
}
}
private void onContentChanged(final int slot) {
private void onContentChanged(final int slot, InvOperation operation, FluidStack added, FluidStack removed) {
if (this.handler != null && Platform.isServer()) {
this.handler.onFluidInventoryChanged(this, slot);
this.handler.onFluidInventoryChanged(this, slot, operation, added, removed);
}
}
@@ -107,7 +111,7 @@ public class AEFluidInventory implements IAEFluidTank {
this.setFluidInSlot(slot, AEFluidStack.fromFluidStack(resource).setStackSize(amountToStore));
} else {
fluid.setStackSize(fluid.getStackSize() + amountToStore);
this.onContentChanged(slot);
this.onContentChanged(slot, InvOperation.INSERT, resource, null);
}
}
@@ -139,7 +143,7 @@ public class AEFluidInventory implements IAEFluidTank {
if (fluid.getStackSize() <= 0) {
this.fluids[slot] = null;
}
this.onContentChanged(slot);
this.onContentChanged(slot, InvOperation.EXTRACT, null, new FluidStack(fluid.getFluid(), drained));
}
return stack;
}
@@ -21,6 +21,7 @@ package appeng.fluids.util;
import appeng.api.storage.data.IAEFluidStack;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.fluids.FluidTank;
@@ -19,7 +19,13 @@
package appeng.fluids.util;
import appeng.util.inv.InvOperation;
import net.minecraftforge.fluids.FluidStack;
@FunctionalInterface
public interface IAEFluidInventory {
void onFluidInventoryChanged(final IAEFluidTank inv, final int slot);
default void onFluidInventoryChanged(final IAEFluidTank inv, final int slot, InvOperation operation, FluidStack added, FluidStack removed) {
}
}
@@ -20,10 +20,7 @@ package appeng.helpers;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.api.config.*;
import appeng.api.implementations.ICraftingPatternItem;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.implementations.tiles.ICraftingMachine;
@@ -53,6 +50,7 @@ import appeng.api.util.AEPartLocation;
import appeng.api.util.DimensionalCoord;
import appeng.api.util.IConfigManager;
import appeng.capabilities.Capabilities;
import appeng.core.AELog;
import appeng.core.settings.TickRates;
import appeng.me.GridAccessException;
import appeng.me.helpers.AENetworkProxy;
@@ -67,10 +65,7 @@ import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.AppEngInternalOversizedInventory;
import appeng.tile.networking.TileCableBus;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.*;
import appeng.util.inv.*;
import appeng.util.item.AEItemStack;
import com.google.common.collect.ImmutableSet;
@@ -101,6 +96,8 @@ import net.minecraftforge.items.wrapper.RangedWrapper;
import javax.annotation.Nullable;
import java.util.*;
import static appeng.api.config.LockCraftingMode.LOCK_UNTIL_PULSE;
import static appeng.api.config.LockCraftingMode.LOCK_UNTIL_RESULT;
import static appeng.helpers.ItemStackHelper.*;
@@ -135,6 +132,13 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private boolean resetConfigCache = true;
private IMEMonitor<IAEItemStack> configCachedHandler;
private YesNo redstoneState = YesNo.UNDECIDED;
@Nullable
private UnlockCraftingEvent unlockEvent;
@Nullable
private IAEItemStack unlockStack;
public DualityInterface(final AENetworkProxy networkProxy, final IInterfaceHost ih) {
this.gridProxy = networkProxy;
this.gridProxy.setFlags(GridFlags.REQUIRE_CHANNEL);
@@ -142,6 +146,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.upgrades = new StackUpgradeInventory(this.gridProxy.getMachineRepresentation(), this, 4);
this.cm.registerSetting(Settings.BLOCK, YesNo.NO);
this.cm.registerSetting(Settings.INTERFACE_TERMINAL, YesNo.YES);
this.cm.registerSetting(Settings.UNLOCK, LockCraftingMode.NONE);
this.iHost = ih;
this.craftingTracker = new MultiCraftingTracker(this.iHost, 9);
@@ -168,6 +173,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if (this.isWorking == slot) {
return;
}
if (inv == this.config && (!removed.isEmpty() || !added.isEmpty())) {
boolean cfg = hasConfig();
this.readConfig();
@@ -178,6 +184,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
} else if (inv == this.patterns && (!removed.isEmpty() || !added.isEmpty())) {
this.updateCraftingList();
} else if (inv == this.storage && slot >= 0) {
if (added != ItemStack.EMPTY){
iHost.onStackReturnNetwork(AEItemStack.fromItemStack(added));
}
final boolean had = this.hasWorkToDo();
this.updatePlan(slot);
@@ -207,6 +216,18 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.craftingTracker.writeToNBT(data);
data.setInteger("priority", this.priority);
if (unlockEvent == UnlockCraftingEvent.PULSE) {
data.setByte("unlockEvent", (byte) 1);
} else if (unlockEvent == UnlockCraftingEvent.RESULT) {
if (unlockStack != null) {
data.setByte("unlockEvent", (byte) 2);
NBTTagCompound unlockStackTag = new NBTTagCompound();
unlockStack.writeToNBT(unlockStackTag);
data.setTag("unlockStack", unlockStackTag);
} else {
AELog.error("Saving MEInterface {}, locked waiting for stack, but stack is null!", iHost);
}
}
final NBTTagList waitingToSend = new NBTTagList();
if (this.waitingToSend != null) {
for (final ItemStack is : this.waitingToSend) {
@@ -286,6 +307,27 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
this.cm.readFromNBT(data);
this.readConfig();
this.updateCraftingList();
var unlockEventType = data.getByte("unlockEvent");
this.unlockEvent = switch (unlockEventType) {
case 0 -> null;
case 1 -> UnlockCraftingEvent.PULSE;
case 2 -> UnlockCraftingEvent.RESULT;
default -> {
AELog.error("Unknown unlock event type {} in NBT for MEInterface: {}", unlockEventType, data);
yield null;
}
};
if (this.unlockEvent == UnlockCraftingEvent.RESULT) {
this.unlockStack = AEItemStack.fromNBT(data.getCompoundTag("unlockStack"));
if (this.unlockStack == null) {
AELog.error("Could not load unlock stack for MEInterface from NBT: {}", data);
}
} else {
this.unlockStack = null;
}
}
private void addToSendList(final ItemStack is) {
@@ -912,6 +954,11 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if (this.getInstalledUpgrades(Upgrades.CRAFTING) == 0) {
this.cancelCrafting();
}
if (newValue == LockCraftingMode.NONE) {
resetCraftingLock();
}
this.iHost.saveChanges();
}
@@ -951,6 +998,10 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final TileEntity tile = this.iHost.getTileEntity();
final World w = tile.getWorld();
if (getCraftingLockedReason() != LockCraftingMode.NONE) {
return false;
}
if (this.visitedFaces.isEmpty()) {
this.visitedFaces = this.iHost.getTargets();
}
@@ -1003,6 +1054,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
addToSendListFacing(is, s);
}
}
onPushPatternSuccess(patternDetails);
pushItemsOut(s);
return true;
@@ -1021,6 +1073,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if (cm.acceptsPlans()) {
visitedFaces.remove(s);
if (cm.pushPattern(patternDetails, table, s.getOpposite())) {
onPushPatternSuccess(patternDetails);
return true;
}
continue;
@@ -1061,6 +1114,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
addToSendListFacing(is, s);
}
}
onPushPatternSuccess(patternDetails);
pushItemsOut(s);
return true;
}
@@ -1070,6 +1124,57 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return false;
}
public void resetCraftingLock() {
if (unlockEvent != null) {
unlockEvent = null;
unlockStack = null;
saveChanges();
}
}
private void onPushPatternSuccess(ICraftingPatternDetails pattern) {
resetCraftingLock();
LockCraftingMode lockMode = (LockCraftingMode) cm.getSetting(Settings.UNLOCK);
switch (lockMode) {
case LOCK_UNTIL_PULSE -> {
unlockEvent = UnlockCraftingEvent.PULSE;
saveChanges();
}
case LOCK_UNTIL_RESULT -> {
unlockEvent = UnlockCraftingEvent.RESULT;
unlockStack = pattern.getPrimaryOutput();
saveChanges();
}
}
}
/**
* Gets if the crafting lock is in effect and why.
*
* @return null if the lock isn't in effect
*/
public LockCraftingMode getCraftingLockedReason() {
var lockMode = cm.getSetting(Settings.UNLOCK);
if (lockMode == LockCraftingMode.LOCK_WHILE_LOW && !getRedstoneState()) {
// Crafting locked by redstone signal
return LockCraftingMode.LOCK_WHILE_LOW;
} else if (lockMode == LockCraftingMode.LOCK_WHILE_HIGH && getRedstoneState()) {
return LockCraftingMode.LOCK_WHILE_HIGH;
} else if (unlockEvent != null) {
// Crafting locked by waiting for unlock event
switch (unlockEvent) {
case PULSE -> {
return LOCK_UNTIL_PULSE;
}
case RESULT -> {
return LOCK_UNTIL_RESULT;
}
}
}
return LockCraftingMode.NONE;
}
@Override
public boolean isBusy() {
boolean busy = false;
@@ -1384,6 +1489,55 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return null;
}
public void updateRedstoneState() {
// If we're waitingh for a pulse, update immediately
if (unlockEvent == UnlockCraftingEvent.PULSE && getRedstoneState()) {
unlockEvent = null; // Unlocked!
} else {
// Otherwise, just reset back to undecided
redstoneState = YesNo.UNDECIDED;
}
saveChanges(); // In any case, this needs to be changed since the state is now outdated
}
/**
* @return Null if {@linkplain #getCraftingLockedReason()} is not {@link LockCraftingMode#LOCK_UNTIL_RESULT}.
*/
@org.jetbrains.annotations.Nullable
public IAEItemStack getUnlockStack() {
return unlockStack;
}
public void onStackReturnedToNetwork(IAEItemStack stack) {
if (unlockEvent != UnlockCraftingEvent.RESULT) {
return; // If we're not waiting for the result, we don't care
}
if (unlockStack == null) {
// Actually an error state...
AELog.error("MEInterface was waiting for RESULT, but no result was set");
unlockEvent = null;
} else if (unlockStack.getItem().equals(stack.getItem())) {
var remainingAmount = unlockStack.getStackSize() - stack.getStackSize();
if (remainingAmount <= 0) {
unlockEvent = null;
unlockStack = null;
} else {
unlockStack.setStackSize(remainingAmount);
}
}
}
private boolean getRedstoneState() {
if (redstoneState == YesNo.UNDECIDED) {
var entity = this.iHost.getTileEntity();
redstoneState = entity.getWorld().getRedstonePowerFromNeighbors(entity.getPos()) > 0
? YesNo.YES
: YesNo.NO;
}
return redstoneState == YesNo.YES;
}
private class InterfaceRequestSource extends MachineSource {
private final InterfaceRequestContext context;
@@ -22,6 +22,7 @@ package appeng.helpers;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.networking.crafting.ICraftingProvider;
import appeng.api.networking.crafting.ICraftingRequester;
import appeng.api.storage.data.IAEItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
@@ -37,4 +38,8 @@ public interface IInterfaceHost extends ICraftingProvider, IUpgradeableHost, ICr
TileEntity getTileEntity();
void saveChanges();
default void onStackReturnNetwork(IAEItemStack stack) {
getInterfaceDuality().onStackReturnedToNetwork(stack);
}
}
@@ -0,0 +1,6 @@
package appeng.helpers;
public enum UnlockCraftingEvent {
PULSE,
RESULT
}
@@ -54,6 +54,7 @@ import appeng.items.parts.PartModels;
import appeng.parts.PartBasicState;
import appeng.parts.PartModel;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.misc.TileInterface;
import appeng.util.Platform;
import appeng.util.SettingsFrom;
import appeng.util.inv.IAEAppEngInventory;
@@ -68,7 +69,9 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
@@ -196,6 +199,11 @@ public class PartInterface extends PartBasicState implements IGridTickable, ISto
this.duality.onChangeInventory(inv, slot, mc, removedStack, newStack);
}
@Override
public void onStackReturnNetwork(IAEItemStack stack) {
this.duality.onStackReturnedToNetwork(stack);
}
@Override
public DualityInterface getInterfaceDuality() {
return this.duality;
@@ -262,6 +270,14 @@ public class PartInterface extends PartBasicState implements IGridTickable, ISto
}
}
@Override
public void onNeighborChanged(IBlockAccess w, BlockPos pos, BlockPos neighbor) {
TileEntity tileEntity = getTileEntity();
if (tileEntity instanceof TileInterface) {
((TileInterface) tileEntity).updateRedstoneState();
}
}
@Override
public boolean hasCapability(Capability<?> capabilityClass) {
return this.duality.hasCapability(capabilityClass, this.getSide().getFacing());
@@ -221,6 +221,11 @@ public class TileInterface extends AENetworkInvTile implements IGridTickable, II
this.duality.onChangeInventory(inv, slot, mc, removed, added);
}
@Override
public void onStackReturnNetwork(IAEItemStack stack) {
this.duality.onStackReturnedToNetwork(stack);
}
@Override
public DualityInterface getInterfaceDuality() {
return this.duality;
@@ -274,6 +279,10 @@ public class TileInterface extends AENetworkInvTile implements IGridTickable, II
return this.duality.injectCraftedItems(link, items, mode);
}
public void updateRedstoneState(){
this.duality.updateRedstoneState();
}
@Override
public void jobStateChange(final ICraftingLink link) {
this.duality.jobStateChange(link);
@@ -25,6 +25,7 @@ import appeng.api.config.StorageFilter;
import appeng.api.util.IConfigManager;
import appeng.core.AELog;
import net.minecraft.nbt.NBTTagCompound;
import org.jetbrains.annotations.Nullable;
import java.util.EnumMap;
import java.util.Map;
@@ -327,6 +327,12 @@ gui.tooltips.appliedenergistics2.Disabled=Disabled
gui.tooltips.appliedenergistics2.Enable=Enabled
gui.tooltips.appliedenergistics2.Blocking=Do not push crafting items if inventory contains items.
gui.tooltips.appliedenergistics2.NonBlocking=Ignore the contents of the target inventory.
gui.tooltips.appliedenergistics2.LockCraftingMode=Lock Crafting
gui.tooltips.appliedenergistics2.LockCraftingModeNone=Never
gui.tooltips.appliedenergistics2.LockCraftingUntilRedstonePulse=Until redstone pulse is received
gui.tooltips.appliedenergistics2.LockCraftingWhileRedstoneHigh=With redstone signal
gui.tooltips.appliedenergistics2.LockCraftingWhileRedstoneLow=Without redstone signal
gui.tooltips.appliedenergistics2.LockCraftingUntilResultReturned=Until primary crafting result is returned
gui.tooltips.appliedenergistics2.Craft=Crafting Behavior
gui.tooltips.appliedenergistics2.CraftOnly=Do not use stocked items, only craft items while exporting.
gui.tooltips.appliedenergistics2.CraftEither=Use stocked items, or craft items while exporting.
@@ -324,6 +324,12 @@ gui.tooltips.appliedenergistics2.Disabled=禁用
gui.tooltips.appliedenergistics2.Enable=启用
gui.tooltips.appliedenergistics2.Blocking=当容器内有物品时不传送物品。
gui.tooltips.appliedenergistics2.NonBlocking=忽略目标容器的内容。
gui.tooltips.appliedenergistics2.LockCraftingMode=合成锁定
gui.tooltips.appliedenergistics2.LockCraftingModeNone=永不锁定
gui.tooltips.appliedenergistics2.LockCraftingUntilRedstonePulse=接收到脉冲信号时解锁
gui.tooltips.appliedenergistics2.LockCraftingWhileRedstoneHigh=有红石信号时锁定
gui.tooltips.appliedenergistics2.LockCraftingWhileRedstoneLow=无红石信号时锁定
gui.tooltips.appliedenergistics2.LockCraftingUntilResultReturned=接受到编码样板主产物时解锁
gui.tooltips.appliedenergistics2.Craft=输出时若有需要则合成物品。
gui.tooltips.appliedenergistics2.CraftOnly=不使用已存储物品,只使用合成物品。
gui.tooltips.appliedenergistics2.CraftEither=输出时使用已存储物品或合成物品。
Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB