Changed JEI transfer error mechanics

This commit is contained in:
raoulvdberge
2020-09-27 11:34:02 +02:00
parent 52ee5d5469
commit f23e393494
8 changed files with 122 additions and 34 deletions

View File

@@ -1,6 +1,7 @@
# Refined Storage Changelog # Refined Storage Changelog
### 1.9.7 ### 1.9.7
- Changed JEI transfer error mechanics (raoulvdberge)
- Fixed crash when opening Controller GUI (Darkere) - Fixed crash when opening Controller GUI (Darkere)
- Fixed dye being consumed without effect in some cases (Darkere) - Fixed dye being consumed without effect in some cases (Darkere)

View File

@@ -29,7 +29,8 @@ import java.util.stream.Collectors;
public class GridRecipeTransferHandler implements IRecipeTransferHandler<GridContainer> { public class GridRecipeTransferHandler implements IRecipeTransferHandler<GridContainer> {
public static final long TRANSFER_SCROLLBAR_DELAY_MS = 200; public static final long TRANSFER_SCROLLBAR_DELAY_MS = 200;
public static long LAST_TRANSFER_TIME;
public static long lastTransferTime;
@Override @Override
public Class<GridContainer> getContainerClass() { public Class<GridContainer> getContainerClass() {
@@ -38,26 +39,62 @@ public class GridRecipeTransferHandler implements IRecipeTransferHandler<GridCon
@Override @Override
public IRecipeTransferError transferRecipe(@Nonnull GridContainer container, Object recipe, @Nonnull IRecipeLayout recipeLayout, @Nonnull PlayerEntity player, boolean maxTransfer, boolean doTransfer) { public IRecipeTransferError transferRecipe(@Nonnull GridContainer container, Object recipe, @Nonnull IRecipeLayout recipeLayout, @Nonnull PlayerEntity player, boolean maxTransfer, boolean doTransfer) {
if (!(container.getScreenInfoProvider() instanceof GridScreen)) {
return null;
}
GridType type = container.getGrid().getGridType();
if (type == GridType.CRAFTING) {
return transferRecipeForCraftingGrid(container, recipeLayout, player, doTransfer);
} else if (type == GridType.PATTERN) {
return transferRecipeForPatternGrid(container, recipeLayout, player, doTransfer);
}
return null;
}
private RecipeTransferCraftingGridError transferRecipeForCraftingGrid(GridContainer container, IRecipeLayout recipeLayout, PlayerEntity player, boolean doTransfer) {
IngredientTracker tracker = createTracker(container, recipeLayout, player); IngredientTracker tracker = createTracker(container, recipeLayout, player);
if (tracker.hasMissing() && !doTransfer) { if (doTransfer) {
return new RecipeTransferGridError(tracker); if (tracker.hasMissingButAutocraftingAvailable() && Screen.hasControlDown()) {
} else if (tracker.hasMissing() && doTransfer && Screen.hasControlDown()) { tracker.createCraftingRequests().forEach((id, count) -> RS.NETWORK_HANDLER.sendToServer(
tracker.getCraftingRequests().forEach((id, count) -> { new GridCraftingPreviewRequestMessage(
RS.NETWORK_HANDLER.sendToServer(new GridCraftingPreviewRequestMessage(id, count, Screen.hasShiftDown(), false)); id,
}); count,
} else if (doTransfer) { Screen.hasShiftDown(),
false
)
));
} else {
moveItems(container, recipeLayout); moveItems(container, recipeLayout);
} }
} else {
if (tracker.hasMissing()) {
return new RecipeTransferCraftingGridError(tracker);
}
}
return null;
}
private IRecipeTransferError transferRecipeForPatternGrid(GridContainer container, IRecipeLayout recipeLayout, PlayerEntity player, boolean doTransfer) {
IngredientTracker tracker = createTracker(container, recipeLayout, player);
if (doTransfer) {
moveItems(container, recipeLayout);
} else {
if (tracker.isAutocraftingAvailable()) {
return new RecipeTransferPatternGridError(tracker);
}
}
return null; return null;
} }
private IngredientTracker createTracker(GridContainer container, IRecipeLayout recipeLayout, PlayerEntity player) { private IngredientTracker createTracker(GridContainer container, IRecipeLayout recipeLayout, PlayerEntity player) {
IngredientTracker tracker = new IngredientTracker(recipeLayout); IngredientTracker tracker = new IngredientTracker(recipeLayout);
if (!(container.getScreenInfoProvider() instanceof GridScreen)) {
return tracker;
}
// Using IGridView#getStacks will return a *filtered* list of items in the view, // Using IGridView#getStacks will return a *filtered* list of items in the view,
// which will cause problems - especially if the user uses JEI synchronised searching. // which will cause problems - especially if the user uses JEI synchronised searching.
@@ -96,7 +133,7 @@ public class GridRecipeTransferHandler implements IRecipeTransferHandler<GridCon
private void moveItems(GridContainer gridContainer, IRecipeLayout recipeLayout) { private void moveItems(GridContainer gridContainer, IRecipeLayout recipeLayout) {
IGrid grid = gridContainer.getGrid(); IGrid grid = gridContainer.getGrid();
LAST_TRANSFER_TIME = System.currentTimeMillis(); lastTransferTime = System.currentTimeMillis();
if (grid.getGridType() == GridType.PATTERN && !recipeLayout.getRecipeCategory().getUid().equals(VanillaRecipeCategoryUid.CRAFTING)) { if (grid.getGridType() == GridType.PATTERN && !recipeLayout.getRecipeCategory().getUid().equals(VanillaRecipeCategoryUid.CRAFTING)) {
List<ItemStack> inputs = new LinkedList<>(); List<ItemStack> inputs = new LinkedList<>();

View File

@@ -6,9 +6,9 @@ import net.minecraft.item.ItemStack;
import java.util.UUID; import java.util.UUID;
class Ingredient { class Ingredient {
private IGuiIngredient<ItemStack> guiIngredient; private final IGuiIngredient<ItemStack> guiIngredient;
private UUID craftStackId; private UUID craftStackId;
private int required; private final int required;
private int fulfilled; private int fulfilled;
public Ingredient(IGuiIngredient<ItemStack> guiIngredient) { public Ingredient(IGuiIngredient<ItemStack> guiIngredient) {

View File

@@ -32,17 +32,19 @@ public class IngredientTracker {
return; return;
} }
if (ingredient.isAvailable()) { Optional<ItemStack> match = ingredient
continue; .getGuiIngredient()
} .getAllIngredients()
.stream()
.filter(s -> API.instance().getComparer().isEqual(stack, s, IComparer.COMPARE_NBT))
.findFirst();
Optional<?> match = ingredient.getGuiIngredient().getAllIngredients().stream().filter((ItemStack matchingStack) -> API.instance().getComparer().isEqual(stack, matchingStack, IComparer.COMPARE_NBT)).findFirst();
if (match.isPresent()) { if (match.isPresent()) {
//craftables and non-craftables are 2 different gridstacks // Craftables and non-craftables are 2 different gridstacks
//as such we need to ignore craftable stacks as they are not actual items // As such we need to ignore craftable stacks as they are not actual items
if (gridStack != null && gridStack.isCraftable()) { if (gridStack != null && gridStack.isCraftable()) {
ingredient.setCraftStackId(gridStack.getId()); ingredient.setCraftStackId(gridStack.getId());
} else { } else if (!ingredient.isAvailable()) {
int needed = ingredient.getMissingAmount(); int needed = ingredient.getMissingAmount();
int used = Math.min(available, needed); int used = Math.min(available, needed);
ingredient.fulfill(used); ingredient.fulfill(used);
@@ -56,7 +58,15 @@ public class IngredientTracker {
return ingredients.stream().anyMatch(ingredient -> !ingredient.isAvailable()); return ingredients.stream().anyMatch(ingredient -> !ingredient.isAvailable());
} }
public Map<UUID, Integer> getCraftingRequests() { public boolean hasMissingButAutocraftingAvailable() {
return ingredients.stream().anyMatch(ingredient -> !ingredient.isAvailable() && ingredient.isCraftable());
}
public boolean isAutocraftingAvailable() {
return ingredients.stream().anyMatch(Ingredient::isCraftable);
}
public Map<UUID, Integer> createCraftingRequests() {
Map<UUID, Integer> toRequest = new HashMap<>(); Map<UUID, Integer> toRequest = new HashMap<>();
for (Ingredient ingredient : ingredients) { for (Ingredient ingredient : ingredients) {

View File

@@ -15,12 +15,13 @@ import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class RecipeTransferGridError implements IRecipeTransferError { public class RecipeTransferCraftingGridError implements IRecipeTransferError {
private static final Color HIGHLIGHT_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.4f); private static final Color MISSING_HIGHLIGHT_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.4f);
private static final Color HIGHLIGHT_AUTOCRAFT_COLOR = new Color(0.0f, 0.0f, 1.0f, 0.4f); protected static final Color AUTOCRAFTING_HIGHLIGHT_COLOR = new Color(0.0f, 0.0f, 1.0f, 0.4f);
IngredientTracker tracker;
public RecipeTransferGridError(IngredientTracker tracker) { protected final IngredientTracker tracker;
public RecipeTransferCraftingGridError(IngredientTracker tracker) {
this.tracker = tracker; this.tracker = tracker;
} }
@@ -31,24 +32,26 @@ public class RecipeTransferGridError implements IRecipeTransferError {
@Override @Override
public void showError(MatrixStack stack, int mouseX, int mouseY, IRecipeLayout recipeLayout, int recipeX, int recipeY) { public void showError(MatrixStack stack, int mouseX, int mouseY, IRecipeLayout recipeLayout, int recipeX, int recipeY) {
List<ITextComponent> message = drawIngredientHighlights(stack, tracker, recipeX, recipeY); List<ITextComponent> message = drawIngredientHighlights(stack, recipeX, recipeY);
Screen currentScreen = Minecraft.getInstance().currentScreen; Screen currentScreen = Minecraft.getInstance().currentScreen;
GuiUtils.drawHoveringText(ItemStack.EMPTY, stack, message, mouseX, mouseY, currentScreen.width, currentScreen.height, 150, Minecraft.getInstance().fontRenderer); GuiUtils.drawHoveringText(ItemStack.EMPTY, stack, message, mouseX, mouseY, currentScreen.width, currentScreen.height, 150, Minecraft.getInstance().fontRenderer);
} }
private List<ITextComponent> drawIngredientHighlights(MatrixStack stack, IngredientTracker tracker, int recipeX, int recipeY) { protected List<ITextComponent> drawIngredientHighlights(MatrixStack stack, int recipeX, int recipeY) {
List<ITextComponent> message = new ArrayList<>(); List<ITextComponent> message = new ArrayList<>();
message.add(new TranslationTextComponent("jei.tooltip.transfer")); message.add(new TranslationTextComponent("jei.tooltip.transfer"));
boolean craftMessage = false; boolean craftMessage = false;
boolean missingMessage = false; boolean missingMessage = false;
for (Ingredient ingredient : tracker.getIngredients()) { for (Ingredient ingredient : tracker.getIngredients()) {
if (!ingredient.isAvailable()) { if (!ingredient.isAvailable()) {
if (ingredient.isCraftable()) { if (ingredient.isCraftable()) {
ingredient.getGuiIngredient().drawHighlight(stack, HIGHLIGHT_AUTOCRAFT_COLOR.getRGB(), recipeX, recipeY); ingredient.getGuiIngredient().drawHighlight(stack, AUTOCRAFTING_HIGHLIGHT_COLOR.getRGB(), recipeX, recipeY);
craftMessage = true; craftMessage = true;
} else { } else {
ingredient.getGuiIngredient().drawHighlight(stack, HIGHLIGHT_COLOR.getRGB(), recipeX, recipeY); ingredient.getGuiIngredient().drawHighlight(stack, MISSING_HIGHLIGHT_COLOR.getRGB(), recipeX, recipeY);
missingMessage = true; missingMessage = true;
} }
} }
@@ -59,7 +62,7 @@ public class RecipeTransferGridError implements IRecipeTransferError {
} }
if (craftMessage) { if (craftMessage) {
message.add(new TranslationTextComponent("gui.refinedstorage.jei.tooltip.error.recipe.transfer.missing.autocraft").mergeStyle(TextFormatting.BLUE)); message.add(new TranslationTextComponent("gui.refinedstorage.jei.transfer.request_autocrafting").mergeStyle(TextFormatting.BLUE));
} }
return message; return message;

View File

@@ -0,0 +1,36 @@
package com.refinedmods.refinedstorage.integration.jei;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent;
import java.util.ArrayList;
import java.util.List;
public class RecipeTransferPatternGridError extends RecipeTransferCraftingGridError {
public RecipeTransferPatternGridError(IngredientTracker tracker) {
super(tracker);
}
@Override
protected List<ITextComponent> drawIngredientHighlights(MatrixStack stack, int recipeX, int recipeY) {
List<ITextComponent> message = new ArrayList<>();
message.add(new TranslationTextComponent("jei.tooltip.transfer"));
boolean craftMessage = false;
for (Ingredient ingredient : tracker.getIngredients()) {
if (ingredient.isCraftable()) {
ingredient.getGuiIngredient().drawHighlight(stack, AUTOCRAFTING_HIGHLIGHT_COLOR.getRGB(), recipeX, recipeY);
craftMessage = true;
}
}
if (craftMessage) {
message.add(new TranslationTextComponent("gui.refinedstorage.jei.transfer.autocrafting_available").mergeStyle(TextFormatting.BLUE));
}
return message;
}
}

View File

@@ -72,7 +72,7 @@ public class ScrollbarWidget implements IGuiEventListener {
if (button == 0 && RenderUtils.inBounds(x, y, width, height, mx, my)) { if (button == 0 && RenderUtils.inBounds(x, y, width, height, mx, my)) {
// Prevent accidental scrollbar click after clicking recipe transfer button // Prevent accidental scrollbar click after clicking recipe transfer button
if (JeiIntegration.isLoaded() && System.currentTimeMillis() - GridRecipeTransferHandler.LAST_TRANSFER_TIME <= GridRecipeTransferHandler.TRANSFER_SCROLLBAR_DELAY_MS) { if (JeiIntegration.isLoaded() && System.currentTimeMillis() - GridRecipeTransferHandler.lastTransferTime <= GridRecipeTransferHandler.TRANSFER_SCROLLBAR_DELAY_MS) {
return false; return false;
} }

View File

@@ -88,7 +88,8 @@
"gui.refinedstorage.crafter_manager": "Crafter Manager", "gui.refinedstorage.crafter_manager": "Crafter Manager",
"gui.refinedstorage.alternatives": "Alternatives", "gui.refinedstorage.alternatives": "Alternatives",
"gui.refinedstorage.alternatives.apply": "Apply", "gui.refinedstorage.alternatives.apply": "Apply",
"gui.refinedstorage.jei.tooltip.error.recipe.transfer.missing.autocraft": "CTRL + CLICK to request autocrafting", "gui.refinedstorage.jei.transfer.autocrafting_available": "Autocrafting available",
"gui.refinedstorage.jei.transfer.request_autocrafting": "CTRL + CLICK to request autocrafting",
"misc.refinedstorage.energy_stored": "%d / %d FE", "misc.refinedstorage.energy_stored": "%d / %d FE",
"misc.refinedstorage.energy_usage": "Usage: %d FE/t", "misc.refinedstorage.energy_usage": "Usage: %d FE/t",
"misc.refinedstorage.energy_usage_minimal": "%d FE/t", "misc.refinedstorage.energy_usage_minimal": "%d FE/t",