Added JEI integration (#2436).

This commit is contained in:
Sebastian Hartte 2016-10-04 01:34:29 +02:00
parent b8344da734
commit 8df692053a
46 changed files with 1555 additions and 170 deletions

View File

@ -26,5 +26,5 @@ package appeng.api.config;
public enum SearchBoxMode
{
AUTOSEARCH, MANUAL_SEARCH, NEI_AUTOSEARCH, NEI_MANUAL_SEARCH
AUTOSEARCH, MANUAL_SEARCH, JEI_AUTOSEARCH, JEI_MANUAL_SEARCH
}

View File

@ -44,7 +44,6 @@ import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@ -82,9 +81,6 @@ import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketSwapSlots;
import appeng.helpers.InventoryAction;
import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType;
import appeng.integration.abstraction.INEI;
public abstract class AEBaseGui extends GuiContainer
@ -831,20 +827,6 @@ public abstract class AEBaseGui extends GuiContainer
this.safeDrawSlot( s );
}
private RenderItem setItemRender( final RenderItem item )
{
if( IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.NEI ) )
{
return ( (INEI) IntegrationRegistry.INSTANCE.getInstance( IntegrationType.NEI ) ).setItemRender( item );
}
else
{
final RenderItem ri = this.itemRender;
this.itemRender = item;
return ri;
}
}
protected boolean isPowered()
{
return true;

View File

@ -60,8 +60,6 @@ import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketSwitchGuis;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType;
import appeng.parts.reporting.AbstractPartTerminal;
import appeng.tile.misc.TileSecurityStation;
import appeng.util.IConfigManagerHost;
@ -227,26 +225,15 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
this.maxRows = this.getMaxRows();
this.perRow = AEConfig.instance.getConfigManager().getSetting( Settings.TERMINAL_STYLE ) != TerminalStyle.FULL ? 9 : 9 + ( ( this.width - this.standardSize ) / 18 );
final boolean hasNEI = IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.NEI );
final int NEI = hasNEI ? 0 : 0;
int top = hasNEI ? 22 : 0;
final int magicNumber = 114 + 1;
final int extraSpace = this.height - magicNumber - NEI - top - this.reservedSpace;
final int extraSpace = this.height - magicNumber - this.reservedSpace;
this.rows = (int) Math.floor( extraSpace / 18 );
if( this.rows > this.maxRows )
{
top += ( this.rows - this.maxRows ) * 18 / 2;
this.rows = this.maxRows;
}
if( hasNEI )
{
this.rows--;
}
if( this.rows < 3 )
{
this.rows = 3;
@ -319,7 +306,7 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
// Enum setting = AEConfig.INSTANCE.getSetting( "Terminal", SearchBoxMode.class, SearchBoxMode.AUTOSEARCH );
final Enum setting = AEConfig.instance.settings.getSetting( Settings.SEARCH_MODE );
this.searchField.setFocused( SearchBoxMode.AUTOSEARCH == setting || SearchBoxMode.NEI_AUTOSEARCH == setting );
this.searchField.setFocused( SearchBoxMode.AUTOSEARCH == setting || SearchBoxMode.JEI_AUTOSEARCH == setting );
if( this.isSubGui() )
{
@ -369,7 +356,7 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
{
final Enum searchMode = AEConfig.instance.settings.getSetting( Settings.SEARCH_MODE );
if( searchMode != SearchBoxMode.AUTOSEARCH && searchMode != SearchBoxMode.NEI_AUTOSEARCH )
if( searchMode != SearchBoxMode.AUTOSEARCH && searchMode != SearchBoxMode.JEI_AUTOSEARCH )
{
this.searchField.mouseClicked( xCoord, yCoord, btn );
}

View File

@ -234,37 +234,6 @@ public class GuiNetworkStatus extends AEBaseGui implements ISortSource
this.getScrollBar().setRange( 0, ( size + 4 ) / 5 - this.rows, 1 );
}
// @Override - NEI
public List<String> handleItemTooltip( final ItemStack stack, final int mouseX, final int mouseY, final List<String> currentToolTip )
{
if( stack != null )
{
final Slot s = this.getSlot( mouseX, mouseY );
if( s instanceof SlotME )
{
IAEItemStack myStack = null;
try
{
final SlotME theSlotField = (SlotME) s;
myStack = theSlotField.getAEStack();
}
catch( final Throwable ignore )
{
}
if( myStack != null )
{
while( currentToolTip.size() > 1 )
{
currentToolTip.remove( 1 );
}
}
}
}
return currentToolTip;
}
// Vanilla version...
protected void drawItemStackTooltip( final ItemStack stack, final int x, final int y )
{

View File

@ -109,8 +109,8 @@ public class GuiImgButton extends GuiButton implements ITooltip
this.registerApp( 16 * 2 + 3, Settings.SEARCH_MODE, SearchBoxMode.AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_Auto );
this.registerApp( 16 * 2 + 4, Settings.SEARCH_MODE, SearchBoxMode.MANUAL_SEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_Standard );
this.registerApp( 16 * 2 + 5, Settings.SEARCH_MODE, SearchBoxMode.NEI_AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_NEIAuto );
this.registerApp( 16 * 2 + 6, Settings.SEARCH_MODE, SearchBoxMode.NEI_MANUAL_SEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_NEIStandard );
this.registerApp( 16 * 2 + 5, Settings.SEARCH_MODE, SearchBoxMode.JEI_AUTOSEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIAuto );
this.registerApp( 16 * 2 + 6, Settings.SEARCH_MODE, SearchBoxMode.JEI_MANUAL_SEARCH, ButtonToolTips.SearchMode, ButtonToolTips.SearchMode_JEIStandard );
this.registerApp( 16 * 5 + 3, Settings.LEVEL_TYPE, LevelType.ENERGY_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Energy );
this.registerApp( 16 * 4 + 3, Settings.LEVEL_TYPE, LevelType.ITEM_LEVEL, ButtonToolTips.LevelType, ButtonToolTips.LevelType_Item );

View File

@ -19,16 +19,12 @@
package appeng.client.me;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import appeng.api.AEApi;
import appeng.api.config.SearchBoxMode;
@ -41,6 +37,7 @@ import appeng.api.storage.data.IItemList;
import appeng.client.gui.widgets.IScrollSource;
import appeng.client.gui.widgets.ISortSource;
import appeng.core.AEConfig;
import appeng.integration.modules.JEI;
import appeng.items.storage.ItemViewCell;
import appeng.util.ItemSorters;
import appeng.util.Platform;
@ -61,7 +58,7 @@ public class ItemRepo
private String searchString = "";
private IPartitionList<IAEItemStack> myPartitionList;
private String innerSearch = "";
private String NEIWord = null;
private String jeiSearch = null;
private boolean hasPower;
public ItemRepo( final IScrollSource src, final ISortSource sortSrc )
@ -128,9 +125,9 @@ public class ItemRepo
final Enum viewMode = this.sortSrc.getSortDisplay();
final Enum searchMode = AEConfig.instance.settings.getSetting( Settings.SEARCH_MODE );
if( searchMode == SearchBoxMode.NEI_AUTOSEARCH || searchMode == SearchBoxMode.NEI_MANUAL_SEARCH )
if( searchMode == SearchBoxMode.JEI_AUTOSEARCH || searchMode == SearchBoxMode.JEI_MANUAL_SEARCH )
{
this.updateNEI( this.searchString );
this.updateJEI( this.searchString );
}
this.innerSearch = this.searchString;
@ -245,28 +242,9 @@ public class ItemRepo
}
}
private void updateNEI( final String filter )
private void updateJEI( String filter )
{
try
{
if( this.NEIWord == null || !this.NEIWord.equals( filter ) )
{
final Class c = ReflectionHelper.getClass( this.getClass().getClassLoader(), "codechicken.nei.LayoutManager" );
final Field fldSearchField = c.getField( "searchField" );
final Object searchField = fldSearchField.get( c );
final Method a = searchField.getClass().getMethod( "setText", String.class );
final Method b = searchField.getClass().getMethod( "onTextChange", String.class );
this.NEIWord = filter;
a.invoke( searchField, filter );
b.invoke( searchField, "" );
}
}
catch( final Throwable ignore )
{
}
JEI.instance.getJei().setSearchText( filter );
}
public int size()

View File

@ -94,7 +94,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
public int portableCellBattery = 20000;
public int colorApplicatorBattery = 20000;
public int chargedStaffBattery = 8000;
public boolean disableColoredCableRecipesInNEI = true;
public boolean disableColoredCableRecipesInJEI = true;
public boolean updatable = false;
public double meteoriteClusterChance = 0.1;
public double meteoriteSpawnChance = 0.3;
@ -226,7 +226,7 @@ public final class AEConfig extends Configuration implements IConfigurableObject
private void clientSync()
{
this.disableColoredCableRecipesInNEI = this.get( "Client", "disableColoredCableRecipesInNEI", true ).getBoolean( true );
this.disableColoredCableRecipesInJEI = this.get( "Client", "disableColoredCableRecipesInJEI", true ).getBoolean( true );
this.enableEffects = this.get( "Client", "enableEffects", true ).getBoolean( true );
this.useLargeFonts = this.get( "Client", "useTerminalUseLargeFont", false ).getBoolean( false );
this.useColoredCraftingStatus = this.get( "Client", "useColoredCraftingStatus", true ).getBoolean( true );
@ -365,9 +365,9 @@ public final class AEConfig extends Configuration implements IConfigurableObject
}
}
public boolean disableColoredCableRecipesInNEI()
public boolean disableColoredCableRecipesInJEI()
{
return this.disableColoredCableRecipesInNEI;
return this.disableColoredCableRecipesInJEI;
}
public String getFilePath()

