Auto crafting table fixes and improvements.
This now uses the same logic that the rolling machine uses to balance recipes.1.15 Fixes #1891
This commit is contained in:
parent
e171d0eabc
commit
bd81ca48f6
2 changed files with 120 additions and 83 deletions
|
@ -53,8 +53,10 @@ import techreborn.init.TRContent;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by modmuss50 on 20/06/2017.
|
* Created by modmuss50 on 20/06/2017.
|
||||||
|
@ -62,10 +64,11 @@ import java.util.Optional;
|
||||||
public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
||||||
implements IToolDrop, InventoryProvider, IContainerProvider {
|
implements IToolDrop, InventoryProvider, IContainerProvider {
|
||||||
|
|
||||||
public RebornInventory<AutoCraftingTableBlockEntity> inventory = new RebornInventory<>(11, "AutoCraftingTableBlockEntity", 64, this, getInventoryAccess());
|
public RebornInventory<AutoCraftingTableBlockEntity> inventory = new RebornInventory<>(11, "AutoCraftingTableBlockEntity", 64, this);
|
||||||
public int progress;
|
public int progress;
|
||||||
public int maxProgress = 120;
|
public int maxProgress = 120;
|
||||||
public int euTick = 10;
|
public int euTick = 10;
|
||||||
|
public int balanceSlot = 0;
|
||||||
|
|
||||||
CraftingInventory inventoryCrafting = null;
|
CraftingInventory inventoryCrafting = null;
|
||||||
CraftingRecipe lastCustomRecipe = null;
|
CraftingRecipe lastCustomRecipe = null;
|
||||||
|
@ -78,7 +81,7 @@ public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public CraftingRecipe getIRecipe() {
|
public CraftingRecipe getCurrentRecipe() {
|
||||||
CraftingInventory crafting = getCraftingInventory();
|
CraftingInventory crafting = getCraftingInventory();
|
||||||
if (!crafting.isInvEmpty()) {
|
if (!crafting.isInvEmpty()) {
|
||||||
if (lastRecipe != null) {
|
if (lastRecipe != null) {
|
||||||
|
@ -119,10 +122,14 @@ public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultedList<Ingredient> ingredients = recipe.getPreviewInputs();
|
DefaultedList<Ingredient> ingredients = recipe.getPreviewInputs();
|
||||||
|
List<Integer> checkedSlots = new ArrayList<>();
|
||||||
for (Ingredient ingredient : ingredients) {
|
for (Ingredient ingredient : ingredients) {
|
||||||
if (ingredient != Ingredient.EMPTY) {
|
if (ingredient != Ingredient.EMPTY) {
|
||||||
boolean foundIngredient = false;
|
boolean foundIngredient = false;
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
|
if(checkedSlots.contains(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ItemStack stack = inventory.getInvStack(i);
|
ItemStack stack = inventory.getInvStack(i);
|
||||||
int requiredSize = locked ? 1 : 0;
|
int requiredSize = locked ? 1 : 0;
|
||||||
if (stack.getMaxCount() == 1) {
|
if (stack.getMaxCount() == 1) {
|
||||||
|
@ -136,6 +143,7 @@ public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foundIngredient = true;
|
foundIngredient = true;
|
||||||
|
checkedSlots.add(i);
|
||||||
stacksInSlots[i]--;
|
stacksInSlots[i]--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -225,65 +233,6 @@ public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasIngredient(Ingredient ingredient) {
|
|
||||||
for (int i = 0; i < 9; i++) {
|
|
||||||
ItemStack stack = inventory.getInvStack(i);
|
|
||||||
if (ingredient.test(stack)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isItemValidForRecipeSlot(Recipe<CraftingInventory> recipe, ItemStack stack, int slotID) {
|
|
||||||
if (recipe == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
int bestSlot = findBestSlotForStack(recipe, stack);
|
|
||||||
if (bestSlot != -1) {
|
|
||||||
return bestSlot == slotID;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int findBestSlotForStack(Recipe<CraftingInventory> recipe, ItemStack stack) {
|
|
||||||
if (recipe == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
DefaultedList<Ingredient> ingredients = recipe.getPreviewInputs();
|
|
||||||
List<Integer> possibleSlots = new ArrayList<>();
|
|
||||||
for (int i = 0; i < recipe.getPreviewInputs().size(); i++) {
|
|
||||||
ItemStack stackInSlot = inventory.getInvStack(i);
|
|
||||||
Ingredient ingredient = ingredients.get(i);
|
|
||||||
if (ingredient != Ingredient.EMPTY && ingredient.test(stack)) {
|
|
||||||
if (stackInSlot.isEmpty()) {
|
|
||||||
possibleSlots.add(i);
|
|
||||||
} else if (stackInSlot.getItem() == stack.getItem()) {
|
|
||||||
if (stackInSlot.getMaxCount() >= stackInSlot.getCount() + stack.getCount()) {
|
|
||||||
possibleSlots.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Slot, count
|
|
||||||
Pair<Integer, Integer> smallestCount = null;
|
|
||||||
for (Integer slot : possibleSlots) {
|
|
||||||
ItemStack slotStack = inventory.getInvStack(slot);
|
|
||||||
if (slotStack.isEmpty()) {
|
|
||||||
return slot;
|
|
||||||
}
|
|
||||||
if (smallestCount == null) {
|
|
||||||
smallestCount = Pair.of(slot, slotStack.getCount());
|
|
||||||
} else if (smallestCount.getRight() >= slotStack.getCount()) {
|
|
||||||
smallestCount = Pair.of(slot, slotStack.getCount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (smallestCount != null) {
|
|
||||||
return smallestCount.getLeft();
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProgress() {
|
public int getProgress() {
|
||||||
return progress;
|
return progress;
|
||||||
}
|
}
|
||||||
|
@ -310,8 +259,11 @@ public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
||||||
if (world.isClient) {
|
if (world.isClient) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CraftingRecipe recipe = getIRecipe();
|
CraftingRecipe recipe = getCurrentRecipe();
|
||||||
if (recipe != null) {
|
if (recipe != null) {
|
||||||
|
Optional<CraftingInventory> balanceResult = balanceRecipe(getCraftingInventory());
|
||||||
|
balanceResult.ifPresent(craftingInventory -> inventoryCrafting = craftingInventory);
|
||||||
|
|
||||||
if (progress >= maxProgress) {
|
if (progress >= maxProgress) {
|
||||||
if (make(recipe)) {
|
if (make(recipe)) {
|
||||||
progress = 0;
|
progress = 0;
|
||||||
|
@ -336,6 +288,110 @@ public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<CraftingInventory> balanceRecipe(CraftingInventory craftCache) {
|
||||||
|
CraftingRecipe currentRecipe = getCurrentRecipe();
|
||||||
|
if (currentRecipe == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
if (world.isClient) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
if (craftCache.isInvEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
balanceSlot++;
|
||||||
|
if (balanceSlot > craftCache.getInvSize()) {
|
||||||
|
balanceSlot = 0;
|
||||||
|
}
|
||||||
|
//Find the best slot for each item in a recipe, and move it if needed
|
||||||
|
ItemStack sourceStack = inventory.getInvStack(balanceSlot);
|
||||||
|
if (sourceStack.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
List<Integer> possibleSlots = new ArrayList<>();
|
||||||
|
for (int s = 0; s < currentRecipe.getPreviewInputs().size(); s++) {
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
if(possibleSlots.contains(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ItemStack stackInSlot = inventory.getInvStack(i);
|
||||||
|
Ingredient ingredient = currentRecipe.getPreviewInputs().get(s);
|
||||||
|
if (ingredient != Ingredient.EMPTY && ingredient.test(sourceStack)) {
|
||||||
|
if (stackInSlot.getItem() == sourceStack.getItem()) {
|
||||||
|
possibleSlots.add(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!possibleSlots.isEmpty()){
|
||||||
|
int totalItems = possibleSlots.stream()
|
||||||
|
.mapToInt(value -> inventory.getInvStack(value).getCount()).sum();
|
||||||
|
int slots = possibleSlots.size();
|
||||||
|
|
||||||
|
//This makes an array of ints with the best possible slot EnvTyperibution
|
||||||
|
int[] split = new int[slots];
|
||||||
|
int remainder = totalItems % slots;
|
||||||
|
Arrays.fill(split, totalItems / slots);
|
||||||
|
while (remainder > 0){
|
||||||
|
for (int i = 0; i < split.length; i++) {
|
||||||
|
if(remainder > 0){
|
||||||
|
split[i] +=1;
|
||||||
|
remainder --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> slotEnvTyperubution = possibleSlots.stream()
|
||||||
|
.mapToInt(value -> inventory.getInvStack(value).getCount())
|
||||||
|
.boxed().collect(Collectors.toList());
|
||||||
|
|
||||||
|
boolean needsBalance = false;
|
||||||
|
for (int i = 0; i < split.length; i++) {
|
||||||
|
int required = split[i];
|
||||||
|
if(slotEnvTyperubution.contains(required)){
|
||||||
|
//We need to remove the int, not at the int, this seems to work around that
|
||||||
|
slotEnvTyperubution.remove(new Integer(required));
|
||||||
|
} else {
|
||||||
|
needsBalance = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!needsBalance) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Slot, count
|
||||||
|
Pair<Integer, Integer> bestSlot = null;
|
||||||
|
for (Integer slot : possibleSlots) {
|
||||||
|
ItemStack slotStack = inventory.getInvStack(slot);
|
||||||
|
if (slotStack.isEmpty()) {
|
||||||
|
bestSlot = Pair.of(slot, 0);
|
||||||
|
}
|
||||||
|
if (bestSlot == null) {
|
||||||
|
bestSlot = Pair.of(slot, slotStack.getCount());
|
||||||
|
} else if (bestSlot.getRight() >= slotStack.getCount()) {
|
||||||
|
bestSlot = Pair.of(slot, slotStack.getCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestSlot == null
|
||||||
|
|| bestSlot.getLeft() == balanceSlot
|
||||||
|
|| bestSlot.getRight() == sourceStack.getCount()
|
||||||
|
|| inventory.getInvStack(bestSlot.getLeft()).isEmpty()
|
||||||
|
|| !ItemUtils.isItemEqual(sourceStack, inventory.getInvStack(bestSlot.getLeft()), true, true)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
sourceStack.decrement(1);
|
||||||
|
inventory.getInvStack(bestSlot.getLeft()).increment(1);
|
||||||
|
inventory.setChanged();
|
||||||
|
|
||||||
|
return Optional.of(getCraftingInventory());
|
||||||
|
}
|
||||||
|
|
||||||
// Easyest way to sync back to the client
|
// Easyest way to sync back to the client
|
||||||
public int getLockedInt() {
|
public int getLockedInt() {
|
||||||
return locked ? 1 : 0;
|
return locked ? 1 : 0;
|
||||||
|
@ -390,25 +446,6 @@ public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IInventoryAccess<AutoCraftingTableBlockEntity> getInventoryAccess(){
|
|
||||||
return (slotID, stack, facing, direction, blockEntity) -> {
|
|
||||||
switch (direction){
|
|
||||||
case INSERT:
|
|
||||||
if (slotID > 8) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int bestSlot = blockEntity.findBestSlotForStack(blockEntity.getIRecipe(), stack);
|
|
||||||
if (bestSlot != -1) {
|
|
||||||
return slotID == bestSlot;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
case EXTRACT:
|
|
||||||
return slotID > 8;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// This machine doesnt have a facing
|
// This machine doesnt have a facing
|
||||||
@Override
|
@Override
|
||||||
public Direction getFacingEnum() {
|
public Direction getFacingEnum() {
|
||||||
|
@ -440,6 +477,6 @@ public class AutoCraftingTableBlockEntity extends PowerAcceptorBlockEntity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSlotConfig() {
|
public boolean hasSlotConfig() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class GuiAutoCrafting extends GuiBase<BuiltContainer> {
|
||||||
@Override
|
@Override
|
||||||
protected void drawForeground(int mouseX, int mouseY) {
|
protected void drawForeground(int mouseX, int mouseY) {
|
||||||
super.drawForeground(mouseX, mouseY);
|
super.drawForeground(mouseX, mouseY);
|
||||||
CraftingRecipe recipe = blockEntityAutoCraftingTable.getIRecipe();
|
CraftingRecipe recipe = blockEntityAutoCraftingTable.getCurrentRecipe();
|
||||||
if (recipe != null) {
|
if (recipe != null) {
|
||||||
renderItemStack(recipe.getOutput(), 95, 42);
|
renderItemStack(recipe.getOutput(), 95, 42);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue