Skip to content

Commit

Permalink
Downgraded JEI missing slots error to a warning. (#5222)
Browse files Browse the repository at this point in the history
Now using the new JEI feature added in 7.7.0.98 to indicate a warning by
tinting the `+` button yellow/orange instead of a hard fail.
Update to using the new methods using `ITextCompoment` instead of
`String`
Fixed a wrong text entry for charged certus quartz when the worldgen is
disabled.

Updated to JEI 7.7.0.98 and added as non mandatory minimum requirement
Updated to Forge 36.1.10 as minimum requirement to fix it ignoring
minimum requirements for non mandatory dependencies.
  • Loading branch information
yueh authored May 17, 2021
1 parent b227255 commit 12b3d2e
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 54 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ processResources {
exclude '.cache'

filesMatching("META-INF/mods.toml") {
expand 'version': version, 'minecraft_version': project.minecraft_version_range, 'forge_version': project.forge_version_range
expand 'version': version, 'minecraft_version': project.minecraft_version_range, 'forge_version': project.forge_version_range,
'jei_version': project.jei_version_range, 'top_version': project.top_version_range
}
}

Expand Down
8 changes: 5 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ minecraft_version=1.16.5
minecraft_version_range=[1.16.5,1.17.0)
mcp_channel=snapshot
mcp_mappings=20210309-1.16.5
forge_version=36.1.0
forge_version_range=[36.1.0,37.0.0)
forge_version=36.1.10
forge_version_range=[36.1.10,37.0.0)

#########################################################
# Provided APIs #
#########################################################
jei_minecraft_version=1.16.5
jei_version=7.6.4.90
jei_version=7.7.0.98
jei_version_range=[7.7.0.98,8.0.0)
top_version=3.0.8-14
top_version_range=[1.16-3.0.0,1.16-4.0.0)

#########################################################
# Deployment #
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@
import java.util.List;
import java.util.Map;

import com.mojang.blaze3d.matrix.MatrixStack;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;

import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiIngredient;
Expand Down Expand Up @@ -70,9 +73,9 @@ protected IRecipeTransferError doTransferRecipe(CraftingTermContainer container,
// Find every "slot" (in JEI parlance) that has no equivalent item in the item repo or player inventory
List<Integer> missingSlots = new ArrayList<>();

// We need to track how many of a given item stack we've already used for other slots in
// the recipe. Otherwise recipes that need 4x<item> will not correctly show missing
// items if at least 1 of <item> is in the grid.
// We need to track how many of a given item stack we've already used for other slots in the recipe.
// Otherwise recipes that need 4x<item> will not correctly show missing items if at least 1 of <item> is in
// the grid.
Map<IAEItemStack, Integer> reservedGridAmounts = new HashMap<>();

for (Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> entry : recipeLayout.getItemStacks()
Expand Down Expand Up @@ -112,8 +115,8 @@ protected IRecipeTransferError doTransferRecipe(CraftingTermContainer container,
}

if (!missingSlots.isEmpty()) {
String tooltip = I18n.format("jei.appliedenergistics2.missing_items");
return helper.createUserErrorForSlots(tooltip, missingSlots);
ITextComponent message = new TranslationTextComponent("jei.appliedenergistics2.missing_items");
return new TransferWarning(helper.createUserErrorForSlots(message, missingSlots));
}
}

Expand All @@ -125,4 +128,25 @@ protected boolean isCrafting() {
return true;
}

private static class TransferWarning implements IRecipeTransferError {

private final IRecipeTransferError parent;

public TransferWarning(IRecipeTransferError parent) {
this.parent = parent;
}

@Override
public Type getType() {
return Type.COSMETIC;
}

@Override
public void showError(MatrixStack matrixStack, int mouseX, int mouseY, IRecipeLayout recipeLayout, int recipeX,
int recipeY) {
this.parent.showError(matrixStack, mouseX, mouseY, recipeLayout, recipeX, recipeY);
}

}

}
37 changes: 20 additions & 17 deletions src/main/java/appeng/integration/modules/jei/JEIPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.RecipeManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;

import mezz.jei.api.IModPlugin;
import mezz.jei.api.JeiPlugin;
Expand Down Expand Up @@ -137,44 +139,46 @@ public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
private void registerDescriptions(IDefinitions definitions, IRecipeRegistration registry) {
IMaterials materials = definitions.materials();

final String[] message;
final ITextComponent[] message;
if (AEConfig.instance().isFeatureEnabled(AEFeature.CERTUS_QUARTZ_WORLD_GEN)) {
message = new String[] { GuiText.ChargedQuartz.getTranslationKey(), "",
GuiText.ChargedQuartzFind.getTranslationKey() };
// " " Used to enforce a new paragraph
message = new ITextComponent[] { GuiText.ChargedQuartz.text(), new StringTextComponent(" "),
GuiText.ChargedQuartzFind.text() };
} else {
message = new String[] { GuiText.ChargedQuartzFind.getTranslationKey() };
message = new ITextComponent[] { GuiText.ChargedQuartz.text() };
}
this.addDescription(registry, materials.certusQuartzCrystalCharged(), message);

if (AEConfig.instance().isFeatureEnabled(AEFeature.METEORITE_WORLD_GEN)) {
this.addDescription(registry, materials.logicProcessorPress(),
GuiText.inWorldCraftingPresses.getTranslationKey());
GuiText.inWorldCraftingPresses.text());
this.addDescription(registry, materials.calcProcessorPress(),
GuiText.inWorldCraftingPresses.getTranslationKey());
GuiText.inWorldCraftingPresses.text());
this.addDescription(registry, materials.engProcessorPress(),
GuiText.inWorldCraftingPresses.getTranslationKey());
GuiText.inWorldCraftingPresses.text());
}