View File

@ -65,8 +65,8 @@ public enum ButtonToolTips
SearchMode_Auto,
SearchMode_Standard,
SearchMode_NEIAuto,
SearchMode_NEIStandard,
SearchMode_JEIAuto,
SearchMode_JEIStandard,
SearchMode,
ItemName,

View File

@ -39,7 +39,7 @@ import appeng.core.sync.packets.PacketMEInventoryUpdate;
import appeng.core.sync.packets.PacketMatterCannon;
import appeng.core.sync.packets.PacketMockExplosion;
import appeng.core.sync.packets.PacketMultiPart;
import appeng.core.sync.packets.PacketNEIRecipe;
import appeng.core.sync.packets.PacketJEIRecipe;
import appeng.core.sync.packets.PacketNewStorageDimension;
import appeng.core.sync.packets.PacketPaintedEntity;
import appeng.core.sync.packets.PacketPartPlacement;
@ -94,7 +94,7 @@ public class AppEngPacketHandlerBase
PACKET_PATTERN_SLOT( PacketPatternSlot.class ),
PACKET_RECIPE_NEI( PacketNEIRecipe.class ),
PACKET_RECIPE_JEI( PacketJEIRecipe.class ),
PACKET_PARTIAL_ITEM( PacketPartialItem.class ),

View File

