Skip to content
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

Improve tracking of "missing ingredients" when performing recipe transfer from REI/EMI on dedicated servers #7714

Merged
merged 1 commit into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
14 changes: 8 additions & 6 deletions src/main/java/appeng/menu/me/common/MEStorageMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;

import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.shorts.ShortSet;

import appeng.api.behaviors.ContainerItemStrategies;
Expand Down Expand Up @@ -698,21 +699,22 @@ protected ItemStack transferStackToMenu(ItemStack input) {
}

/**
* Checks if the terminal has a given amount of the requested item. Used to determine for REI/JEI if a recipe is
* potentially craftable based on the available items.
* Checks if the terminal has a given reservedAmounts of the requested item. Used to determine for REI/JEI if a
* recipe is potentially craftable based on the available items.
* <p/>
* This method is <strong>slow</strong>, but it is client-only and thus doesn't scale with the player count.
*/
public boolean hasIngredient(Predicate<ItemStack> ingredient, int amount) {
public boolean hasIngredient(Predicate<ItemStack> predicate, Object2IntOpenHashMap<Object> reservedAmounts) {
var clientRepo = getClientRepo();

if (clientRepo != null) {
for (var stack : clientRepo.getAllEntries()) {
if (stack.getWhat() instanceof AEItemKey itemKey && ingredient.test(itemKey.toStack())) {
if (stack.getStoredAmount() >= amount) {
if (stack.getWhat() instanceof AEItemKey itemKey && predicate.test(itemKey.toStack())) {
var reservedAmount = reservedAmounts.getOrDefault(stack.getWhat(), 0);
if (stack.getStoredAmount() - reservedAmount >= 1) {
reservedAmounts.merge(itemKey, 1, Integer::sum);
return true;
}
amount -= stack.getStoredAmount();
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/appeng/menu/me/items/CraftingTermMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,21 +169,22 @@ public void clearCraftingGrid() {
}

@Override
public boolean hasIngredient(Predicate<ItemStack> predicate, int amount) {
public boolean hasIngredient(Predicate<ItemStack> predicate, Object2IntOpenHashMap<Object> reservedAmounts) {
// In addition to the base item repo, also check the crafting grid if it
// already contains some of the needed items
for (var slot : getSlots(SlotSemantics.CRAFTING_GRID)) {
var stackInSlot = slot.getItem();
if (!stackInSlot.isEmpty() && predicate.test(stackInSlot)) {
if (stackInSlot.getCount() >= amount) {
var reservedAmount = reservedAmounts.getOrDefault(slot, 0);
if (stackInSlot.getCount() > reservedAmount) {
reservedAmounts.merge(slot, 1, Integer::sum);
return true;
}
amount -= stackInSlot.getCount();
}

}

return super.hasIngredient(predicate, amount);
return super.hasIngredient(predicate, reservedAmounts);
}

/**
Expand Down Expand Up @@ -229,9 +230,8 @@ public MissingIngredientSlots findMissingIngredients(Map<Integer, Ingredient> in
// Then check the terminal screen's repository of network items
if (!found) {
// We use AE stacks to get an easily comparable item type key that ignores stack size
int neededAmount = reservedGridAmounts.getOrDefault(ingredient, 0) + 1;
if (hasIngredient(ingredient, neededAmount)) {
reservedGridAmounts.put(ingredient, neededAmount);
if (hasIngredient(ingredient, reservedGridAmounts)) {
reservedGridAmounts.merge(ingredient, 1, Integer::sum);
found = true;
}
}
Expand Down
Loading