if (AEConfig.instance().isFeatureEnabled(AEFeature.IN_WORLD_FLUIX)) {
this.addDescription(registry, materials.fluixCrystal(), GuiText.inWorldFluix.getTranslationKey());
this.addDescription(registry, materials.fluixCrystal(), GuiText.inWorldFluix.text());
}

if (AEConfig.instance().isFeatureEnabled(AEFeature.IN_WORLD_SINGULARITY)) {
this.addDescription(registry, materials.qESingularity(), GuiText.inWorldSingularity.getTranslationKey());
this.addDescription(registry, materials.qESingularity(), GuiText.inWorldSingularity.text());
}

if (AEConfig.instance().isFeatureEnabled(AEFeature.IN_WORLD_PURIFICATION)) {
this.addDescription(registry, materials.purifiedCertusQuartzCrystal(),
GuiText.inWorldPurificationCertus.getTranslationKey());
GuiText.inWorldPurificationCertus.text());
this.addDescription(registry, materials.purifiedNetherQuartzCrystal(),
GuiText.inWorldPurificationNether.getTranslationKey());
GuiText.inWorldPurificationNether.text());
this.addDescription(registry, materials.purifiedFluixCrystal(),
GuiText.inWorldPurificationFluix.getTranslationKey());
GuiText.inWorldPurificationFluix.text());
}

}