@ -62,13 +62,13 @@ import appeng.util.item.AEItemStack;
import appeng.util.prioitylist.IPartitionList;
public class PacketNEIRecipe extends AppEngPacket
public class PacketJEIRecipe extends AppEngPacket
{
private ItemStack[][] recipe;
// automatic.
public PacketNEIRecipe( final ByteBuf stream ) throws IOException
public PacketJEIRecipe( final ByteBuf stream ) throws IOException
{
final ByteArrayInputStream bytes = new ByteArrayInputStream( stream.array() );
bytes.skip( stream.readerIndex() );
@ -92,7 +92,7 @@ public class PacketNEIRecipe extends AppEngPacket
}
// api
public PacketNEIRecipe( final NBTTagCompound recipe ) throws IOException
public PacketJEIRecipe( final NBTTagCompound recipe ) throws IOException
{
final ByteBuf data = Unpooled.buffer();

View File

@ -53,7 +53,7 @@ public enum IntegrationType
InvTweaks( IntegrationSide.CLIENT, "Inventory Tweaks", "inventorytweaks" ),
NEI( IntegrationSide.CLIENT, "Not Enough Items", "NotEnoughItems" ),
JEI( IntegrationSide.CLIENT, "Just Enough Items", "JEI" ),
CraftGuide( IntegrationSide.CLIENT, "Craft Guide", "craftguide" ),

View File

@ -0,0 +1,15 @@
package appeng.integration.abstraction;
/**
* Abstracts access to the JEI API functionality.
*/
public interface IJEI
{
boolean isEnabled();
String getSearchText();
void setSearchText( String searchText );
}

View File

@ -1,32 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.integration.abstraction;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.inventory.Slot;
public interface INEI
{
void drawSlot( Slot s );
RenderItem setItemRender( RenderItem renderItem );
}

View File

@ -0,0 +1,40 @@
package appeng.integration.modules;
import appeng.helpers.Reflected;
import appeng.integration.IIntegrationModule;
import appeng.integration.abstraction.IJEI;
import appeng.integration.modules.jei.NullJEI;
public class JEI implements IIntegrationModule
{
@Reflected
public static JEI instance;
private IJEI jei = new NullJEI();
@Override
public void init() throws Throwable
{
}
@Override
public void postInit()
{
}
public void setJei( IJEI jei )
{
this.jei = jei;
}
public IJEI getJei()
{
return jei;
}
}

View File

@ -0,0 +1,125 @@
package appeng.integration.modules.jei;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import mezz.jei.api.IGuiHelper;
import mezz.jei.api.gui.IDrawable;
import mezz.jei.api.gui.IDrawableAnimated;
import mezz.jei.api.gui.IDrawableStatic;
import mezz.jei.api.gui.IGuiItemStackGroup;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeCategory;
import appeng.api.AEApi;
import appeng.api.config.CondenserOutput;
import appeng.api.definitions.IMaterials;
import appeng.api.implementations.items.IStorageComponent;
import appeng.core.AppEng;
import appeng.tile.misc.TileCondenser;
class CondenserCategory extends BlankRecipeCategory<CondenserOutputWrapper>
{
public static final String UID = "appliedenergistics2.condenser";
private final String localizedName;
private final IDrawable background;
private final IDrawable iconTrash;
private final IDrawableAnimated progress;
private final IDrawable iconButton;
public CondenserCategory( IGuiHelper guiHelper )
{
this.localizedName = I18n.format( "gui.appliedenergistics2.Condenser" );
ResourceLocation location = new ResourceLocation( AppEng.MOD_ID, "textures/guis/condenser.png" );
this.background = guiHelper.createDrawable( location, 50, 25, 94, 48 );
ResourceLocation statesLocation = new ResourceLocation( AppEng.MOD_ID, "textures/guis/states.png" );
this.iconTrash = guiHelper.createDrawable( statesLocation, 241, 81, 14, 14, 28, 0, 2, 0 );
this.iconButton = guiHelper.createDrawable( statesLocation, 240, 240, 16, 16, 28, 0, 78, 0 );
IDrawableStatic progressDrawable = guiHelper.createDrawable( location, 178, 25, 6, 18, 0, 0, 70, 0 );
this.progress = guiHelper.createAnimatedDrawable( progressDrawable, 40, IDrawableAnimated.StartDirection.BOTTOM, false );
}
@Override
public String getUid()
{
return CondenserCategory.UID;
}
@Override
public String getTitle()
{
return localizedName;
}
@Override
public IDrawable getBackground()
{
return background;
}
@Override
public void drawAnimations( Minecraft minecraft )
{
progress.draw( minecraft );
}
@Override
public void drawExtras( Minecraft minecraft )
{
iconTrash.draw( minecraft );
iconButton.draw( minecraft );
}
@Override
public void setRecipe( IRecipeLayout recipeLayout, CondenserOutputWrapper recipeWrapper, IIngredients ingredients )
{
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init( 0, false, 54, 26 );
// Get all storage cells and cycle them through a fake input slot
itemStacks.init( 1, true, 50, 0 );
itemStacks.set( 1, getViableStorageComponents( recipeWrapper ) );
// This only sets the output
itemStacks.set( ingredients );
}
private List<ItemStack> getViableStorageComponents( CondenserOutputWrapper recipeWrapper )
{
CondenserOutput condenserOutput = recipeWrapper.getCondenserOutput();
IMaterials materials = AEApi.instance().definitions().materials();
List<ItemStack> viableComponents = new ArrayList<>();
materials.cell1kPart().maybeStack( 1 ).ifPresent( itemStack -> addViableComponent( condenserOutput, viableComponents, itemStack ) );
materials.cell4kPart().maybeStack( 1 ).ifPresent( itemStack -> addViableComponent( condenserOutput, viableComponents, itemStack ) );
materials.cell16kPart().maybeStack( 1 ).ifPresent( itemStack -> addViableComponent( condenserOutput, viableComponents, itemStack ) );
materials.cell64kPart().maybeStack( 1 ).ifPresent( itemStack -> addViableComponent( condenserOutput, viableComponents, itemStack ) );
return viableComponents;
}
private void addViableComponent( CondenserOutput condenserOutput, List<ItemStack> viableComponents, ItemStack itemStack )
{
IStorageComponent comp = (IStorageComponent) itemStack.getItem();
int storage = comp.getBytes( itemStack ) * TileCondenser.BYTE_MULTIPLIER;
if( storage >= condenserOutput.requiredPower )
{
viableComponents.add( itemStack );
}
}
}

View File

@ -0,0 +1,79 @@
package appeng.integration.modules.jei;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import mezz.jei.api.IGuiHelper;
import mezz.jei.api.gui.IDrawable;
import mezz.jei.api.recipe.IRecipeHandler;
import mezz.jei.api.recipe.IRecipeWrapper;
import appeng.api.config.CondenserOutput;
import appeng.core.AppEng;
class CondenserOutputHandler implements IRecipeHandler<CondenserOutput>
{
private final ItemStack matterBall;
private final ItemStack singularity;
private final IDrawable iconButtonMatterBall;
private final IDrawable iconButtonSingularity;
public CondenserOutputHandler( IGuiHelper guiHelper, ItemStack matterBall, ItemStack singularity )
{
this.matterBall = matterBall;
this.singularity = singularity;
ResourceLocation statesLocation = new ResourceLocation( AppEng.MOD_ID, "textures/guis/states.png" );
this.iconButtonMatterBall = guiHelper.createDrawable( statesLocation, 16, 112, 14, 14, 28, 0, 78, 0 );
this.iconButtonSingularity = guiHelper.createDrawable( statesLocation, 32, 112, 14, 14, 28, 0, 78, 0 );
}
@Override
public Class<CondenserOutput> getRecipeClass()
{
return CondenserOutput.class;
}
@Override
public String getRecipeCategoryUid()
{
return CondenserCategory.UID;
}
@Override
public String getRecipeCategoryUid( CondenserOutput recipe )
{
return CondenserCategory.UID;
}
@Override
public IRecipeWrapper getRecipeWrapper( CondenserOutput recipe )
{
switch( recipe )
{
case MATTER_BALLS:
return new CondenserOutputWrapper( recipe, matterBall, iconButtonMatterBall );
case SINGULARITY:
return new CondenserOutputWrapper( recipe, singularity, iconButtonSingularity );
default:
return null;
}
}
@Override
public boolean isRecipeValid( CondenserOutput recipe )
{
switch( recipe )
{
case MATTER_BALLS:
return matterBall != null;
case SINGULARITY:
return singularity != null;
default:
return false;
}
}
}

View File

@ -0,0 +1,81 @@
package appeng.integration.modules.jei;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import com.google.common.base.Splitter;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.client.config.HoverChecker;
import mezz.jei.api.gui.IDrawable;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeWrapper;
import appeng.api.config.CondenserOutput;
class CondenserOutputWrapper extends BlankRecipeWrapper
{
private final ItemStack outputItem;
private final CondenserOutput condenserOutput;
private final HoverChecker buttonHoverChecker;
private final IDrawable buttonIcon;
CondenserOutputWrapper( CondenserOutput condenserOutput, ItemStack outputItem, IDrawable buttonIcon )
{
this.condenserOutput = condenserOutput;
this.outputItem = outputItem;
this.buttonIcon = buttonIcon;
this.buttonHoverChecker = new HoverChecker( 28, 28 + 16, 78, 78 + 16, 0 );
}
@Override
public void getIngredients( IIngredients ingredients )
{
ingredients.setOutput( ItemStack.class, outputItem );
}
public CondenserOutput getCondenserOutput()
{
return condenserOutput;
}
@Nullable
@Override
public List<String> getTooltipStrings( int mouseX, int mouseY )
{
if( buttonHoverChecker.checkHover( mouseX, mouseY ) )
{
String key;
switch( condenserOutput )
{
case MATTER_BALLS:
key = "gui.tooltips.appliedenergistics2.MatterBalls";
break;
case SINGULARITY:
key = "gui.tooltips.appliedenergistics2.Singularity";
break;
default:
return Collections.emptyList();
}
return Splitter.on( "\\n" ).splitToList( I18n.format( key, condenserOutput.requiredPower ) );
}
return Collections.emptyList();
}
@Override
public void drawInfo( Minecraft minecraft, int recipeWidth, int recipeHeight, int mouseX, int mouseY )
{
buttonIcon.draw( minecraft );
}
}

View File

@ -0,0 +1,65 @@
package appeng.integration.modules.jei;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.item.ItemStack;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeWrapper;
import mezz.jei.api.recipe.wrapper.IShapedCraftingRecipeWrapper;
/**
* Acts as a fake facade recipe wrapper, created by {@link FacadeRegistryPlugin}.
*/
class FacadeRecipeWrapper extends BlankRecipeWrapper implements IShapedCraftingRecipeWrapper
{
private final ItemStack textureItem;
private final ItemStack cableAnchor;
private final ItemStack facade;
FacadeRecipeWrapper( ItemStack textureItem, ItemStack cableAnchor, ItemStack facade )
{
this.textureItem = textureItem;
this.cableAnchor = cableAnchor;
this.facade = facade;
}
@Override
public int getWidth()
{
return 3;
}
@Override
public int getHeight()
{
return 3;
}
@Override
public void getIngredients( IIngredients ingredients )
{
List<ItemStack> input = new ArrayList<>( 9 );
input.add( null );
input.add( cableAnchor );
input.add( null );
input.add( cableAnchor );
input.add( textureItem );
input.add( cableAnchor );
input.add( null );
input.add( cableAnchor );
input.add( null );
ingredients.setInputs( ItemStack.class, input );
ingredients.setOutput( ItemStack.class, facade );
}
}

View File

@ -0,0 +1,95 @@
package appeng.integration.modules.jei;
import java.util.Collections;
import java.util.List;
import net.minecraft.item.ItemStack;
import mezz.jei.api.recipe.IFocus;
import mezz.jei.api.recipe.IRecipeCategory;
import mezz.jei.api.recipe.IRecipeRegistryPlugin;
import mezz.jei.api.recipe.IRecipeWrapper;
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
import appeng.items.parts.ItemFacade;
/**
* This plugin will dynamically add facade recipes for any item that can be turned into a facade.
*/
class FacadeRegistryPlugin implements IRecipeRegistryPlugin
{
private final ItemFacade itemFacade;
private final ItemStack cableAnchor;
FacadeRegistryPlugin( ItemFacade itemFacade, ItemStack cableAnchor )
{
this.itemFacade = itemFacade;
this.cableAnchor = cableAnchor;
}
@Override
public <V> List<String> getRecipeCategoryUids( IFocus<V> focus )
{
if( focus.getMode() == IFocus.Mode.OUTPUT && focus.getValue() instanceof ItemStack )
{
// Looking up how a certain facade is crafted
ItemStack itemStack = (ItemStack) focus.getValue();
if( itemStack.getItem() instanceof ItemFacade )
{
return Collections.singletonList( VanillaRecipeCategoryUid.CRAFTING );
}
}
else if( focus.getMode() == IFocus.Mode.INPUT && focus.getValue() instanceof ItemStack )
{
// Looking up if a certain block can be used to make a facade
ItemStack itemStack = (ItemStack) focus.getValue();
if( itemFacade.createFacadeForItem( itemStack, true ) != null )
{
return Collections.singletonList( VanillaRecipeCategoryUid.CRAFTING );
}
}
return Collections.emptyList();
}
@SuppressWarnings( "unchecked" )
@Override
public <T extends IRecipeWrapper, V> List<T> getRecipeWrappers( IRecipeCategory<T> recipeCategory, IFocus<V> focus )
{
if( !VanillaRecipeCategoryUid.CRAFTING.equals( recipeCategory.getUid() ) )
{
return Collections.emptyList();
}
if( focus.getMode() == IFocus.Mode.OUTPUT && focus.getValue() instanceof ItemStack )
{
// Looking up how a certain facade is crafted
ItemStack itemStack = (ItemStack) focus.getValue();
if( itemStack.getItem() instanceof ItemFacade )
{
ItemFacade facadeItem = (ItemFacade) itemStack.getItem();
ItemStack textureItem = facadeItem.getTextureItem( itemStack );
return Collections.singletonList( (T) new FacadeRecipeWrapper( textureItem, cableAnchor, itemStack ) );
}
}
else if( focus.getMode() == IFocus.Mode.INPUT && focus.getValue() instanceof ItemStack )
{
// Looking up if a certain block can be used to make a facade
ItemStack itemStack = (ItemStack) focus.getValue();
ItemStack facade = itemFacade.createFacadeForItem( itemStack, false );
if( facade != null )
{
return Collections.singletonList( (T) new FacadeRecipeWrapper( itemStack, cableAnchor, facade ) );
}
}
return Collections.emptyList();
}
}

View File

@ -0,0 +1,64 @@
package appeng.integration.modules.jei;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
import mezz.jei.api.IGuiHelper;
import mezz.jei.api.gui.IDrawable;
import mezz.jei.api.gui.IGuiItemStackGroup;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeCategory;
import appeng.core.AppEng;
class GrinderRecipeCategory extends BlankRecipeCategory<GrinderRecipeWrapper>
{
public static final String UID = "appliedenergistics2.grinder";
private final String localizedName;
private final IDrawable background;
public GrinderRecipeCategory( IGuiHelper guiHelper )
{
this.localizedName = I18n.format( "tile.appliedenergistics2.grindstone.name" );
ResourceLocation location = new ResourceLocation( AppEng.MOD_ID, "textures/guis/grinder.png" );
this.background = guiHelper.createDrawable( location, 11, 16, 154, 64 );
}
@Override
public String getUid()
{
return GrinderRecipeCategory.UID;
}
@Override
public String getTitle()
{
return localizedName;
}
@Override
public IDrawable getBackground()
{
return background;
}
@Override
public void setRecipe( IRecipeLayout recipeLayout, GrinderRecipeWrapper recipeWrapper, IIngredients ingredients )
{
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init( 0, true, 0, 0 );
itemStacks.init( 1, false, 100, 46 );
itemStacks.init( 2, false, 118, 46 );
itemStacks.init( 3, false, 136, 46 );
itemStacks.set( ingredients );
}
}

View File

@ -0,0 +1,42 @@
package appeng.integration.modules.jei;
import mezz.jei.api.recipe.IRecipeHandler;
import mezz.jei.api.recipe.IRecipeWrapper;
import appeng.api.features.IGrinderEntry;
class GrinderRecipeHandler implements IRecipeHandler<IGrinderEntry>
{
@Override
public Class<IGrinderEntry> getRecipeClass()
{
return IGrinderEntry.class;
}
@Override
public String getRecipeCategoryUid()
{
return GrinderRecipeCategory.UID;
}
@Override
public String getRecipeCategoryUid( IGrinderEntry recipe )
{
return GrinderRecipeCategory.UID;
}
@Override
public IRecipeWrapper getRecipeWrapper( IGrinderEntry recipe )
{
return new GrinderRecipeWrapper( recipe );
}
@Override
public boolean isRecipeValid( IGrinderEntry recipe )
{
return true;
}
}

View File

@ -0,0 +1,77 @@
package appeng.integration.modules.jei;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.item.ItemStack;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeWrapper;
import appeng.api.features.IGrinderEntry;
class GrinderRecipeWrapper extends BlankRecipeWrapper
{
private final IGrinderEntry recipe;
GrinderRecipeWrapper( IGrinderEntry recipe )
{
this.recipe = recipe;
}
@Override
public void getIngredients( IIngredients ingredients )
{
ingredients.setInput( ItemStack.class, recipe.getInput() );
List<ItemStack> outputs = new ArrayList<>( 3 );
outputs.add( recipe.getOutput() );
if( recipe.getOptionalOutput() != null )
{
outputs.add( recipe.getOptionalOutput() );
}
if( recipe.getSecondOptionalOutput() != null )
{
outputs.add( recipe.getSecondOptionalOutput() );
}
ingredients.setOutputs( ItemStack.class, outputs );
}
@Override
public void drawInfo( Minecraft minecraft, int recipeWidth, int recipeHeight, int mouseX, int mouseY )
{
FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
int x = 118;
final float scale = 0.85f;
final float invScale = 1 / scale;
GlStateManager.scale( scale, scale, 1 );
if( recipe.getOptionalOutput() != null )
{
String text = String.format( "%d%%", (int) ( recipe.getOptionalChance() * 100 ) );
float width = fr.getStringWidth( text ) * scale;
int xScaled = (int) Math.round( ( x + ( 18 - width ) / 2 ) * invScale );
fr.drawString( text, xScaled, (int) ( 65 * invScale ), Color.gray.getRGB() );
x += 18;
}
if( recipe.getSecondOptionalOutput() != null )
{
String text = String.format( "%d%%", (int) ( recipe.getSecondOptionalChance() * 100 ) );
float width = fr.getStringWidth( text ) * scale;
int xScaled = (int) Math.round( ( x + ( 18 - width ) / 2 ) * invScale );
fr.drawString( text, xScaled, (int) ( 65 * invScale ), Color.gray.getRGB() );
}
GlStateManager.scale( invScale, invScale, 1 );
}
}

View File

@ -0,0 +1,82 @@
package appeng.integration.modules.jei;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
import mezz.jei.api.IGuiHelper;
import mezz.jei.api.gui.IDrawable;
import mezz.jei.api.gui.IDrawableAnimated;
import mezz.jei.api.gui.IDrawableStatic;
import mezz.jei.api.gui.IGuiItemStackGroup;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeCategory;
import appeng.core.AppEng;
class InscriberRecipeCategory extends BlankRecipeCategory<InscriberRecipeWrapper>
{
private static final int SLOT_INPUT_TOP = 0;
private static final int SLOT_INPUT_MIDDLE = 1;
private static final int SLOT_INPUT_BOTTOM = 2;
private static final int SLOT_OUTPUT = 3;
static final String UID = "appliedenergistics2.inscriber";
private final IDrawable background;
private final String localizedName;
private final IDrawableAnimated progress;
public InscriberRecipeCategory( IGuiHelper guiHelper )
{
ResourceLocation location = new ResourceLocation( AppEng.MOD_ID, "textures/guis/inscriber.png" );
this.background = guiHelper.createDrawable( location, 44, 15, 97, 64 );
this.localizedName = I18n.format( "tile.appliedenergistics2.inscriber.name" );
IDrawableStatic progressDrawable = guiHelper.createDrawable( location, 135, 177, 6, 18, 24, 0, 91, 0 );
this.progress = guiHelper.createAnimatedDrawable( progressDrawable, 40, IDrawableAnimated.StartDirection.BOTTOM, false );
}
@Override
public String getUid()
{
return UID;
}
@Override
public String getTitle()
{
return localizedName;
}
@Override
public IDrawable getBackground()
{
return background;
}
@Override
public void drawAnimations( Minecraft minecraft )
{
this.progress.draw( minecraft );
}
@Override
public void setRecipe( IRecipeLayout recipeLayout, InscriberRecipeWrapper recipeWrapper, IIngredients ingredients )
{
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init( SLOT_INPUT_TOP, true, 0, 0 );
itemStacks.init( SLOT_INPUT_MIDDLE, true, 18, 23 );
itemStacks.init( SLOT_INPUT_BOTTOM, true, 0, 46 );
itemStacks.init( SLOT_OUTPUT, false, 68, 24 );
itemStacks.set( ingredients );
}
}

View File

@ -0,0 +1,43 @@
package appeng.integration.modules.jei;
import mezz.jei.api.recipe.IRecipeHandler;
import mezz.jei.api.recipe.IRecipeWrapper;
import appeng.api.features.IInscriberRecipe;
class InscriberRecipeHandler implements IRecipeHandler<IInscriberRecipe>
{
@Override
public Class<IInscriberRecipe> getRecipeClass()
{
return IInscriberRecipe.class;
}
@Override
public String getRecipeCategoryUid()
{
return InscriberRecipeCategory.UID;
}
@Override
public String getRecipeCategoryUid( IInscriberRecipe recipe )
{
return InscriberRecipeCategory.UID;
}
@Override
public IRecipeWrapper getRecipeWrapper( IInscriberRecipe recipe )
{
return new InscriberRecipeWrapper( recipe );
}
@Override
public boolean isRecipeValid( IInscriberRecipe recipe )
{
return true;
}
}

View File

@ -0,0 +1,38 @@
package appeng.integration.modules.jei;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.minecraft.item.ItemStack;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeWrapper;
import appeng.api.features.IInscriberRecipe;
class InscriberRecipeWrapper extends BlankRecipeWrapper
{
private final IInscriberRecipe recipe;
public InscriberRecipeWrapper( IInscriberRecipe recipe )
{
this.recipe = recipe;
}
@Override
public void getIngredients( IIngredients ingredients )
{
List<List<ItemStack>> inputSlots = new ArrayList<>( 3 );
inputSlots.add( Collections.singletonList( recipe.getTopOptional().orElse( null ) ) );
inputSlots.add( recipe.getInputs() );
inputSlots.add( Collections.singletonList( recipe.getBottomOptional().orElse( null ) ) );
ingredients.setInputLists( ItemStack.class, inputSlots );
ingredients.setOutput( ItemStack.class, recipe.getOutput() );
}
}

View File

@ -0,0 +1,51 @@
package appeng.integration.modules.jei;
import java.util.Collections;
import java.util.List;
import net.minecraft.item.ItemStack;
import mezz.jei.api.recipe.IFocus;
import mezz.jei.api.recipe.IRecipeCategory;
import mezz.jei.api.recipe.IRecipeRegistryPlugin;
import mezz.jei.api.recipe.IRecipeWrapper;
import appeng.api.AEApi;
import appeng.api.features.IInscriberRegistry;
/**
* Exposes the inscriber registry recipes to JEI.
*/
class InscriberRegistryPlugin implements IRecipeRegistryPlugin
{
private final IInscriberRegistry inscriber = AEApi.instance().registries().inscriber();
@Override
public <V> List<String> getRecipeCategoryUids( IFocus<V> focus )
{
if( !( focus.getValue() instanceof ItemStack ) )
{
return Collections.emptyList();
}
if( focus.getMode() == IFocus.Mode.INPUT )
{
ItemStack input = (ItemStack) focus.getValue();
for( ItemStack validInput : inscriber.getInputs() )
{
}
}
return Collections.emptyList();
}
@Override
public <T extends IRecipeWrapper, V> List<T> getRecipeWrappers( IRecipeCategory<T> recipeCategory, IFocus<V> focus )
{
return null;
}
}

View File

@ -0,0 +1,185 @@
package appeng.integration.modules.jei;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import com.google.common.collect.ImmutableList;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import mezz.jei.api.BlankModPlugin;
import mezz.jei.api.IJeiRuntime;
import mezz.jei.api.IModRegistry;
import appeng.api.AEApi;
import appeng.api.config.CondenserOutput;
import appeng.api.definitions.IDefinitions;
import appeng.api.definitions.IItemDefinition;
import appeng.api.definitions.IMaterials;
import appeng.api.features.IInscriberRecipe;
import appeng.container.implementations.ContainerCraftingTerm;
import appeng.container.implementations.ContainerPatternTerm;
import appeng.core.AEConfig;
import appeng.core.features.AEFeature;
import appeng.core.localization.GuiText;
import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType;
import appeng.integration.modules.JEI;
import appeng.items.parts.ItemFacade;
@mezz.jei.api.JEIPlugin
public class JEIPlugin extends BlankModPlugin
{
@Override
public void register( IModRegistry registry )
{
registry.addRecipeHandlers( new ShapedRecipeHandler(), new ShapelessRecipeHandler() );
IDefinitions definitions = AEApi.instance().definitions();
registerFacadeRecipe( definitions, registry );
registerInscriberRecipes( definitions, registry );
registerCondenserRecipes( definitions, registry );
registerGrinderRecipes( definitions, registry );
registerDescriptions( definitions, registry );
// Allow recipe transfer from JEI to crafting and pattern terminal
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerCraftingTerm.class ) );
registry.getRecipeTransferRegistry().addRecipeTransferHandler( new RecipeTransferHandler<>( ContainerPatternTerm.class ) );
}
private void registerDescriptions( IDefinitions definitions, IModRegistry registry )
{
IMaterials materials = definitions.materials();
final String message;
if( AEConfig.instance.isFeatureEnabled( AEFeature.CertusQuartzWorldGen ) )
{
message = GuiText.ChargedQuartz.getLocal() + "\n\n" + GuiText.ChargedQuartzFind.getLocal();
}
else
{
message = GuiText.ChargedQuartzFind.getLocal();
}
addDescription( registry, materials.certusQuartzCrystalCharged(), message );
if( AEConfig.instance.isFeatureEnabled( AEFeature.MeteoriteWorldGen ) )
{
addDescription( registry, materials.logicProcessorPress(), GuiText.inWorldCraftingPresses.getLocal() );
addDescription( registry, materials.calcProcessorPress(), GuiText.inWorldCraftingPresses.getLocal() );
addDescription( registry, materials.engProcessorPress(), GuiText.inWorldCraftingPresses.getLocal() );
}
if( AEConfig.instance.isFeatureEnabled( AEFeature.InWorldFluix ) )
{
addDescription( registry, materials.fluixCrystal(), GuiText.inWorldFluix.getLocal() );
}
if( AEConfig.instance.isFeatureEnabled( AEFeature.InWorldSingularity ) )
{
addDescription( registry, materials.qESingularity(), GuiText.inWorldSingularity.getLocal() );
}
if( AEConfig.instance.isFeatureEnabled( AEFeature.InWorldPurification ) )
{
addDescription( registry, materials.purifiedCertusQuartzCrystal(), GuiText.inWorldPurificationCertus.getLocal() );
addDescription( registry, materials.purifiedNetherQuartzCrystal(), GuiText.inWorldPurificationNether.getLocal() );
addDescription( registry, materials.purifiedFluixCrystal(), GuiText.inWorldPurificationFluix.getLocal() );
}
}
private void addDescription( IModRegistry registry, IItemDefinition itemDefinition, String message )
{
itemDefinition.maybeStack( 1 ).ifPresent( itemStack -> registry.addDescription( itemStack, message ) );
}
private void registerGrinderRecipes( IDefinitions definitions, IModRegistry registry )
{
ItemStack grindstone = definitions.blocks().grindstone().maybeStack( 1 ).orElse( null );
if( grindstone == null )
{
return;
}
registry.addRecipes( AEApi.instance().registries().grinder().getRecipes() );
registry.addRecipeHandlers( new GrinderRecipeHandler() );
registry.addRecipeCategories( new GrinderRecipeCategory( registry.getJeiHelpers().getGuiHelper() ) );
registry.addRecipeCategoryCraftingItem( grindstone, GrinderRecipeCategory.UID );
}
private void registerCondenserRecipes( IDefinitions definitions, IModRegistry registry )
{
ItemStack condenser = definitions.blocks().condenser().maybeStack( 1 ).orElse( null );
if( condenser == null )
{
return;
}
ItemStack matterBall = definitions.materials().matterBall().maybeStack( 1 ).orElse( null );
if( matterBall != null )
{
registry.addRecipes( ImmutableList.of( CondenserOutput.MATTER_BALLS ) );
}
ItemStack singularity = definitions.materials().singularity().maybeStack( 1 ).orElse( null );
if( singularity != null )
{
registry.addRecipes( ImmutableList.of( CondenserOutput.SINGULARITY ) );
}
if( matterBall != null || singularity != null )
{
registry.addRecipeCategories( new CondenserCategory( registry.getJeiHelpers().getGuiHelper() ) );
registry.addRecipeCategoryCraftingItem( condenser, CondenserCategory.UID );
registry.addRecipeHandlers( new CondenserOutputHandler( registry.getJeiHelpers().getGuiHelper(), matterBall, singularity ) );
}
}
private void registerInscriberRecipes( IDefinitions definitions, IModRegistry registry )
{
registry.addRecipeHandlers( new InscriberRecipeHandler() );
registry.addRecipeCategories( new InscriberRecipeCategory( registry.getJeiHelpers().getGuiHelper() ) );
// Register the inscriber as the crafting item for the inscription category
definitions.blocks().inscriber().maybeStack( 1 ).ifPresent( inscriber ->
{
registry.addRecipeCategoryCraftingItem( inscriber, InscriberRecipeCategory.UID );
} );
List<IInscriberRecipe> inscriberRecipes = new ArrayList<>( AEApi.instance().registries().inscriber().getRecipes() );
registry.addRecipes( inscriberRecipes );
}
// Handle the generic crafting recipe for patterns in JEI
private void registerFacadeRecipe( IDefinitions definitions, IModRegistry registry )
{
Optional<Item> itemFacade = definitions.items().facade().maybeItem();
Optional<ItemStack> cableAnchor = definitions.parts().cableAnchor().maybeStack( 1 );
if( itemFacade.isPresent() && cableAnchor.isPresent() )
{
registry.addRecipeRegistryPlugin( new FacadeRegistryPlugin( (ItemFacade) itemFacade.get(), cableAnchor.get() ) );
}
}
@Override
public void onRuntimeAvailable( IJeiRuntime jeiRuntime )
{
JEI jeiModule = (JEI) IntegrationRegistry.INSTANCE.getInstance( IntegrationType.JEI );
jeiModule.setJei( new JeiRuntimeAdapter( jeiRuntime ) );
}
}

