Skip to content

Commit

Permalink
Cribs super recipe check (#3608)
Browse files Browse the repository at this point in the history
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Maya <[email protected]>
  • Loading branch information
3 people authored Jan 12, 2025
1 parent fb18c4e commit 79d4df8
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 15 deletions.
2 changes: 2 additions & 0 deletions src/main/java/gregtech/api/logic/AbstractProcessingLogic.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public abstract class AbstractProcessingLogic<P extends AbstractProcessingLogic<
protected double speedBoost = 1.0;
protected boolean amperageOC = true;
protected boolean isCleanroom;
protected boolean needWipeCraftingPatternRecipeCache;

// #region Setters

Expand Down Expand Up @@ -213,6 +214,7 @@ protected RecipeMap<?> preProcess() {
recipeMap = recipeMapSupplier.get();
}
if (lastRecipeMap != recipeMap) {
if (lastRecipeMap != null) needWipeCraftingPatternRecipeCache = true;
lastRecipe = null;
lastRecipeMap = recipeMap;
}
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/gregtech/api/logic/ProcessingLogic.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package gregtech.api.logic;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Nonnull;
Expand All @@ -10,13 +14,15 @@
import net.minecraftforge.fluids.FluidStack;

import gregtech.api.interfaces.tileentity.IRecipeLockable;
import gregtech.api.objects.GTDualInputs;
import gregtech.api.recipe.RecipeMap;
import gregtech.api.recipe.check.CheckRecipeResult;
import gregtech.api.recipe.check.CheckRecipeResultRegistry;
import gregtech.api.recipe.check.SingleRecipeCheck;
import gregtech.api.util.GTRecipe;
import gregtech.api.util.OverclockCalculator;
import gregtech.api.util.ParallelHelper;
import gregtech.common.tileentities.machines.IDualInputInventory;

/**
* Logic class to calculate result of recipe check from inputs, based on recipemap.
Expand All @@ -29,6 +35,8 @@ public class ProcessingLogic extends AbstractProcessingLogic<ProcessingLogic> {
protected ItemStack[] inputItems;
protected FluidStack[] inputFluids;
protected boolean isRecipeLocked;
protected IDualInputInventory craftingPattern;
protected Map<IDualInputInventory, Set<GTRecipe>> craftingPatternRecipeCache = new HashMap<>();

public ProcessingLogic() {}

Expand Down Expand Up @@ -63,6 +71,33 @@ public ProcessingLogic setSpecialSlotItem(ItemStack specialSlotItem) {
return getThis();
}

public boolean craftingPatternHandler(IDualInputInventory slot) {
if (needWipeCraftingPatternRecipeCache) {
craftingPatternRecipeCache.clear();
needWipeCraftingPatternRecipeCache = false;
}

if (craftingPatternRecipeCache.containsKey(slot)) {
craftingPattern = slot;
return true;
} else {
GTDualInputs inputs = slot.getPatternInputs();
setInputItems(inputs.inputItems);
setInputFluids(inputs.inputFluid);
Set<GTRecipe> recipes = findRecipeMatches(preProcess()).collect(Collectors.toSet());
if (!recipes.isEmpty()) {
craftingPatternRecipeCache.put(slot, recipes);
craftingPattern = slot;
return true;
}
return false;
}
}

public void removeEntryCraftingPatternRecipeCache(IDualInputInventory slot) {
craftingPatternRecipeCache.remove(slot);
}

/**
* Enables single recipe locking mode.
*/
Expand All @@ -85,6 +120,7 @@ public ProcessingLogic clear() {
this.calculatedEut = 0;
this.duration = 0;
this.calculatedParallels = 0;
this.craftingPattern = null;
return getThis();
}

Expand All @@ -106,6 +142,18 @@ public CheckRecipeResult process() {
inputFluids = new FluidStack[0];
}

if (craftingPattern != null) {
Set<GTRecipe> matchedRecipes = craftingPatternRecipeCache.get(craftingPattern);
for (GTRecipe matchedRecipe : matchedRecipes) {
if (matchedRecipe.maxParallelCalculatedByInputs(1, inputFluids, inputItems) == 1) {
CalculationResult foundResult = validateAndCalculateRecipe(matchedRecipe);
return foundResult.checkRecipeResult;
}
}
craftingPattern = null;
return CheckRecipeResultRegistry.NO_RECIPE;
}

if (isRecipeLocked && recipeLockableMachine != null && recipeLockableMachine.getSingleRecipeCheck() != null) {
// Recipe checker is already built, we'll use it
SingleRecipeCheck singleRecipeCheck = recipeLockableMachine.getSingleRecipeCheck();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -883,16 +883,18 @@ protected boolean supportsCraftingMEBuffer() {
@Nonnull
protected CheckRecipeResult doCheckRecipe() {
CheckRecipeResult result = CheckRecipeResultRegistry.NO_RECIPE;

// check crafting input hatches first
if (supportsCraftingMEBuffer()) {
for (IDualInputHatch dualInputHatch : mDualInputHatches) {
for (var it = dualInputHatch.inventories(); it.hasNext();) {
IDualInputInventory slot = it.next();
// Reverse order of input items for consistent behavior with standard input buses.
ItemStack[] inputItems = slot.getItemInputs();
ArrayUtils.reverse(inputItems);
processingLogic.setInputItems(inputItems);
for (IDualInputHatch dualInputHatch : mDualInputHatches) {
ItemStack[] sharedItems = dualInputHatch.getSharedItems();
for (var it = dualInputHatch.inventories(); it.hasNext();) {
IDualInputInventory slot = it.next();

if (!slot.isEmpty() && processingLogic.craftingPatternHandler(slot)) {

processingLogic.setInputItems(ArrayUtils.addAll(sharedItems, slot.getItemInputs()));
processingLogic.setInputFluids(slot.getFluidInputs());

CheckRecipeResult foundResult = processingLogic.process();
if (foundResult.wasSuccessful()) {
return foundResult;
Expand Down Expand Up @@ -1720,6 +1722,7 @@ public boolean addToMachineList(IGregTechTileEntity aTileEntity, int aBaseCasing
}
if (aMetaTileEntity instanceof IDualInputHatch hatch) {
hatch.updateCraftingIcon(this.getMachineCraftingIcon());
hatch.setProcessingLogic(processingLogic);
return mDualInputHatches.add(hatch);
}
if (aMetaTileEntity instanceof ISmartInputHatch hatch) {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/gregtech/api/objects/GTDualInputs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package gregtech.api.objects;

import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;

public class GTDualInputs {

public ItemStack[] inputItems;
public FluidStack[] inputFluid;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import net.minecraft.item.ItemStack;

import gregtech.api.logic.ProcessingLogic;

public interface IDualInputHatch {

boolean justUpdated();
Expand All @@ -18,4 +20,8 @@ public interface IDualInputHatch {
Optional<IDualInputInventory> getFirstNonEmptyInventory();

boolean supportsFluids();

ItemStack[] getSharedItems();

void setProcessingLogic(ProcessingLogic pl);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;

import gregtech.api.objects.GTDualInputs;

public interface IDualInputInventory {

boolean isEmpty();

ItemStack[] getItemInputs();

FluidStack[] getFluidInputs();

GTDualInputs getPatternInputs();

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.apache.commons.lang3.ArrayUtils;
import org.jetbrains.annotations.NotNull;

import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.modularui.api.math.Alignment;
Expand Down Expand Up @@ -91,8 +92,10 @@
import gregtech.api.interfaces.modularui.IAddGregtechLogo;
import gregtech.api.interfaces.modularui.IAddUIWidgets;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.logic.ProcessingLogic;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.metatileentity.implementations.MTEHatchInputBus;
import gregtech.api.objects.GTDualInputs;
import gregtech.api.render.TextureFactory;
import gregtech.api.util.GTUtility;
import gregtech.api.util.extensions.ArrayExt;
Expand All @@ -116,6 +119,7 @@ public interface SharedItemGetter {
private final List<ItemStack> itemInventory;
private final List<FluidStack> fluidInventory;
private final SharedItemGetter sharedItemGetter;
private final GTUtility.ItemId itemId;

public PatternSlot(ItemStack pattern, World world, SharedItemGetter getter) {
this.pattern = pattern;
Expand All @@ -124,6 +128,7 @@ public PatternSlot(ItemStack pattern, World world, SharedItemGetter getter) {
this.itemInventory = new ArrayList<>();
this.fluidInventory = new ArrayList<>();
this.sharedItemGetter = getter;
this.itemId = GTUtility.ItemId.create(pattern);
}

public PatternSlot(ItemStack pattern, NBTTagCompound nbt, World world, SharedItemGetter getter) {
Expand All @@ -133,6 +138,7 @@ public PatternSlot(ItemStack pattern, NBTTagCompound nbt, World world, SharedIte
this.itemInventory = new ArrayList<>();
this.fluidInventory = new ArrayList<>();
this.sharedItemGetter = getter;
this.itemId = GTUtility.ItemId.create(pattern);
NBTTagList inv = nbt.getTagList("inventory", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < inv.tagCount(); i++) {
NBTTagCompound tagItemStack = inv.getCompoundTagAt(i);
Expand Down Expand Up @@ -198,14 +204,15 @@ public boolean isFluidEmpty() {
return fluidInventory.isEmpty();
}

@Override
public boolean isEmpty() {
return isItemEmpty() && isFluidEmpty();
}

@Override
public ItemStack[] getItemInputs() {
if (isEmpty()) return new ItemStack[0];
return ArrayUtils.addAll(itemInventory.toArray(new ItemStack[0]), sharedItemGetter.getSharedItem());
if (isItemEmpty()) return new ItemStack[0];
return itemInventory.toArray(new ItemStack[0]);
}

@Override
Expand All @@ -218,6 +225,43 @@ public ICraftingPatternDetails getPatternDetails() {
return patternDetails;
}

@Override
public GTDualInputs getPatternInputs() {
GTDualInputs dualInputs = new GTDualInputs();

ItemStack[] inputItems = this.sharedItemGetter.getSharedItem();
FluidStack[] inputFluids = new FluidStack[0];

for (IAEItemStack singleInput : this.getPatternDetails()
.getInputs()) {
if (singleInput == null) continue;
ItemStack singleInputItemStack = singleInput.getItemStack();
if (singleInputItemStack.getItem() instanceof ItemFluidDrop) {
FluidStack fluidStack = ItemFluidDrop.getFluidStack(singleInputItemStack);
if (fluidStack != null) inputFluids = ArrayUtils.addAll(inputFluids, fluidStack);
} else {
inputItems = ArrayUtils.addAll(inputItems, singleInputItemStack);
}
}

dualInputs.inputItems = inputItems;
dualInputs.inputFluid = inputFluids;
return dualInputs;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PatternSlot that = (PatternSlot) o;
return Objects.equals(pattern, that.pattern);
}

@Override
public int hashCode() {
return itemId.hashCode();
}

public void refund(AENetworkProxy proxy, BaseActionSource src) throws GridAccessException {
IMEMonitor<IAEItemStack> sg = proxy.getStorage()
.getItemInventory();
Expand Down Expand Up @@ -324,6 +368,7 @@ public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
private static final int MANUAL_SLOT_WINDOW = 10;
private BaseActionSource requestSource = null;
private @Nullable AENetworkProxy gridProxy = null;
public List<ProcessingLogic> processingLogics = new ArrayList<>();

// holds all internal inventories
private final PatternSlot[] internalInventory = new PatternSlot[MAX_PATTERN_COUNT];
Expand Down Expand Up @@ -785,6 +830,9 @@ private void onPatternChange(int index, ItemStack newItem) {
if (originalPattern.hasChanged(newItem, world)) {
try {
originalPattern.refund(getProxy(), getRequest());
for (ProcessingLogic pl : processingLogics) {
pl.removeEntryCraftingPatternRecipeCache(originalPattern);
}
} catch (GridAccessException ignored) {}
internalInventory[index] = null;
needPatternSync = true;
Expand All @@ -803,13 +851,30 @@ private void onPatternChange(int index, ItemStack newItem) {
needPatternSync = true;
}

@Override
public ItemStack[] getSharedItems() {
ItemStack[] sharedItems = new ItemStack[SLOT_MANUAL_SIZE + 1];
sharedItems[0] = mInventory[SLOT_CIRCUIT];
System.arraycopy(mInventory, SLOT_MANUAL_START, sharedItems, 1, SLOT_MANUAL_SIZE);
return ArrayExt.withoutNulls(sharedItems, ItemStack[]::new);
}

@Override
public void setProcessingLogic(ProcessingLogic pl) {
if (!processingLogics.contains(pl)) {
processingLogics.add(Objects.requireNonNull(pl));
}
}

private void resetCraftingInputRecipeMap() {
for (ProcessingLogic pl : processingLogics) {
for (PatternSlot sl : internalInventory) {
if (sl == null) continue;
pl.removeEntryCraftingPatternRecipeCache(sl);
}
}
}

@Override
public void getWailaBody(ItemStack itemStack, List<String> currenttip, IWailaDataAccessor accessor,
IWailaConfigHandler config) {
Expand Down Expand Up @@ -982,6 +1047,12 @@ public ItemStack getCrafterIcon() {
return getMachineCraftingIcon();
}

@Override
public void markDirty() {
super.markDirty();
resetCraftingInputRecipeMap();
}

private boolean postMEPatternChange() {
// don't post until it's active
if (!getProxy().isActive()) return false;
Expand Down Expand Up @@ -1015,6 +1086,7 @@ protected ModularWindow createSlotManualWindow(final EntityPlayer player) {
.endAtSlot(SLOT_MANUAL_START + SLOT_MANUAL_SIZE - 1)
.phantom(false)
.background(getGUITextureSet().getItemSlot())
.widgetCreator(slot -> new SlotWidget(slot).setChangeListener(this::resetCraftingInputRecipeMap))
.build()
.setPos(7, 7));
return builder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import gregtech.api.interfaces.IDataCopyable;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.logic.ProcessingLogic;
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.metatileentity.implementations.MTEHatchInputBus;
import gregtech.api.render.TextureFactory;
Expand Down Expand Up @@ -163,6 +164,11 @@ public boolean supportsFluids() {
return getMaster() != null && getMaster().supportsFluids();
}

@Override
public ItemStack[] getSharedItems() {
return getMaster() != null ? getMaster().getSharedItems() : new ItemStack[0];
}

@Override
public boolean justUpdated() {
return getMaster() != null && getMaster().justUpdated();
Expand Down Expand Up @@ -291,4 +297,9 @@ public void getWailaNBTData(EntityPlayerMP player, TileEntity tile, NBTTagCompou
public List<ItemStack> getItemsForHoloGlasses() {
return getMaster() != null ? getMaster().getItemsForHoloGlasses() : null;
}

@Override
public void setProcessingLogic(ProcessingLogic pl) {
if (getMaster() != null) getMaster().setProcessingLogic(pl);
}
}
Loading

0 comments on commit 79d4df8

Please sign in to comment.