Skip to content

Add support for VoidProtection of Items to MultiSmelter #3650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions src/main/java/gregtech/api/util/VoidProtectionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ public class VoidProtectionHelper {
* The fluid output inventory
*/
private FluidInventoryLogic fluidOutputInventory;
/**
* The item outputs to take in account as already in output buses
*/
private ItemStack[] virtualItemOutputsInBus;
/**
* Has this helper been built?
*/
Expand Down Expand Up @@ -150,6 +154,11 @@ public VoidProtectionHelper setChangeGetter(Function<Integer, Integer> getter) {
return this;
}

public VoidProtectionHelper setVirtualItemOutputsInBus(ItemStack[] itemOutputs) {
this.virtualItemOutputsInBus = itemOutputs;
return this;
}

/**
* Finishes the VoidProtectionHelper. Anything changed after this will not affect anything
*/
Expand Down Expand Up @@ -403,6 +412,9 @@ private int calculateMaxItemParallels() {
} else {
busStacks = machine.getItemOutputSlots(itemOutputs);
}

mergeVirtualItemOutputsInto(busStacks);

// A map to hold the items we will be 'inputting' into the output buses. These itemstacks are actually the
// recipe outputs.
Map<ItemStack, Integer> tItemOutputMap = new ItemStackMap<>();
Expand Down Expand Up @@ -476,6 +488,64 @@ private int calculateMaxItemParallels() {
return 0;
}

private void mergeVirtualItemOutputsInto(List<ItemStack> itemStacks) {
if (virtualItemOutputsInBus == null) return;

for (ItemStack virtualStack : virtualItemOutputsInBus) {
if (virtualStack == null || virtualStack.stackSize <= 0) continue;

int maxStackSize = virtualStack.getMaxStackSize();
int remainingItems = virtualStack.stackSize;

while (remainingItems > 0) {
boolean merged = false;

for (ItemStack busStack : itemStacks) {
if (busStack == null) continue;

if (busStack.isItemEqual(virtualStack) && ItemStack.areItemStackTagsEqual(busStack, virtualStack)) {
int spaceLeft = busStack.getMaxStackSize() - busStack.stackSize;
if (spaceLeft > 0) {
int transferAmount = Math.min(spaceLeft, remainingItems);
busStack.stackSize += transferAmount;
remainingItems -= transferAmount;

if (remainingItems == 0) {
merged = true;
break;
}
}
}
}

if (!merged) {
boolean replacedNull = false;

for (int i = 0; i < itemStacks.size(); i++) {
if (itemStacks.get(i) == null) {
int newStackSize = Math.min(remainingItems, maxStackSize);
ItemStack newStack = ItemStack.copyItemStack(virtualStack);
newStack.stackSize = newStackSize;
itemStacks.set(i, newStack);
remainingItems -= newStackSize;
replacedNull = true;
break;
}
}

// If no null slot was found, add a new stack to the list
if (!replacedNull) {
int newStackSize = Math.min(remainingItems, maxStackSize);
ItemStack newStack = ItemStack.copyItemStack(virtualStack);
newStack.stackSize = newStackSize;
itemStacks.add(newStack);
remainingItems -= newStackSize;
}
}
}
}
}

private static class ParallelData {

private int batch;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import gregtech.api.util.GTUtility;
import gregtech.api.util.MultiblockTooltipBuilder;
import gregtech.api.util.OverclockCalculator;
import gregtech.api.util.VoidProtectionHelper;

public class MTEMultiFurnace extends MTEAbstractMultiFurnace<MTEMultiFurnace> implements ISurvivalConstructable {

Expand Down Expand Up @@ -206,19 +207,50 @@ public CheckRecipeResult checkProcessing() {
for (ItemStack item : tInputList) {
ItemStack smeltedOutput = GTModHandler.getSmeltingOutput(item, false, null);
if (smeltedOutput != null) {
if (remainingCost >= item.stackSize) {
int maxParallelForOutput = remainingCost;

// Initialize void protection for the current output
if (protectsExcessItem()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still suggest you move this void protection part and merge into Calculate parallel part, so that subtick energy cost will be correct

VoidProtectionHelper voidProtectionHelper = new VoidProtectionHelper();
voidProtectionHelper.setMachine(this)
.setMaxParallel(remainingCost)
.setVirtualItemOutputsInBus(smeltedOutputs.toArray(new ItemStack[0]))
.setItemOutputs(new ItemStack[] { smeltedOutput })
.build();

maxParallelForOutput = Math.min(voidProtectionHelper.getMaxParallel(), remainingCost);

if (maxParallelForOutput == 0) {
continue;
}
}

if (maxParallelForOutput >= item.stackSize) {
remainingCost -= item.stackSize;
smeltedOutput.stackSize *= item.stackSize;
item.stackSize = 0;
smeltedOutputs.add(smeltedOutput);
} else {
smeltedOutput.stackSize *= remainingCost;
item.stackSize -= remainingCost;
remainingCost -= maxParallelForOutput;
smeltedOutput.stackSize *= maxParallelForOutput;
item.stackSize -= maxParallelForOutput;
smeltedOutputs.add(smeltedOutput);
}

if (remainingCost <= 0) {
break;
}
}
}

if (protectsExcessItem() && smeltedOutputs.isEmpty()) {
return CheckRecipeResultRegistry.ITEM_OUTPUT_FULL;
}

if (isBatchModeEnabled()) {
batchMultiplierMax = Math.max(1, batchMultiplierMax * (finalParallel - remainingCost) / finalParallel);
}

this.mOutputItems = smeltedOutputs.toArray(new ItemStack[0]);

this.mEfficiency = 10000 - (getIdealStatus() - getRepairStatus()) * 1000;
Expand Down Expand Up @@ -376,4 +408,9 @@ public boolean onWireCutterRightClick(ForgeDirection side, ForgeDirection wrench
}
return true;
}

@Override
public boolean supportsVoidProtection() {
return true;
}
}