View File

@ -0,0 +1,38 @@
package appeng.integration.modules.jei;
import com.google.common.base.Strings;
import mezz.jei.api.IJeiRuntime;
import appeng.integration.abstraction.IJEI;
class JeiRuntimeAdapter implements IJEI
{
private final IJeiRuntime runtime;
JeiRuntimeAdapter( IJeiRuntime jeiRuntime )
{
this.runtime = jeiRuntime;
}
@Override
public boolean isEnabled()
{
return true;
}
@Override
public String getSearchText()
{
return Strings.nullToEmpty( runtime.getItemListOverlay().getFilterText() );
}
@Override
public void setSearchText( String searchText )
{
runtime.getItemListOverlay().setFilterText( Strings.nullToEmpty( searchText ) );
}
}

View File

@ -0,0 +1,25 @@
package appeng.integration.modules.jei;
import appeng.integration.abstraction.IJEI;
public class NullJEI implements IJEI
{
@Override
public boolean isEnabled()
{
return false;
}
@Override
public String getSearchText()
{
return "";
}
@Override
public void setSearchText( String searchText )
{
}
}

View File

@ -0,0 +1,125 @@
package appeng.integration.modules.jei;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import mezz.jei.api.gui.IGuiIngredient;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
import appeng.container.slot.SlotCraftingMatrix;
import appeng.container.slot.SlotFakeCraftingMatrix;
import appeng.core.AELog;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketJEIRecipe;
import appeng.util.Platform;
class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandler<T>
{
private final Class<T> containerClass;
RecipeTransferHandler( Class<T> containerClass )
{
this.containerClass = containerClass;
}
@Override
public Class<T> getContainerClass()
{
return containerClass;
}
@Override
public String getRecipeCategoryUid()
{
return VanillaRecipeCategoryUid.CRAFTING;
}
@Nullable
@Override
public IRecipeTransferError transferRecipe( T container, IRecipeLayout recipeLayout, EntityPlayer player, boolean maxTransfer, boolean doTransfer )
{
if( !doTransfer )
{
return null;
}
Map<Integer, ? extends IGuiIngredient<ItemStack>> ingredients = recipeLayout.getItemStacks().getGuiIngredients();
final NBTTagCompound recipe = new NBTTagCompound();
int slotIndex = 0;
for( Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> ingredientEntry : ingredients.entrySet() )
{
IGuiIngredient<ItemStack> ingredient = ingredientEntry.getValue();
if( !ingredient.isInput() )
{
continue;
}
for( final Slot slot : container.inventorySlots )
{
if( slot instanceof SlotCraftingMatrix || slot instanceof SlotFakeCraftingMatrix )
{
if( slot.getSlotIndex() == slotIndex )
{
final NBTTagList tags = new NBTTagList();
final List<ItemStack> list = new LinkedList<ItemStack>();
// prefer pure crystals.
for( ItemStack stack : ingredient.getAllIngredients() )
{
if( Platform.isRecipePrioritized( stack ) )
{
list.add( 0, stack );
}
else
{
list.add( stack );
}
}
for( final ItemStack is : list )
{
final NBTTagCompound tag = new NBTTagCompound();
is.writeToNBT( tag );
tags.appendTag( tag );
}
recipe.setTag( "#" + slot.getSlotIndex(), tags );
break;
}
}
}
slotIndex++;
}
try
{
NetworkHandler.instance.sendToServer( new PacketJEIRecipe( recipe ) );
}
catch( IOException e )
{
AELog.debug( e );
}
return null;
}
}

