Refactored crafting patterns (#4458)
* Deduplicate crafting patterns internals This should save a bit memory for duplicate patterns as well as speed up loading new patterns on reloading chunks. * Encode recipe id in pattern * Use the recipe id directly for looking it up * Slightly refactored how patterns encode whether they are crafting patterns or not. * Renamed PatternHelper. * Added APIs to encode patterns. (#4463) * Removed ICraftingPatternItem. * Renamed isCrafting to isCraftable Co-authored-by: shartte <shartte@users.noreply.github.com>
This commit is contained in:
@@ -38,6 +38,7 @@ import appeng.container.slot.AppEngSlot;
|
||||
import appeng.container.slot.MolecularAssemblerPatternSlot;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.items.misc.EncodedPatternItem;
|
||||
import appeng.tile.crafting.MolecularAssemblerTileEntity;
|
||||
import appeng.util.Platform;
|
||||
@@ -79,8 +80,7 @@ public class MolecularAssemblerContainer extends UpgradeableContainer implements
|
||||
|
||||
if (is.getItem() instanceof EncodedPatternItem) {
|
||||
final World w = this.getTileEntity().getWorld();
|
||||
final EncodedPatternItem iep = (EncodedPatternItem) is.getItem();
|
||||
final ICraftingPatternDetails ph = iep.getPatternForItem(is, w);
|
||||
final ICraftingPatternDetails ph = Api.instance().crafting().decodePattern(is, w);
|
||||
if (ph.isCraftable()) {
|
||||
return ph.isValidItemForSlot(slotIndex, i, w);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ package appeng.container.implementations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
@@ -32,11 +31,9 @@ import net.minecraft.inventory.container.CraftingResultSlot;
|
||||
import net.minecraft.inventory.container.IContainerListener;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.ICraftingRecipe;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeType;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.INBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
@@ -44,6 +41,7 @@ import net.minecraftforge.items.wrapper.PlayerInvWrapper;
|
||||
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.crafting.ICraftingHelper;
|
||||
import appeng.api.definitions.IDefinitions;
|
||||
import appeng.api.storage.IMEMonitor;
|
||||
import appeng.api.storage.ITerminalHost;
|
||||
@@ -98,8 +96,9 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
private final PatternTermSlot craftSlot;
|
||||
private final RestrictedInputSlot patternSlotIN;
|
||||
private final RestrictedInputSlot patternSlotOUT;
|
||||
private final ICraftingHelper craftingHelper = Api.INSTANCE.crafting();
|
||||
|
||||
private IRecipe<CraftingInventory> currentRecipe;
|
||||
private ICraftingRecipe currentRecipe;
|
||||
@GuiSync(97)
|
||||
public boolean craftingMode = true;
|
||||
@GuiSync(96)
|
||||
@@ -206,17 +205,17 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
final ItemStack[] out = this.getOutputs();
|
||||
|
||||
// if there is no input, this would be silly.
|
||||
if (in == null || out == null) {
|
||||
if (in == null || out == null || isCraftingMode() && currentRecipe == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// first check the output slots, should either be null, or a pattern
|
||||
if (!output.isEmpty() && !this.isPattern(output)) {
|
||||
if (!output.isEmpty() && !craftingHelper.isEncodedPattern(output)) {
|
||||
return;
|
||||
} // if nothing is there we should snag a new pattern.
|
||||
else if (output.isEmpty()) {
|
||||
output = this.patternSlotIN.getStack();
|
||||
if (output.isEmpty() || !this.isPattern(output)) {
|
||||
if (output.isEmpty() || !isPattern(output)) {
|
||||
return; // no blanks.
|
||||
}
|
||||
|
||||
@@ -226,34 +225,17 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
this.patternSlotIN.putStack(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
// add a new encoded pattern.
|
||||
Optional<ItemStack> maybePattern = Api.instance().definitions().items().encodedPattern().maybeStack(1);
|
||||
if (maybePattern.isPresent()) {
|
||||
output = maybePattern.get();
|
||||
this.patternSlotOUT.putStack(output);
|
||||
}
|
||||
// let the crafting helper create a new encoded pattern
|
||||
output = null;
|
||||
}
|
||||
|
||||
// encode the slot.
|
||||
final CompoundNBT encodedValue = new CompoundNBT();
|
||||
|
||||
final ListNBT tagIn = new ListNBT();
|
||||
final ListNBT tagOut = new ListNBT();
|
||||
|
||||
for (final ItemStack i : in) {
|
||||
tagIn.add(this.createItemTag(i));
|
||||
if (this.isCraftingMode()) {
|
||||
output = craftingHelper.encodeCraftingPattern(output, this.currentRecipe, in, out[0], isSubstitute());
|
||||
} else {
|
||||
output = craftingHelper.encodeProcessingPattern(output, in, out);
|
||||
}
|
||||
this.patternSlotOUT.putStack(output);
|
||||
|
||||
for (final ItemStack i : out) {
|
||||
tagOut.add(this.createItemTag(i));
|
||||
}
|
||||
|
||||
encodedValue.put("in", tagIn);
|
||||
encodedValue.put("out", tagOut);
|
||||
encodedValue.putBoolean("crafting", this.isCraftingMode());
|
||||
encodedValue.putBoolean("substitute", this.isSubstitute());
|
||||
|
||||
output.setTag(encodedValue);
|
||||
}
|
||||
|
||||
private ItemStack[] getInputs() {
|
||||
@@ -308,21 +290,7 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
}
|
||||
|
||||
final IDefinitions definitions = Api.instance().definitions();
|
||||
|
||||
boolean isPattern = definitions.items().encodedPattern().isSameAs(output);
|
||||
isPattern |= definitions.materials().blankPattern().isSameAs(output);
|
||||
|
||||
return isPattern;
|
||||
}
|
||||
|
||||
private INBT createItemTag(final ItemStack i) {
|
||||
final CompoundNBT c = new CompoundNBT();
|
||||
|
||||
if (!i.isEmpty()) {
|
||||
i.write(c);
|
||||
}
|
||||
|
||||
return c;
|
||||
return definitions.materials().blankPattern().isSameAs(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,11 +33,11 @@ import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import appeng.api.crafting.ICraftingHelper;
|
||||
import appeng.api.definitions.IDefinitions;
|
||||
import appeng.api.definitions.IItems;
|
||||
import appeng.api.definitions.IMaterials;
|
||||
import appeng.api.features.INetworkEncodable;
|
||||
import appeng.api.implementations.ICraftingPatternItem;
|
||||
import appeng.api.implementations.items.IBiometricCard;
|
||||
import appeng.api.implementations.items.ISpatialStorageCell;
|
||||
import appeng.api.implementations.items.IStorageComponent;
|
||||
@@ -88,10 +88,7 @@ public class RestrictedInputSlot extends AppEngSlot {
|
||||
|
||||
public boolean isValid(final ItemStack is, final World theWorld) {
|
||||
if (this.which == PlacableItemType.VALID_ENCODED_PATTERN_W_OUTPUT) {
|
||||
final ICraftingPatternDetails ap = is.getItem() instanceof ICraftingPatternItem
|
||||
? ((ICraftingPatternItem) is.getItem()).getPatternForItem(is, theWorld)
|
||||
: null;
|
||||
return ap != null;
|
||||
return Api.instance().crafting().decodePattern(is, theWorld) != null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -126,39 +123,24 @@ public class RestrictedInputSlot extends AppEngSlot {
|
||||
final IDefinitions definitions = Api.instance().definitions();
|
||||
final IMaterials materials = definitions.materials();
|
||||
final IItems items = definitions.items();
|
||||
final ICraftingHelper crafting = Api.instance().crafting();
|
||||
|
||||
switch (this.which) {
|
||||
case ENCODED_CRAFTING_PATTERN:
|
||||
if (i.getItem() instanceof ICraftingPatternItem) {
|
||||
final ICraftingPatternItem b = (ICraftingPatternItem) i.getItem();
|
||||
final ICraftingPatternDetails de = b.getPatternForItem(i, this.p.player.world);
|
||||
if (de != null) {
|
||||
return de.isCraftable();
|
||||
}
|
||||
final ICraftingPatternDetails de = crafting.decodePattern(i, this.p.player.world);
|
||||
if (de != null) {
|
||||
return de.isCraftable();
|
||||
}
|
||||
return false;
|
||||
case VALID_ENCODED_PATTERN_W_OUTPUT:
|
||||
case ENCODED_PATTERN_W_OUTPUT:
|
||||
case ENCODED_PATTERN: {
|
||||
if (i.getItem() instanceof ICraftingPatternItem) {
|
||||
return true;
|
||||
}
|
||||
// ICraftingPatternDetails pattern = i.getItem() instanceof ICraftingPatternItem
|
||||
// ?
|
||||
// ((ICraftingPatternItem)
|
||||
// i.getItem()).getPatternForItem( i ) : null;
|
||||
return false;// pattern != null;
|
||||
}
|
||||
case ENCODED_PATTERN:
|
||||
return crafting.isEncodedPattern(i);
|
||||
case BLANK_PATTERN:
|
||||
return materials.blankPattern().isSameAs(i);
|
||||
|
||||
case PATTERN:
|
||||
|
||||
if (i.getItem() instanceof ICraftingPatternItem) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return materials.blankPattern().isSameAs(i);
|
||||
return materials.blankPattern().isSameAs(i) || crafting.isEncodedPattern(i);
|
||||
|
||||
case INSCRIBER_PLATE:
|
||||
if (materials.namePress().isSameAs(i)) {
|
||||
|
||||
Reference in New Issue
Block a user