Rebuilt the recipe transfer after upstream changes.
This commit is contained in:
@@ -28,18 +28,18 @@ import com.mojang.datafixers.util.Pair;
|
|||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
|
||||||
import net.minecraft.inventory.container.Container;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import net.minecraft.item.crafting.IRecipeSerializer;
|
import net.minecraft.recipe.Ingredient;
|
||||||
import net.minecraft.item.crafting.Ingredient;
|
import net.minecraft.recipe.Recipe;
|
||||||
import net.minecraft.item.crafting.ShapedRecipe;
|
import net.minecraft.recipe.RecipeSerializer;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.recipe.ShapedRecipe;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.screen.ScreenHandler;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraftforge.common.crafting.IShapedRecipe;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraft.util.collection.DefaultedList;
|
||||||
|
|
||||||
|
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||||
|
|
||||||
import appeng.api.config.Actionable;
|
import appeng.api.config.Actionable;
|
||||||
import appeng.api.config.SecurityPermissions;
|
import appeng.api.config.SecurityPermissions;
|
||||||
@@ -59,9 +59,10 @@ import appeng.core.sync.BasePacketHandler;
|
|||||||
import appeng.core.sync.network.INetworkInfo;
|
import appeng.core.sync.network.INetworkInfo;
|
||||||
import appeng.helpers.IContainerCraftingPacket;
|
import appeng.helpers.IContainerCraftingPacket;
|
||||||
import appeng.items.storage.ViewCellItem;
|
import appeng.items.storage.ViewCellItem;
|
||||||
|
import appeng.mixins.IngredientAccessor;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
import appeng.util.helpers.ItemHandlerUtil;
|
import appeng.util.helpers.ItemHandlerUtil;
|
||||||
import appeng.util.inv.AdaptorItemHandler;
|
import appeng.util.inv.AdaptorFixedInv;
|
||||||
import appeng.util.inv.WrapperInvItemHandler;
|
import appeng.util.inv.WrapperInvItemHandler;
|
||||||
import appeng.util.item.AEItemStack;
|
import appeng.util.item.AEItemStack;
|
||||||
import appeng.util.prioritylist.IPartitionList;
|
import appeng.util.prioritylist.IPartitionList;
|
||||||
@@ -79,26 +80,26 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
*/
|
*/
|
||||||
private static final int INLINE_RECIPE_SHAPED = 2;
|
private static final int INLINE_RECIPE_SHAPED = 2;
|
||||||
|
|
||||||
private ResourceLocation recipeId;
|
private Identifier recipeId;
|
||||||
/**
|
/**
|
||||||
* This is optional, in case the client already knows it could not resolve the
|
* This is optional, in case the client already knows it could not resolve the
|
||||||
* recipe id.
|
* recipe id.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private IRecipe<?> recipe;
|
private Recipe<?> recipe;
|
||||||
private boolean crafting;
|
private boolean crafting;
|
||||||
|
|
||||||
public JEIRecipePacket(final PacketBuffer stream) {
|
public JEIRecipePacket(final PacketByteBuf stream) {
|
||||||
this.crafting = stream.readBoolean();
|
this.crafting = stream.readBoolean();
|
||||||
final String id = stream.readString(Short.MAX_VALUE);
|
final String id = stream.readString(Short.MAX_VALUE);
|
||||||
this.recipeId = new ResourceLocation(id);
|
this.recipeId = new Identifier(id);
|
||||||
|
|
||||||
int inlineRecipeType = stream.readVarInt();
|
int inlineRecipeType = stream.readVarInt();
|
||||||
switch (inlineRecipeType) {
|
switch (inlineRecipeType) {
|
||||||
case INLINE_RECIPE_NONE:
|
case INLINE_RECIPE_NONE:
|
||||||
break;
|
break;
|
||||||
case INLINE_RECIPE_SHAPED:
|
case INLINE_RECIPE_SHAPED:
|
||||||
recipe = IRecipeSerializer.CRAFTING_SHAPED.read(this.recipeId, stream);
|
recipe = RecipeSerializer.SHAPED.read(this.recipeId, stream);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Invalid inline recipe type.");
|
throw new IllegalArgumentException("Invalid inline recipe type.");
|
||||||
@@ -109,8 +110,8 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
* Sends a recipe identified by the given recipe ID to the server for either
|
* Sends a recipe identified by the given recipe ID to the server for either
|
||||||
* filling a crafting grid or a pattern.
|
* filling a crafting grid or a pattern.
|
||||||
*/
|
*/
|
||||||
public JEIRecipePacket(final ResourceLocation recipeId, final boolean crafting) {
|
public JEIRecipePacket(final Identifier recipeId, final boolean crafting) {
|
||||||
PacketBuffer data = createCommonHeader(recipeId, crafting, INLINE_RECIPE_NONE);
|
PacketByteBuf data = createCommonHeader(recipeId, crafting, INLINE_RECIPE_NONE);
|
||||||
this.configureWrite(data);
|
this.configureWrite(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,17 +121,17 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
* Prefer the id-based constructor above whereever possible.
|
* Prefer the id-based constructor above whereever possible.
|
||||||
*/
|
*/
|
||||||
public JEIRecipePacket(final ShapedRecipe recipe, final boolean crafting) {
|
public JEIRecipePacket(final ShapedRecipe recipe, final boolean crafting) {
|
||||||
PacketBuffer data = createCommonHeader(recipe.getId(), crafting, INLINE_RECIPE_SHAPED);
|
PacketByteBuf data = createCommonHeader(recipe.getId(), crafting, INLINE_RECIPE_SHAPED);
|
||||||
IRecipeSerializer.CRAFTING_SHAPED.write(data, recipe);
|
RecipeSerializer.SHAPED.write(data, recipe);
|
||||||
this.configureWrite(data);
|
this.configureWrite(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PacketBuffer createCommonHeader(ResourceLocation recipeId, boolean crafting, int inlineRecipeType) {
|
private PacketByteBuf createCommonHeader(Identifier recipeId, boolean crafting, int inlineRecipeType) {
|
||||||
final PacketBuffer data = new PacketBuffer(Unpooled.buffer());
|
final PacketByteBuf data = new PacketByteBuf(Unpooled.buffer());
|
||||||
|
|
||||||
data.writeInt(this.getPacketID());
|
data.writeInt(this.getPacketID());
|
||||||
data.writeBoolean(crafting);
|
data.writeBoolean(crafting);
|
||||||
data.writeResourceLocation(recipeId);
|
data.writeIdentifier(recipeId);
|
||||||
data.writeVarInt(inlineRecipeType);
|
data.writeVarInt(inlineRecipeType);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@@ -147,10 +148,10 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
public void serverPacketData(final INetworkInfo manager, final PlayerEntity player) {
|
public void serverPacketData(final INetworkInfo manager, final PlayerEntity player) {
|
||||||
// Setup and verification
|
// Setup and verification
|
||||||
final ServerPlayerEntity pmp = (ServerPlayerEntity) player;
|
final ServerPlayerEntity pmp = (ServerPlayerEntity) player;
|
||||||
final Container con = pmp.openContainer;
|
final ScreenHandler con = pmp.currentScreenHandler;
|
||||||
Preconditions.checkArgument(con instanceof IContainerCraftingPacket);
|
Preconditions.checkArgument(con instanceof IContainerCraftingPacket);
|
||||||
|
|
||||||
IRecipe<?> recipe = player.getEntityWorld().getRecipeManager().getRecipe(this.recipeId).orElse(null);
|
Recipe<?> recipe = player.getEntityWorld().getRecipeManager().get(this.recipeId).orElse(null);
|
||||||
if (recipe == null && this.recipe != null) {
|
if (recipe == null && this.recipe != null) {
|
||||||
// Certain recipes (i.e. AE2 facades) are represented in JEI as ShapedRecipe's,
|
// Certain recipes (i.e. AE2 facades) are represented in JEI as ShapedRecipe's,
|
||||||
// while in reality they
|
// while in reality they
|
||||||
@@ -175,17 +176,17 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
|
|
||||||
final IEnergyGrid energy = grid.getCache(IEnergyGrid.class);
|
final IEnergyGrid energy = grid.getCache(IEnergyGrid.class);
|
||||||
final ICraftingGrid crafting = grid.getCache(ICraftingGrid.class);
|
final ICraftingGrid crafting = grid.getCache(ICraftingGrid.class);
|
||||||
final IItemHandler craftMatrix = cct.getInventoryByName("crafting");
|
final FixedItemInv craftMatrix = cct.getInventoryByName("crafting");
|
||||||
final IItemHandler playerInventory = cct.getInventoryByName("player");
|
final FixedItemInv playerInventory = cct.getInventoryByName("player");
|
||||||
|
|
||||||
final IMEMonitor<IAEItemStack> storage = inv
|
final IMEMonitor<IAEItemStack> storage = inv
|
||||||
.getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
.getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
||||||
final IPartitionList<IAEItemStack> filter = ViewCellItem.createFilter(cct.getViewCells());
|
final IPartitionList<IAEItemStack> filter = ViewCellItem.createFilter(cct.getViewCells());
|
||||||
final NonNullList<Ingredient> ingredients = this.ensure3by3CraftingMatrix(recipe);
|
final DefaultedList<Ingredient> ingredients = this.ensure3by3CraftingMatrix(recipe);
|
||||||
|
|
||||||
// Handle each slot
|
// Handle each slot
|
||||||
for (int x = 0; x < craftMatrix.getSlots(); x++) {
|
for (int x = 0; x < craftMatrix.getSlotCount(); x++) {
|
||||||
ItemStack currentItem = craftMatrix.getStackInSlot(x);
|
ItemStack currentItem = craftMatrix.getInvStack(x);
|
||||||
Ingredient ingredient = ingredients.get(x);
|
Ingredient ingredient = ingredients.get(x);
|
||||||
|
|
||||||
// prepare slots
|
// prepare slots
|
||||||
@@ -222,8 +223,8 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
if (out == null) {
|
if (out == null) {
|
||||||
out = findBestMatchingItemStack(ingredient, filter, storage, cct);
|
out = findBestMatchingItemStack(ingredient, filter, storage, cct);
|
||||||
}
|
}
|
||||||
if (out == null && ingredient.getMatchingStacks().length > 0) {
|
if (out == null && getMatchingStacks(ingredient).length > 0) {
|
||||||
out = AEItemStack.fromItemStack(ingredient.getMatchingStacks()[0]);
|
out = AEItemStack.fromItemStack(getMatchingStacks(ingredient)[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,10 +235,10 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
|
|
||||||
// If still nothing, search the player inventory.
|
// If still nothing, search the player inventory.
|
||||||
if (currentItem.isEmpty()) {
|
if (currentItem.isEmpty()) {
|
||||||
ItemStack[] matchingStacks = ingredient.getMatchingStacks();
|
ItemStack[] matchingStacks = getMatchingStacks(ingredient);
|
||||||
for (ItemStack matchingStack : matchingStacks) {
|
for (ItemStack matchingStack : matchingStacks) {
|
||||||
if (currentItem.isEmpty()) {
|
if (currentItem.isEmpty()) {
|
||||||
AdaptorItemHandler ad = new AdaptorItemHandler(playerInventory);
|
AdaptorFixedInv ad = new AdaptorFixedInv(playerInventory);
|
||||||
|
|
||||||
if (cct.useRealItems()) {
|
if (cct.useRealItems()) {
|
||||||
currentItem = ad.removeItems(1, matchingStack, null);
|
currentItem = ad.removeItems(1, matchingStack, null);
|
||||||
@@ -254,7 +255,21 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
this.handleProcessing(con, cct, recipe);
|
this.handleProcessing(con, cct, recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
con.onCraftMatrixChanged(new WrapperInvItemHandler(craftMatrix));
|
con.onContentChanged(new WrapperInvItemHandler(craftMatrix));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
private static ItemStack[] getMatchingStacks(Ingredient ingredient) {
|
||||||
|
IngredientAccessor accessor = (IngredientAccessor) (Object) ingredient;
|
||||||
|
// accessor.callCacheMatchingStacks();
|
||||||
|
if (ingredient.isEmpty()) {
|
||||||
|
return new ItemStack[0];
|
||||||
|
}
|
||||||
|
ItemStack[] stacks = accessor.getMatchingStacks();
|
||||||
|
if (stacks.length == 1 && stacks[0].isEmpty()) {
|
||||||
|
return new ItemStack[0];
|
||||||
|
}
|
||||||
|
return stacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,18 +278,18 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
* Will throw an {@link IllegalArgumentException} in case it has more than 9 or
|
* Will throw an {@link IllegalArgumentException} in case it has more than 9 or
|
||||||
* a shaped recipe is either wider or higher than 3. ingredients.
|
* a shaped recipe is either wider or higher than 3. ingredients.
|
||||||
*/
|
*/
|
||||||
private NonNullList<Ingredient> ensure3by3CraftingMatrix(IRecipe<?> recipe) {
|
private DefaultedList<Ingredient> ensure3by3CraftingMatrix(Recipe<?> recipe) {
|
||||||
NonNullList<Ingredient> ingredients = recipe.getIngredients();
|
DefaultedList<Ingredient> ingredients = recipe.getPreviewInputs();
|
||||||
NonNullList<Ingredient> expandedIngredients = NonNullList.withSize(9, Ingredient.EMPTY);
|
DefaultedList<Ingredient> expandedIngredients = DefaultedList.ofSize(9, Ingredient.EMPTY);
|
||||||
|
|
||||||
Preconditions.checkArgument(ingredients.size() <= 9);
|
Preconditions.checkArgument(ingredients.size() <= 9);
|
||||||
|
|
||||||
// shaped recipes can be smaller than 3x3, expand to 3x3 to match the crafting
|
// shaped recipes can be smaller than 3x3, expand to 3x3 to match the crafting
|
||||||
// matrix
|
// matrix
|
||||||
if (recipe instanceof IShapedRecipe) {
|
if (recipe instanceof ShapedRecipe) {
|
||||||
IShapedRecipe<?> shapedRecipe = (IShapedRecipe<?>) recipe;
|
ShapedRecipe shapedRecipe = (ShapedRecipe) recipe;
|
||||||
int width = shapedRecipe.getRecipeWidth();
|
int width = shapedRecipe.getWidth();
|
||||||
int height = shapedRecipe.getRecipeHeight();
|
int height = shapedRecipe.getHeight();
|
||||||
Preconditions.checkArgument(width <= 3 && height <= 3);
|
Preconditions.checkArgument(width <= 3 && height <= 3);
|
||||||
|
|
||||||
for (int h = 0; h < height; h++) {
|
for (int h = 0; h < height; h++) {
|
||||||
@@ -301,7 +316,7 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
* @return is if it can be used, else EMPTY
|
* @return is if it can be used, else EMPTY
|
||||||
*/
|
*/
|
||||||
private ItemStack canUseInSlot(Ingredient ingredient, ItemStack is) {
|
private ItemStack canUseInSlot(Ingredient ingredient, ItemStack is) {
|
||||||
return Arrays.stream(ingredient.getMatchingStacks()).filter(p -> p.isItemEqual(is)).findFirst()
|
return Arrays.stream(getMatchingStacks(ingredient)).filter(p -> p.isItemEqual(is)).findFirst()
|
||||||
.orElse(ItemStack.EMPTY);
|
.orElse(ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +325,7 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
*/
|
*/
|
||||||
private IAEItemStack findBestMatchingItemStack(Ingredient ingredients, IPartitionList<IAEItemStack> filter,
|
private IAEItemStack findBestMatchingItemStack(Ingredient ingredients, IPartitionList<IAEItemStack> filter,
|
||||||
IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) {
|
IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) {
|
||||||
return Arrays.stream(ingredients.getMatchingStacks()).map(AEItemStack::fromItemStack) //
|
return Arrays.stream(getMatchingStacks(ingredients)).map(AEItemStack::fromItemStack) //
|
||||||
.filter(r -> r != null && (filter == null || filter.isListed(r))) //
|
.filter(r -> r != null && (filter == null || filter.isListed(r))) //
|
||||||
.map(s -> {
|
.map(s -> {
|
||||||
// Determine the stored count
|
// Determine the stored count
|
||||||
@@ -329,7 +344,7 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
*/
|
*/
|
||||||
private IAEItemStack findBestMatchingPattern(Ingredient ingredients, IPartitionList<IAEItemStack> filter,
|
private IAEItemStack findBestMatchingPattern(Ingredient ingredients, IPartitionList<IAEItemStack> filter,
|
||||||
ICraftingGrid crafting, IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) {
|
ICraftingGrid crafting, IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) {
|
||||||
return Arrays.stream(ingredients.getMatchingStacks()).map(AEItemStack::fromItemStack)
|
return Arrays.stream(getMatchingStacks(ingredients)).map(AEItemStack::fromItemStack)
|
||||||
.filter(r -> r != null && (filter == null || filter.isListed(r)))
|
.filter(r -> r != null && (filter == null || filter.isListed(r)))
|
||||||
.map(s -> s.setCraftable(!crafting.getCraftingFor(s, null, 0, null).isEmpty()))
|
.map(s -> s.setCraftable(!crafting.getCraftingFor(s, null, 0, null).isEmpty()))
|
||||||
.filter(IAEItemStack::isCraftable).map(s -> {
|
.filter(IAEItemStack::isCraftable).map(s -> {
|
||||||
@@ -341,12 +356,12 @@ public class JEIRecipePacket extends BasePacket {
|
|||||||
}).orElse(null);
|
}).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleProcessing(Container con, IContainerCraftingPacket cct, IRecipe<?> recipe) {
|
private void handleProcessing(ScreenHandler con, IContainerCraftingPacket cct, Recipe<?> recipe) {
|
||||||
if (con instanceof PatternTermContainer) {
|
if (con instanceof PatternTermContainer) {
|
||||||
PatternTermContainer patternTerm = (PatternTermContainer) con;
|
PatternTermContainer patternTerm = (PatternTermContainer) con;
|
||||||
if (!patternTerm.craftingMode) {
|
if (!patternTerm.craftingMode) {
|
||||||
final IItemHandler output = cct.getInventoryByName("output");
|
final FixedItemInv output = cct.getInventoryByName("output");
|
||||||
ItemHandlerUtil.setStackInSlot(output, 0, recipe.getRecipeOutput());
|
ItemHandlerUtil.setStackInSlot(output, 0, recipe.getOutput());
|
||||||
ItemHandlerUtil.setStackInSlot(output, 1, ItemStack.EMPTY);
|
ItemHandlerUtil.setStackInSlot(output, 1, ItemStack.EMPTY);
|
||||||
ItemHandlerUtil.setStackInSlot(output, 2, ItemStack.EMPTY);
|
ItemHandlerUtil.setStackInSlot(output, 2, ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
package appeng.integration.abstraction;
|
package appeng.integration.abstraction;
|
||||||
|
|
||||||
import mezz.jei.api.runtime.IJeiRuntime;
|
|
||||||
|
|
||||||
import appeng.integration.IIntegrationModule;
|
import appeng.integration.IIntegrationModule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,10 +25,6 @@ import appeng.integration.IIntegrationModule;
|
|||||||
*/
|
*/
|
||||||
public interface IRei extends IIntegrationModule {
|
public interface IRei extends IIntegrationModule {
|
||||||
|
|
||||||
default IJeiRuntime getRuntime() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getSearchText() {
|
default String getSearchText() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,24 +18,21 @@
|
|||||||
|
|
||||||
package appeng.integration.modules.jei;
|
package appeng.integration.modules.jei;
|
||||||
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import me.shedaniel.rei.api.AutoTransferHandler;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import me.shedaniel.rei.api.RecipeDisplay;
|
||||||
|
import me.shedaniel.rei.api.TransferRecipeDisplay;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
|
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper;
|
|
||||||
|
|
||||||
import appeng.container.implementations.CraftingTermContainer;
|
import appeng.container.implementations.CraftingTermContainer;
|
||||||
|
|
||||||
public class CraftingRecipeTransferHandler extends RecipeTransferHandler<CraftingTermContainer> {
|
public class CraftingRecipeTransferHandler extends RecipeTransferHandler<CraftingTermContainer> {
|
||||||
|
|
||||||
CraftingRecipeTransferHandler(Class<CraftingTermContainer> containerClass, IRecipeTransferHandlerHelper helper) {
|
public CraftingRecipeTransferHandler(Class<CraftingTermContainer> containerClass) {
|
||||||
super(containerClass, helper);
|
super(containerClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IRecipeTransferError doTransferRecipe(CraftingTermContainer container, IRecipe<?> recipe,
|
protected AutoTransferHandler.Result doTransferRecipe(CraftingTermContainer container, RecipeDisplay recipe,
|
||||||
IRecipeLayout recipeLayout, PlayerEntity player, boolean maxTransfer) {
|
AutoTransferHandler.Context context) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ class FacadeRegistryGenerator implements LiveRecipeGenerator<DefaultShapedDispla
|
|||||||
ingredients.set(7, Ingredient.ofStacks(cableAnchor));
|
ingredients.set(7, Ingredient.ofStacks(cableAnchor));
|
||||||
ingredients.set(4, Ingredient.ofStacks(textureItem));
|
ingredients.set(4, Ingredient.ofStacks(textureItem));
|
||||||
|
|
||||||
|
result.setCount(4);
|
||||||
|
|
||||||
return new DefaultShapedDisplay(new ShapedRecipe(id, "", 3, 3, ingredients, result));
|
return new DefaultShapedDisplay(new ShapedRecipe(id, "", 3, 3, ingredients, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,33 +18,28 @@
|
|||||||
|
|
||||||
package appeng.integration.modules.jei;
|
package appeng.integration.modules.jei;
|
||||||
|
|
||||||
import net.minecraft.client.resources.I18n;
|
import me.shedaniel.rei.api.AutoTransferHandler;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import me.shedaniel.rei.api.RecipeDisplay;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import me.shedaniel.rei.api.TransferRecipeDisplay;
|
||||||
|
import me.shedaniel.rei.plugin.DefaultPlugin;
|
||||||
import mezz.jei.api.constants.VanillaRecipeCategoryUid;
|
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
|
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper;
|
|
||||||
|
|
||||||
import appeng.container.implementations.PatternTermContainer;
|
import appeng.container.implementations.PatternTermContainer;
|
||||||
|
|
||||||
public class PatternRecipeTransferHandler extends RecipeTransferHandler<PatternTermContainer> {
|
public class PatternRecipeTransferHandler extends RecipeTransferHandler<PatternTermContainer> {
|
||||||
|
|
||||||
PatternRecipeTransferHandler(Class<PatternTermContainer> containerClass, IRecipeTransferHandlerHelper helper) {
|
PatternRecipeTransferHandler(Class<PatternTermContainer> containerClass) {
|
||||||
super(containerClass, helper);
|
super(containerClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IRecipeTransferError doTransferRecipe(PatternTermContainer container, IRecipe<?> recipe,
|
protected AutoTransferHandler.Result doTransferRecipe(PatternTermContainer container, RecipeDisplay recipe,
|
||||||
IRecipeLayout recipeLayout, PlayerEntity player, boolean maxTransfer) {
|
AutoTransferHandler.Context context) {
|
||||||
if (container.isCraftingMode()
|
|
||||||
&& recipeLayout.getRecipeCategory().getUid() != VanillaRecipeCategoryUid.CRAFTING) {
|
if (container.isCraftingMode() && recipe.getRecipeCategory() != DefaultPlugin.CRAFTING) {
|
||||||
return this.helper
|
return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.requires_processing_mode");
|
||||||
.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.requires_processing_mode"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recipe.getRecipeOutput().isEmpty()) {
|
if (recipe.getResultingEntries().isEmpty()) {
|
||||||
return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.no_output"));
|
return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.no_output");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -18,82 +18,70 @@
|
|||||||
|
|
||||||
package appeng.integration.modules.jei;
|
package appeng.integration.modules.jei;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import net.minecraft.client.resources.I18n;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.inventory.container.Container;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.crafting.IRecipe;
|
import net.minecraft.recipe.Ingredient;
|
||||||
import net.minecraft.item.crafting.Ingredient;
|
import net.minecraft.recipe.ShapedRecipe;
|
||||||
import net.minecraft.item.crafting.ShapedRecipe;
|
import net.minecraft.screen.ScreenHandler;
|
||||||
import net.minecraft.item.crafting.ShapelessRecipe;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.NonNullList;
|
import net.minecraft.util.collection.DefaultedList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
|
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import me.shedaniel.rei.api.AutoTransferHandler;
|
||||||
import mezz.jei.api.gui.ingredient.IGuiIngredient;
|
import me.shedaniel.rei.api.EntryStack;
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
|
import me.shedaniel.rei.api.RecipeDisplay;
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
|
import me.shedaniel.rei.api.TransferRecipeDisplay;
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper;
|
|
||||||
|
|
||||||
import appeng.core.sync.network.NetworkHandler;
|
import appeng.core.sync.network.NetworkHandler;
|
||||||
import appeng.core.sync.packets.JEIRecipePacket;
|
import appeng.core.sync.packets.JEIRecipePacket;
|
||||||
import appeng.helpers.IContainerCraftingPacket;
|
import appeng.helpers.IContainerCraftingPacket;
|
||||||
|
|
||||||
abstract class RecipeTransferHandler<T extends Container & IContainerCraftingPacket>
|
abstract class RecipeTransferHandler<T extends ScreenHandler & IContainerCraftingPacket>
|
||||||
implements IRecipeTransferHandler<T> {
|
implements AutoTransferHandler {
|
||||||
|
|
||||||
private final Class<T> containerClass;
|
private final Class<T> containerClass;
|
||||||
protected final IRecipeTransferHandlerHelper helper;
|
|
||||||
|
|
||||||
RecipeTransferHandler(Class<T> containerClass, IRecipeTransferHandlerHelper helper) {
|
RecipeTransferHandler(Class<T> containerClass) {
|
||||||
this.containerClass = containerClass;
|
this.containerClass = containerClass;
|
||||||
this.helper = helper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Class<T> getContainerClass() {
|
public AutoTransferHandler.Result handle(AutoTransferHandler.Context context) {
|
||||||
return this.containerClass;
|
RecipeDisplay recipe = context.getRecipe();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (!containerClass.isInstance(context.getContainerScreen().getScreenHandler())) {
|
||||||
public final IRecipeTransferError transferRecipe(T container, Object recipe, IRecipeLayout recipeLayout,
|
return AutoTransferHandler.Result.createNotApplicable();
|
||||||
PlayerEntity player, boolean maxTransfer, boolean doTransfer) {
|
|
||||||
if (!(recipe instanceof IRecipe)) {
|
|
||||||
return this.helper.createInternalError();
|
|
||||||
}
|
}
|
||||||
final IRecipe<?> irecipe = (IRecipe<?>) recipe;
|
|
||||||
final ResourceLocation recipeId = irecipe.getId();
|
|
||||||
|
|
||||||
if (recipeId == null) {
|
T container = containerClass.cast(context.getContainerScreen().getScreenHandler());
|
||||||
return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.missing_id"));
|
|
||||||
}
|
final Identifier recipeId = recipe.getRecipeLocation().orElse(null);
|
||||||
|
|
||||||
// Check that the recipe can actually be looked up via the manager, i.e. our
|
// Check that the recipe can actually be looked up via the manager, i.e. our
|
||||||
// facade recipes
|
// facade recipes
|
||||||
// have an ID, but are never registered with the recipe manager.
|
// have an ID, but are never registered with the recipe manager.
|
||||||
boolean canSendReference = true;
|
boolean canSendReference = true;
|
||||||
if (!player.getEntityWorld().getRecipeManager().getRecipe(recipeId).isPresent()) {
|
if (recipeId == null || !context.getMinecraft().world.getRecipeManager().get(recipeId).isPresent()) {
|
||||||
// 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"));
|
|
||||||
}
|
|
||||||
canSendReference = false;
|
canSendReference = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!irecipe.canFit(3, 3)) {
|
if (recipe instanceof TransferRecipeDisplay) {
|
||||||
return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.recipe_too_large"));
|
TransferRecipeDisplay trd = (TransferRecipeDisplay) recipe;
|
||||||
|
if (trd.getWidth() > 3 || trd.getHeight() > 3) {
|
||||||
|
return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.recipe_too_large");
|
||||||
|
}
|
||||||
|
} else if (recipe.getInputEntries().size() > 9) {
|
||||||
|
return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.recipe_too_large");
|
||||||
}
|
}
|
||||||
|
|
||||||
final IRecipeTransferError error = doTransferRecipe(container, irecipe, recipeLayout, player, maxTransfer);
|
final AutoTransferHandler.Result error = doTransferRecipe(container, recipe, context);
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doTransfer) {
|
if (context.isActuallyCrafting()) {
|
||||||
if (canSendReference) {
|
if (canSendReference) {
|
||||||
NetworkHandler.instance().sendToServer(new JEIRecipePacket(recipeId, isCrafting()));
|
NetworkHandler.instance().sendToServer(new JEIRecipePacket(recipeId, isCrafting()));
|
||||||
} else {
|
} else {
|
||||||
@@ -102,31 +90,29 @@ abstract class RecipeTransferHandler<T extends Container & IContainerCraftingPac
|
|||||||
// as a fallback when the recipe ID could not be resolved, we'll just send the
|
// as a fallback when the recipe ID could not be resolved, we'll just send the
|
||||||
// displayed
|
// displayed
|
||||||
// items.
|
// items.
|
||||||
NonNullList<Ingredient> flatIngredients = NonNullList.withSize(9, Ingredient.EMPTY);
|
DefaultedList<Ingredient> flatIngredients = DefaultedList.ofSize(9, Ingredient.EMPTY);
|
||||||
ItemStack output = ItemStack.EMPTY;
|
ItemStack output = null;
|
||||||
|
for (EntryStack entryStack : recipe.getResultingEntries().get(0)) {
|
||||||
// Determine the first JEI slot that has an actual input, we'll use this to
|
if (entryStack.getType() == EntryStack.Type.ITEM) {
|
||||||
// offset the
|
output = entryStack.getItemStack();
|
||||||
// crafting grid target slot
|
}
|
||||||
int firstInputSlot = recipeLayout.getItemStacks().getGuiIngredients().entrySet().stream()
|
}
|
||||||
.filter(e -> e.getValue().isInput()).mapToInt(Map.Entry::getKey).min().orElse(0);
|
if (output == null || output.isEmpty()) {
|
||||||
|
return AutoTransferHandler.Result.createFailed("jei.appliedenergistics2.no_output");
|
||||||
|
}
|
||||||
|
|
||||||
// Now map the actual ingredients into the output/input
|
// Now map the actual ingredients into the output/input
|
||||||
for (Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> entry : recipeLayout.getItemStacks()
|
for (int i = 0; i < recipe.getInputEntries().size(); i++) {
|
||||||
.getGuiIngredients().entrySet()) {
|
List<EntryStack> inputEntry = recipe.getInputEntries().get(i);
|
||||||
IGuiIngredient<ItemStack> item = entry.getValue();
|
if (inputEntry.isEmpty()) {
|
||||||
if (item.getDisplayedIngredient() == null) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
EntryStack first = inputEntry.get(0);
|
||||||
int inputIndex = entry.getKey() - firstInputSlot;
|
if (i < flatIngredients.size()) {
|
||||||
if (item.isInput() && inputIndex < flatIngredients.size()) {
|
ItemStack displayedIngredient = first.getItemStack();
|
||||||
ItemStack displayedIngredient = item.getDisplayedIngredient();
|
|
||||||
if (displayedIngredient != null) {
|
if (displayedIngredient != null) {
|
||||||
flatIngredients.set(inputIndex, Ingredient.fromStacks(displayedIngredient));
|
flatIngredients.set(i, Ingredient.method_26964(Stream.of(displayedIngredient)));
|
||||||
}
|
}
|
||||||
} else if (!item.isInput() && output.isEmpty()) {
|
|
||||||
output = item.getDisplayedIngredient();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,11 +121,11 @@ abstract class RecipeTransferHandler<T extends Container & IContainerCraftingPac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return Result.createSuccessful().blocksFurtherHandling();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IRecipeTransferError doTransferRecipe(T container, IRecipe<?> recipe, IRecipeLayout recipeLayout,
|
protected abstract AutoTransferHandler.Result doTransferRecipe(T container, RecipeDisplay recipe,
|
||||||
PlayerEntity player, boolean maxTransfer);
|
AutoTransferHandler.Context context);
|
||||||
|
|
||||||
protected abstract boolean isCrafting();
|
protected abstract boolean isCrafting();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import net.minecraft.item.ItemStack;
|
|||||||
import net.minecraft.text.TranslatableText;
|
import net.minecraft.text.TranslatableText;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import me.shedaniel.math.Rectangle;
|
|
||||||
import me.shedaniel.rei.api.BaseBoundsHandler;
|
import me.shedaniel.rei.api.BaseBoundsHandler;
|
||||||
import me.shedaniel.rei.api.DisplayHelper;
|
import me.shedaniel.rei.api.DisplayHelper;
|
||||||
import me.shedaniel.rei.api.EntryRegistry;
|
import me.shedaniel.rei.api.EntryRegistry;
|
||||||
@@ -124,8 +123,8 @@ public class ReiPlugin implements REIPluginV0 {
|
|||||||
@Override
|
@Override
|
||||||
public void registerOthers(RecipeHelper recipeHelper) {
|
public void registerOthers(RecipeHelper recipeHelper) {
|
||||||
// Allow recipe transfer from JEI to crafting and pattern terminal
|
// Allow recipe transfer from JEI to crafting and pattern terminal
|
||||||
recipeHelper.registerAutoCraftingHandler(new RecipeTransferHandler<>(CraftingTermContainer.class));
|
recipeHelper.registerAutoCraftingHandler(new CraftingRecipeTransferHandler(CraftingTermContainer.class));
|
||||||
recipeHelper.registerAutoCraftingHandler(new RecipeTransferHandler<>(PatternTermContainer.class));
|
recipeHelper.registerAutoCraftingHandler(new PatternRecipeTransferHandler(PatternTermContainer.class));
|
||||||
|
|
||||||
recipeHelper.removeAutoCraftButton(GrinderRecipeCategory.UID);
|
recipeHelper.removeAutoCraftButton(GrinderRecipeCategory.UID);
|
||||||
recipeHelper.removeAutoCraftButton(InscriberRecipeCategory.UID);
|
recipeHelper.removeAutoCraftButton(InscriberRecipeCategory.UID);
|
||||||
@@ -227,7 +226,7 @@ public class ReiPlugin implements REIPluginV0 {
|
|||||||
ItemStack stack = entryStack.getItemStack();
|
ItemStack stack = entryStack.getItemStack();
|
||||||
|
|
||||||
if (items.dummyFluidItem().isSameAs(stack) || items.facade().isSameAs(stack) // REI will add a broken facade
|
if (items.dummyFluidItem().isSameAs(stack) || items.facade().isSameAs(stack) // REI will add a broken facade
|
||||||
// with no NBT
|
// with no NBT
|
||||||
|| blocks.multiPart().isSameAs(stack) || blocks.matrixFrame().isSameAs(stack)
|
|| blocks.multiPart().isSameAs(stack) || blocks.matrixFrame().isSameAs(stack)
|
||||||
|| blocks.paint().isSameAs(stack)) {
|
|| blocks.paint().isSameAs(stack)) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -39,10 +39,6 @@ class ReiRuntimeAdapter implements IRei {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IJeiRuntime getRuntime() {
|
|
||||||
return runtime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSearchText() {
|
public String getSearchText() {
|
||||||
TextFieldWidget searchField = this.runtime.getSearchTextField();
|
TextFieldWidget searchField = this.runtime.getSearchTextField();
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package appeng.mixins;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.recipe.Ingredient;
|
||||||
|
|
||||||
|
@Mixin(Ingredient.class)
|
||||||
|
public interface IngredientAccessor {
|
||||||
|
|
||||||
|
@Invoker
|
||||||
|
void callCacheMatchingStacks();
|
||||||
|
|
||||||
|
@Accessor
|
||||||
|
ItemStack[] getMatchingStacks();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -291,7 +291,7 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
|
|||||||
|
|
||||||
// Replace it if there is a custom entity
|
// Replace it if there is a custom entity
|
||||||
if (is.getItem() instanceof AECustomEntityItem) {
|
if (is.getItem() instanceof AECustomEntityItem) {
|
||||||
Entity result = ((AECustomEntityItem) is.getItem()).replaceItemEntity(w, entity, is);
|
Entity result = ((AECustomEntityItem) is.getItem()).replaceItemEntity(w, (ItemEntity) entity, is);
|
||||||
// Destroy the old one, in case it's spawned somehow and replace with the new
|
// Destroy the old one, in case it's spawned somehow and replace with the new
|
||||||
// one.
|
// one.
|
||||||
if (result != entity) {
|
if (result != entity) {
|
||||||
@@ -300,16 +300,6 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is.getItem().hasCustomEntity(is)) {
|
|
||||||
Entity result = is.getItem().createEntity(w, entity, is);
|
|
||||||
// Destroy the old one, in case it's spawned somehow and replace with the new
|
|
||||||
// one.
|
|
||||||
if (result != null) {
|
|
||||||
entity.remove();
|
|
||||||
entity = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// When spawning downwards, we have to take into account that it spawns it at
|
// When spawning downwards, we have to take into account that it spawns it at
|
||||||
// their "feet" and not center like x or z. So we move it up to be flush with
|
// their "feet" and not center like x or z. So we move it up to be flush with
|
||||||
// the plane
|
// the plane
|
||||||
@@ -340,7 +330,7 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
|
|||||||
final double absoluteZ = centerZ + offsetZ;
|
final double absoluteZ = centerZ + offsetZ;
|
||||||
|
|
||||||
// Set to correct position and slow the motion down a bit
|
// Set to correct position and slow the motion down a bit
|
||||||
entity.setPosition(absoluteX, absoluteY, absoluteZ);
|
entity.setPos(absoluteX, absoluteY, absoluteZ);
|
||||||
entity.setVelocity(side.xOffset * .1, side.yOffset * 0.1, side.zOffset * 0.1);
|
entity.setVelocity(side.xOffset * .1, side.yOffset * 0.1, side.zOffset * 0.1);
|
||||||
|
|
||||||
// Try to spawn it and destroy it in case it's not possible
|
// Try to spawn it and destroy it in case it's not possible
|
||||||
|
|||||||
@@ -25,7 +25,8 @@
|
|||||||
"TntAccessor",
|
"TntAccessor",
|
||||||
"ServerWorldCustomItemEntityMixin",
|
"ServerWorldCustomItemEntityMixin",
|
||||||
"BootstrapMixin",
|
"BootstrapMixin",
|
||||||
"ItemEntityAccessor"
|
"ItemEntityAccessor",
|
||||||
|
"IngredientAccessor"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"spatial.SkyRenderMixin",
|
"spatial.SkyRenderMixin",
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
"gui.appliedenergistics2.Gray": "Grey",
|
"gui.appliedenergistics2.Gray": "Grey",
|
||||||
"gui.appliedenergistics2.LightGray": "Light Grey",
|
"gui.appliedenergistics2.LightGray": "Light Grey",
|
||||||
"gui.appliedenergistics2.inWorldCraftingPresses": "Crafting Presses are found in the centre of meteorites which can be found in around the world, they can be located by using a meteorite compass.",
|
"gui.appliedenergistics2.inWorldCraftingPresses": "Crafting Presses are found in the centre of meteorites which can be found in around the world, they can be located by using a meteorite compass.",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_JEIAuto": "JEI Synchronised Auto",
|
"gui.tooltips.appliedenergistics2.SearchMode_JEIAuto": "REI Synchronised Auto",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandard": "JEI Synchronised Standard",
|
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandard": "REI Synchronised Standard",
|
||||||
"gui.tooltips.appliedenergistics2.TerminalStyle_Small": "Small Centered Terminal",
|
"gui.tooltips.appliedenergistics2.TerminalStyle_Small": "Small Centered Terminal",
|
||||||
"gui.tooltips.appliedenergistics2.TerminalStyle_Tall": "Tall Centered Terminal",
|
"gui.tooltips.appliedenergistics2.TerminalStyle_Tall": "Tall Centered Terminal",
|
||||||
"item.appliedenergistics2.color_applicator": "Colour Applicator"
|
"item.appliedenergistics2.color_applicator": "Colour Applicator"
|
||||||
|
|||||||
@@ -380,10 +380,10 @@
|
|||||||
"gui.tooltips.appliedenergistics2.SearchMode": "Search Box Mode",
|
"gui.tooltips.appliedenergistics2.SearchMode": "Search Box Mode",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_Auto": "Auto Search",
|
"gui.tooltips.appliedenergistics2.SearchMode_Auto": "Auto Search",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_AutoKeep": "Auto Search Keep",
|
"gui.tooltips.appliedenergistics2.SearchMode_AutoKeep": "Auto Search Keep",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_JEIAuto": "JEI Synchronized Auto",
|
"gui.tooltips.appliedenergistics2.SearchMode_JEIAuto": "REI Synchronized Auto",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_JEIAutoKeep": "JEI Synchronized Auto Keep",
|
"gui.tooltips.appliedenergistics2.SearchMode_JEIAutoKeep": "REI Synchronized Auto Keep",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandard": "JEI Synchronized Standard",
|
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandard": "REI Synchronized Standard",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandardKeep": "JEI Synchronized Standard Keep",
|
"gui.tooltips.appliedenergistics2.SearchMode_JEIStandardKeep": "REI Synchronized Standard Keep",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_Standard": "Standard Search",
|
"gui.tooltips.appliedenergistics2.SearchMode_Standard": "Standard Search",
|
||||||
"gui.tooltips.appliedenergistics2.SearchMode_StandardKeep": "Standard Search Keep",
|
"gui.tooltips.appliedenergistics2.SearchMode_StandardKeep": "Standard Search Keep",
|
||||||
"gui.tooltips.appliedenergistics2.Singularity": "Condense Into Singularities\n%s per item",
|
"gui.tooltips.appliedenergistics2.Singularity": "Condense Into Singularities\n%s per item",
|
||||||
|
|||||||
Reference in New Issue
Block a user