View File

@ -0,0 +1,43 @@
package appeng.integration.modules.jei;
import mezz.jei.api.recipe.IRecipeHandler;
import mezz.jei.api.recipe.IRecipeWrapper;
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
import appeng.recipes.game.ShapedRecipe;
class ShapedRecipeHandler implements IRecipeHandler<ShapedRecipe>
{
@Override
public Class<ShapedRecipe> getRecipeClass()
{
return ShapedRecipe.class;
}
@Override
public String getRecipeCategoryUid()
{
return VanillaRecipeCategoryUid.CRAFTING;
}
@Override
public String getRecipeCategoryUid( ShapedRecipe recipe )
{
return VanillaRecipeCategoryUid.CRAFTING;
}
@Override
public IRecipeWrapper getRecipeWrapper( ShapedRecipe recipe )
{
return new ShapedRecipeWrapper( recipe );
}
@Override
public boolean isRecipeValid( ShapedRecipe recipe )
{
return recipe.isEnabled();
}
}

View File

@ -0,0 +1,85 @@
package appeng.integration.modules.jei;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.minecraft.item.ItemStack;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeWrapper;
import mezz.jei.api.recipe.wrapper.IShapedCraftingRecipeWrapper;
import scala.actors.threadpool.Arrays;
import appeng.api.exceptions.MissingIngredientError;
import appeng.api.exceptions.RegistrationError;
import appeng.api.recipes.IIngredient;
import appeng.core.AEConfig;
import appeng.recipes.game.ShapedRecipe;
import appeng.util.Platform;
class ShapedRecipeWrapper extends BlankRecipeWrapper implements IShapedCraftingRecipeWrapper
{
private final ShapedRecipe recipe;
public ShapedRecipeWrapper( ShapedRecipe recipe )
{
this.recipe = recipe;
}
@Override
public void getIngredients( IIngredients ingredients )
{
final boolean useSingleItems = AEConfig.instance.disableColoredCableRecipesInJEI();
Object[] items = recipe.getIngredients();
int width = recipe.getWidth();
int height = recipe.getHeight();
List<List<ItemStack>> in = new ArrayList<>( width * height );
for( int x = 0; x < width; x++ )
{
for( int y = 0; y < height; y++ )
{
if( items[( x * height + y )] != null )
{
final IIngredient ing = (IIngredient) items[( x * height + y )];
List<ItemStack> slotList = Collections.emptyList();
try
{
ItemStack[] is = ing.getItemStackSet();
slotList = useSingleItems ? Platform.findPreferred( is ) : Arrays.asList( is );
}
catch( final RegistrationError | MissingIngredientError ignored )
{
}
in.add( slotList );
}
else
{
in.add( Collections.emptyList() );
}
}
}
ingredients.setInputLists( ItemStack.class, in );
ingredients.setOutput( ItemStack.class, recipe.getRecipeOutput() );
}
@Override
public int getWidth()
{
return recipe.getWidth();
}
@Override
public int getHeight()
{
return recipe.getHeight();
}
}