private void addDescription(IRecipeRegistration registry, IItemDefinition itemDefinition, String... message) {
private void addDescription(IRecipeRegistration registry, IItemDefinition itemDefinition,
ITextComponent... message) {
registry.addIngredientInfo(itemDefinition.stack(1), VanillaTypes.ITEM, message);
}

Expand Down Expand Up @@ -206,8 +210,8 @@ public List<Rectangle2d> getGuiExtraAreas(ContainerScreen containerScreen) {
@Nullable
@Override
public Object getIngredientUnderMouse(ContainerScreen<?> containerScreen, double mouseX, double mouseY) {
// The following code allows the player to show recipes involving fluids in AE fluid terminals or
// AE fluid tanks shown in fluid interfaces and other UI.
// The following code allows the player to show recipes involving fluids in AE fluid terminals or AE
// fluid tanks shown in fluid interfaces and other UI.
if (containerScreen instanceof AEBaseScreen) {
AEBaseScreen<?> baseScreen = (AEBaseScreen<?>) containerScreen;
return baseScreen.getIngredientUnderMouse(mouseX, mouseY);
Expand Down Expand Up @@ -244,8 +248,7 @@ public void onRuntimeAvailable(IJeiRuntime jeiRuntime) {
private void hideDebugTools(IJeiRuntime jeiRuntime) {
Collection<ItemStack> toRemove = new ArrayList<>();

// We use the internal API here as exception as debug tools are not part of the
// public one by design.
// We use the internal API here as exception as debug tools are not part of the public one by design.
toRemove.add(Api.INSTANCE.definitions().items().dummyFluidItem().maybeStack(1).orElse(null));

if (!AEConfig.instance().isFeatureEnabled(AEFeature.UNSUPPORTED_DEVELOPER_TOOLS)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

package appeng.integration.modules.jei;

import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.text.TranslationTextComponent;

import mezz.jei.api.constants.VanillaRecipeCategoryUid;
import mezz.jei.api.gui.IRecipeLayout;
Expand All @@ -41,11 +41,13 @@ protected IRecipeTransferError doTransferRecipe(PatternTermContainer container,
if (container.isCraftingMode()
&& recipeLayout.getRecipeCategory().getUid() != VanillaRecipeCategoryUid.CRAFTING) {
return this.helper
.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.requires_processing_mode"));
.createUserErrorWithTooltip(
new TranslationTextComponent("jei.appliedenergistics2.requires_processing_mode"));
}

if (recipe.getRecipeOutput().isEmpty()) {
return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.no_output"));
return this.helper
.createUserErrorWithTooltip(new TranslationTextComponent("jei.appliedenergistics2.no_output"));
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import java.util.Map;

import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.Container;
import net.minecraft.item.ItemStack;
Expand All @@ -30,10 +29,12 @@
import net.minecraft.item.crafting.ShapelessRecipe;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TranslationTextComponent;

import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiIngredient;
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
import mezz.jei.api.recipe.transfer.IRecipeTransferError.Type;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper;

Expand Down Expand Up @@ -67,47 +68,40 @@ public final IRecipeTransferError transferRecipe(T container, Object recipe, IRe
final ResourceLocation recipeId = irecipe.getId();

if (recipeId == null) {
return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.missing_id"));
return this.helper
.createUserErrorWithTooltip(new TranslationTextComponent("jei.appliedenergistics2.missing_id"));
}

// Check that the recipe can actually be looked up via the manager, i.e. our
// facade recipes
// have an ID, but are never registered with the recipe manager.
// Check that the recipe can actually be looked up via the manager, i.e. our facade recipes have an ID, but are
// never registered with the recipe manager.
boolean canSendReference = true;
if (!player.getEntityWorld().getRecipeManager().getRecipe(recipeId).isPresent()) {
// Validate that the recipe is a shapeless or shapedrecipe, since we can
// serialize those
// Validate that the recipe is a shapeless or shapedrecipe, since we can serialize those
if (!(recipe instanceof ShapedRecipe) && !(recipe instanceof ShapelessRecipe)) {
return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.missing_id"));
return this.helper
.createUserErrorWithTooltip(new TranslationTextComponent("jei.appliedenergistics2.missing_id"));
}
canSendReference = false;
}

if (!irecipe.canFit(3, 3)) {
return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.recipe_too_large"));
return this.helper.createUserErrorWithTooltip(
new TranslationTextComponent("jei.appliedenergistics2.recipe_too_large"));
}

final IRecipeTransferError error = doTransferRecipe(container, irecipe, recipeLayout, player, maxTransfer);

if (error != null) {
return error;
}

if (doTransfer) {
if (doTransfer && this.canTransfer(error)) {
if (canSendReference) {
NetworkHandler.instance().sendToServer(new JEIRecipePacket(recipeId, isCrafting()));
} else {
// To avoid earlier problems of too large packets being sent that crashed the
// client,
// as a fallback when the recipe ID could not be resolved, we'll just send the
// displayed
// items.
// To avoid earlier problems of too large packets being sent that crashed the client, as a fallback when
// the recipe ID could not be resolved, we'll just send the displayed items.
NonNullList<Ingredient> flatIngredients = NonNullList.withSize(9, Ingredient.EMPTY);
ItemStack output = ItemStack.EMPTY;

// Determine the first JEI slot that has an actual input, we'll use this to
// offset the
// crafting grid target slot
// Determine the first JEI slot that has an actual input, we'll use this to offset the crafting grid
// target slot
int firstInputSlot = recipeLayout.getItemStacks().getGuiIngredients().entrySet().stream()
.filter(e -> e.getValue().isInput()).mapToInt(Map.Entry::getKey).min().orElse(0);

Expand Down Expand Up @@ -135,11 +129,15 @@ public final IRecipeTransferError transferRecipe(T container, Object recipe, IRe
}
}

return null;
return error;
}

protected abstract IRecipeTransferError doTransferRecipe(T container, IRecipe<?> recipe, IRecipeLayout recipeLayout,
PlayerEntity player, boolean maxTransfer);

protected abstract boolean isCrafting();

private boolean canTransfer(IRecipeTransferError error) {
return error == null || error.getType() == Type.COSMETIC;
}
}
14 changes: 14 additions & 0 deletions src/main/resources/META-INF/mods.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,17 @@ description="A Mod about Matter, Energy and using them to conquer the world.."
versionRange="${minecraft_version}"
ordering="NONE"
side="BOTH"

[[dependencies.appliedenergistics2]]
modId="jei"
mandatory=false
versionRange="${jei_version}"
ordering="AFTER"
side="CLIENT"

[[dependencies.appliedenergistics2]]
modId="theoneprobe"
mandatory=false
versionRange="${top_version}"
ordering="AFTER"
side="BOTH"
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@
"jei.appliedenergistics2.recipe_too_large": "Recipe larger than 3x3",
"jei.appliedenergistics2.requires_processing_mode": "Requires processing mode",
"jei.appliedenergistics2.no_output": "Recipe has no output",
"jei.appliedenergistics2.missing_items": "Missing Items",
"jei.appliedenergistics2.missing_items": "Missing items will be skipped",
"gui.appliedenergistics2.ConfirmCraftCpuStatus": "Storage: %s : Co Processors: %s",
"gui.appliedenergistics2.ConfirmCraftNoCpu": "Storage: N/A : Co Processors: N/A"
}

0 comments on commit 12b3d2e

Please sign in to comment.