View File

@ -0,0 +1,43 @@
package appeng.integration.modules.jei;
import mezz.jei.api.recipe.IRecipeHandler;
import mezz.jei.api.recipe.IRecipeWrapper;
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
import appeng.recipes.game.ShapelessRecipe;
class ShapelessRecipeHandler implements IRecipeHandler<ShapelessRecipe>
{
@Override
public Class<ShapelessRecipe> getRecipeClass()
{
return ShapelessRecipe.class;
}
@Override
public String getRecipeCategoryUid()
{
return VanillaRecipeCategoryUid.CRAFTING;
}
@Override
public String getRecipeCategoryUid( ShapelessRecipe recipe )
{
return VanillaRecipeCategoryUid.CRAFTING;
}
@Override
public IRecipeWrapper getRecipeWrapper( ShapelessRecipe recipe )
{
return new ShapelessRecipeWrapper( recipe );
}
@Override
public boolean isRecipeValid( ShapelessRecipe recipe )
{
return recipe.isEnabled();
}
}

View File

@ -0,0 +1,56 @@
package appeng.integration.modules.jei;
import java.util.ArrayList;
import java.util.List;
import com.google.common.collect.Lists;
import net.minecraft.item.ItemStack;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.BlankRecipeWrapper;
import mezz.jei.api.recipe.wrapper.ICraftingRecipeWrapper;
import appeng.api.exceptions.MissingIngredientError;
import appeng.api.exceptions.RegistrationError;
import appeng.api.recipes.IIngredient;
import appeng.recipes.game.ShapelessRecipe;
class ShapelessRecipeWrapper extends BlankRecipeWrapper implements ICraftingRecipeWrapper
{
private final ShapelessRecipe recipe;
public ShapelessRecipeWrapper( ShapelessRecipe recipe )
{
this.recipe = recipe;
}
@Override
public void getIngredients( IIngredients ingredients )
{
List<Object> recipeInput = this.recipe.getInput();
List<List<ItemStack>> inputs = new ArrayList<>( recipeInput.size() );
for( Object inputObj : recipeInput )
{
if( inputObj instanceof IIngredient )
{
IIngredient ingredient = (IIngredient) inputObj;
try
{
inputs.add( Lists.newArrayList( ingredient.getItemStackSet() ) );
}
catch( RegistrationError | MissingIngredientError registrationError )
{
throw new RuntimeException( "Unable to register recipe with JEI" );
}
}
}
ingredients.setInputLists( ItemStack.class, inputs );
ingredients.setOutput( ItemStack.class, this.recipe.getRecipeOutput() );
}
}

View File

@ -48,6 +48,8 @@ import appeng.util.Platform;
public class TileCondenser extends AEBaseInvTile implements IFluidHandler, IConfigManagerHost, IConfigurableObject
{
public static final int BYTE_MULTIPLIER = 8;
private static final FluidTankInfo[] EMPTY = { new FluidTankInfo( null, 10 ) };
private final int[] sides = { 0, 1 };
private final AppEngInternalInventory inv = new AppEngInternalInventory( this, 3 );
@ -84,7 +86,7 @@ public class TileCondenser extends AEBaseInvTile implements IFluidHandler, IConf
final IStorageComponent sc = (IStorageComponent) is.getItem();
if( sc.isStorageComponent( is ) )
{
return sc.getBytes( is ) * 8;
return sc.getBytes( is ) * BYTE_MULTIPLIER;
}
}
}

View File

@ -25,6 +25,7 @@ import java.security.InvalidParameterException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
@ -32,10 +33,11 @@ import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.WeakHashMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.google.common.collect.Lists;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@ -356,12 +358,12 @@ public class Platform
return true;
}
if( e == SearchBoxMode.NEI_AUTOSEARCH && !IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.NEI ) )
if( e == SearchBoxMode.JEI_AUTOSEARCH && !IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.JEI ) )
{
return true;
}
if( e == SearchBoxMode.NEI_MANUAL_SEARCH && !IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.NEI ) )
if( e == SearchBoxMode.JEI_MANUAL_SEARCH && !IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.JEI ) )
{
return true;
}
@ -2098,7 +2100,7 @@ public class Platform
return false;
}
public static Object findPreferred( final ItemStack[] is )
public static List<ItemStack> findPreferred( final ItemStack[] is )
{
final IParts parts = AEApi.instance().definitions().parts();
@ -2106,26 +2108,26 @@ public class Platform
{
if( parts.cableGlass().sameAs( AEColor.TRANSPARENT, stack ) )
{
return stack;
return Collections.singletonList(stack);
}
if( parts.cableCovered().sameAs( AEColor.TRANSPARENT, stack ) )
{
return stack;
return Collections.singletonList(stack);
}
if( parts.cableSmart().sameAs( AEColor.TRANSPARENT, stack ) )
{
return stack;
return Collections.singletonList(stack);
}
if( parts.cableDense().sameAs( AEColor.TRANSPARENT, stack ) )
{
return stack;
return Collections.singletonList(stack);
}
}
return is;
return Lists.newArrayList( is );
}
public static void sendChunk( final Chunk c, final int verticalBits )

View File

@ -245,8 +245,8 @@ gui.tooltips.appliedenergistics2.EmitLevelsBelow=Vysílá, když jsou úrovně p
gui.tooltips.appliedenergistics2.EmitLevelAbove=Vysílá, když jsou úrovně nad, nebo odpovídají limitu.
gui.tooltips.appliedenergistics2.SearchMode_Auto=Automatické vyhledávání
gui.tooltips.appliedenergistics2.SearchMode_Standard=Standartní vyhledávání
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=NEI automatické synchronizování
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=NEI standartní synchronizování
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=JEI automatické synchronizování
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=JEI standartní synchronizování
gui.tooltips.appliedenergistics2.SearchMode=Mód vyhledávacího rámečku
gui.tooltips.appliedenergistics2.PartitionStorageHint=Nastavuje oddíly založené na právě uložených předmětech.
gui.tooltips.appliedenergistics2.ClearSettings=Promazat konfiguraci/nastavení

View File

@ -282,8 +282,8 @@ gui.tooltips.appliedenergistics2.EmitLevelsBelow=Signal, wenn Limit erreicht ode
gui.tooltips.appliedenergistics2.EmitLevelAbove=Signal, wenn Limit erreicht oder überschritten.
gui.tooltips.appliedenergistics2.SearchMode_Auto=Automatische Suche
gui.tooltips.appliedenergistics2.SearchMode_Standard=Standard-Suche
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=Automatische Suche mit NEI
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=Standard-Suche mit NEI
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=Automatische Suche mit JEI
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=Standard-Suche mit JEI
gui.tooltips.appliedenergistics2.SearchMode=Suchleistenmodus
gui.tooltips.appliedenergistics2.PartitionStorageHint=Partition mit aktuell gespeicherten Items erstellen.
gui.tooltips.appliedenergistics2.ClearSettings=Config/Einstellungen löschen

View File

@ -2,8 +2,8 @@
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
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=NEI Synchronised Auto
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=NEI Synchronised Standard
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=JEI Synchronised Auto
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=JEI Synchronised Standard
gui.tooltips.appliedenergistics2.TerminalStyle_Tall=Tall Centered Terminal
gui.tooltips.appliedenergistics2.TerminalStyle_Small=Small Centered Terminal

View File

@ -284,8 +284,8 @@ gui.tooltips.appliedenergistics2.EmitLevelsBelow=Emit when levels are below limi
gui.tooltips.appliedenergistics2.EmitLevelAbove=Emit when levels are above or equal to limit.
gui.tooltips.appliedenergistics2.SearchMode_Auto=Auto Search
gui.tooltips.appliedenergistics2.SearchMode_Standard=Standard Search
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=NEI Synchronized Auto
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=NEI Synchronized Standard
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=JEI Synchronized Auto
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=JEI Synchronized Standard
gui.tooltips.appliedenergistics2.SearchMode=Search Box Mode
gui.tooltips.appliedenergistics2.PartitionStorageHint=Configures Partition based on currently stored items.
gui.tooltips.appliedenergistics2.ClearSettings=Clear Config/Settings

View File

@ -237,8 +237,8 @@ gui.tooltips.appliedenergistics2.EmitLevelsBelow=Emitir cuando el nivel esté po
gui.tooltips.appliedenergistics2.EmitLevelAbove=Emitir cuando el nivel esté por encima o igual al límite.
gui.tooltips.appliedenergistics2.SearchMode_Auto=Auto Buscar
gui.tooltips.appliedenergistics2.SearchMode_Standard=Búsqueda Estandar
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=NEI Sincronización Automática
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=NEI Sincronización Estandar
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=JEI Sincronización Automática
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=JEI Sincronización Estandar
gui.tooltips.appliedenergistics2.SearchMode=Modo de Búsqueda
gui.tooltips.appliedenergistics2.PartitionStorageHint=Configurar Partición basado en los objetos almacenados actualmente.
gui.tooltips.appliedenergistics2.ClearSettings=Limpiar Configuración

View File

@ -279,8 +279,8 @@ gui.tooltips.appliedenergistics2.EmitLevelsBelow=Emettre quand les niveaux sont
gui.tooltips.appliedenergistics2.EmitLevelAbove=Emettre quand les niveaux sont supérieurs ou égaux à la limite.
gui.tooltips.appliedenergistics2.SearchMode_Auto=Recherche auto
gui.tooltips.appliedenergistics2.SearchMode_Standard=Recharche standard
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=Synchronisation NEI auto
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=Synchronisation NEI standard
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=Synchronisation JEI auto
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=Synchronisation JEI standard
gui.tooltips.appliedenergistics2.SearchMode=Mode de la boite de recherche
gui.tooltips.appliedenergistics2.PartitionStorageHint=Configure la partition par rapport aux objets actuellement stockés.
gui.tooltips.appliedenergistics2.ClearSettings=Efface les paramètres

View File

@ -266,8 +266,8 @@ gui.tooltips.appliedenergistics2.EmitLevelsBelow=Emetti quando il livello è min
gui.tooltips.appliedenergistics2.EmitLevelAbove=Emetti quando il livello è sopra al limite.
gui.tooltips.appliedenergistics2.SearchMode_Auto=Auto-cerca
gui.tooltips.appliedenergistics2.SearchMode_Standard=Ricerca normale
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=Sincronizazione NEI automatica
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=Sincronizazione NEI normale
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=Sincronizazione JEI automatica
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=Sincronizazione JEI normale
gui.tooltips.appliedenergistics2.SearchMode=Modalità ricerca
gui.tooltips.appliedenergistics2.PartitionStorageHint=Configura divisione basato sugli oggetti depositati ora.
gui.tooltips.appliedenergistics2.ClearSettings=Cancella config/impostazioni

View File

@ -255,8 +255,8 @@ gui.tooltips.appliedenergistics2.EmitLevelsBelow=Emit when levels are below or e
gui.tooltips.appliedenergistics2.EmitLevelAbove=Emit when levels are above or equal to limit.
gui.tooltips.appliedenergistics2.SearchMode_Auto=Auto Search
gui.tooltips.appliedenergistics2.SearchMode_Standard=Standard Search
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=NEI Syncronized Auto
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=NEI Syncronized Standard
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=JEI Syncronized Auto
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=JEI Syncronized Standard
gui.tooltips.appliedenergistics2.SearchMode=Search Box Mode
gui.tooltips.appliedenergistics2.PartitionStorageHint=Configures Partition based on currently stored items.
gui.tooltips.appliedenergistics2.ClearSettings=Clear Config/Settings

View File

@ -284,8 +284,8 @@ gui.tooltips.appliedenergistics2.EmitLevelsBelow=Emitir quando níveis são igua
gui.tooltips.appliedenergistics2.EmitLevelAbove=Emitir quando níveis são iguais ou estão acima do limite.
gui.tooltips.appliedenergistics2.SearchMode_Auto=Auto Procura
gui.tooltips.appliedenergistics2.SearchMode_Standard=Procura Normal
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=Auto Sincronizado ao NEI
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=Sincronizado ao NEI Normalmente
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=Auto Sincronizado ao JEI
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=Sincronizado ao JEI Normalmente
gui.tooltips.appliedenergistics2.SearchMode=Modo de Caixa de Procura
gui.tooltips.appliedenergistics2.PartitionStorageHint=Configura a Partição baseado em itens atualmente armazenados.
gui.tooltips.appliedenergistics2.ClearSettings=Limpar Configurações

View File

@ -169,8 +169,8 @@ gui.tooltips.appliedenergistics2.EmitLevelsBelow=Emite numai când nivelele sunt
gui.tooltips.appliedenergistics2.EmitLevelAbove=Emite când nivelele sunt peste sau egale cu limita.
gui.tooltips.appliedenergistics2.SearchMode_Auto=Auto Cercetare
gui.tooltips.appliedenergistics2.SearchMode_Standard=Cercetare Standard
gui.tooltips.appliedenergistics2.SearchMode_NEIAuto=Auto Sincronizat cu NEI
gui.tooltips.appliedenergistics2.SearchMode_NEIStandard=Sincronizat cu NEI Standard
gui.tooltips.appliedenergistics2.SearchMode_JEIAuto=Auto Sincronizat cu JEI
gui.tooltips.appliedenergistics2.SearchMode_JEIStandard=Sincronizat cu JEI Standard
gui.tooltips.appliedenergistics2.SearchMode=Modul de Cutie de Cercetare
gui.tooltips.appliedenergistics2.PartitionStorageHint=Configurează Partiţie bazat pe iteme stocate în momentul de faţă.
gui.tooltips.appliedenergistics2.ClearSettings=Şterge Configurație/Setări