From 9599a31893378b44d643ae9dd2453bcd92e3572e Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Sun, 14 Jun 2020 11:27:24 +0200 Subject: [PATCH] Removed Inscriber Recipe Registry Fixed Inscriber TESR rendering and added a small easing function --- README.md | 19 +- .../appeng/api/features/IInscriberRecipe.java | 83 ------- .../api/features/IInscriberRecipeBuilder.java | 107 --------- .../api/features/IInscriberRegistry.java | 97 -------- .../api/features/IRegistryContainer.java | 5 - .../client/render/tesr/InscriberTESR.java | 116 +++++----- .../implementations/ContainerInscriber.java | 82 ++----- .../container/slot/SlotRestrictedInput.java | 30 +-- src/main/java/appeng/core/Registration.java | 2 + .../registries/RegistryContainer.java | 9 - .../inscriber/InscriberInscribeRecipe.java | 45 ---- .../registries/inscriber/InscriberRecipe.java | 150 ------------- .../inscriber/InscriberRegistry.java | 211 ------------------ .../appeng/tile/misc/InscriberRecipes.java | 144 ++++++++++++ .../java/appeng/tile/misc/TileInscriber.java | 148 ++---------- 15 files changed, 258 insertions(+), 990 deletions(-) delete mode 100644 src/api/java/appeng/api/features/IInscriberRecipe.java delete mode 100644 src/api/java/appeng/api/features/IInscriberRecipeBuilder.java delete mode 100644 src/api/java/appeng/api/features/IInscriberRegistry.java delete mode 100644 src/main/java/appeng/core/features/registries/inscriber/InscriberInscribeRecipe.java delete mode 100644 src/main/java/appeng/core/features/registries/inscriber/InscriberRecipe.java delete mode 100644 src/main/java/appeng/core/features/registries/inscriber/InscriberRegistry.java create mode 100644 src/main/java/appeng/tile/misc/InscriberRecipes.java diff --git a/README.md b/README.md index c3339c069..9413656ca 100644 --- a/README.md +++ b/README.md @@ -159,25 +159,14 @@ An example string would be `appeng:appliedenergistics2:rv5-stable-1:api` for the ## Applied Energistics 2 CraftTweaker ### Inscriber -Add a recipe. When `inscribe` is true the bottom and top inputs are not consumed. - mods.appliedenergistics2.Inscriber.addRecipe(ItemStack output, ItemStack input, boolean inscribe, - @Optional ItemStack topInput, @Optional ItemStack bottomInput ); - -Remove all recipes for this output stack. - - mods.appliedenergistics2.Inscriber.removeRecipe(ItemStack output); +The inscriber uses the vanilla recipe system with a custom `type` of `appliedenergistics2:inscriber`. +See the [inscriber recipe folder](src/main/resources/data/appliedenergistics2/recipes/inscriber) for some examples. ### Grindstone -Add a recipe. - mods.appliedenergistics2.Grinder.addRecipe( ItemStack output, ItemStack input, int turns, - @Optional ItemStack secondary1Output, @Optional float secondary1Chance, - @Optional ItemStack secondary2Output, @Optional float secondary2Chance); - -Remove recipes for this input. - - mods.appliedenergistics2.Grinder.removeRecipe(ItemStack input); +The grindstone uses the vanilla recipe system with a custom `type` of `appliedenergistics2:grinder`. +See the [grinder recipe folder](src/main/resources/data/appliedenergistics2/recipes/grinder) for some examples. ### Spatial Whitelist a TileEntity class for Spatial IO. diff --git a/src/api/java/appeng/api/features/IInscriberRecipe.java b/src/api/java/appeng/api/features/IInscriberRecipe.java deleted file mode 100644 index 810c6138f..000000000 --- a/src/api/java/appeng/api/features/IInscriberRecipe.java +++ /dev/null @@ -1,83 +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 . - */ - -package appeng.api.features; - - -import java.util.List; -import java.util.Optional; - -import javax.annotation.Nonnull; - -import net.minecraft.item.ItemStack; - - -/** - * Registration Records for {@link IInscriberRegistry} - * - * You have to pay attention though, that recipes are not mirrored, - * where the top and bottom slots are switching places. - * - * This is applied on runtime. - * - * @author thatsIch - * @version rv2 - * @since rv2 - */ -public interface IInscriberRecipe -{ - /** - * the current inputs - * - * @return inputs the inscriber will accept - */ - @Nonnull - List getInputs(); - - /** - * gets the current output - * - * @return output that the recipe will produce - */ - @Nonnull - ItemStack getOutput(); - - /** - * gets the top optional - * - * @return item which is used top - */ - @Nonnull - Optional getTopOptional(); - - /** - * gets the bottom optional - * - * @return item which is used bottom - */ - @Nonnull - Optional getBottomOptional(); - - /** - * type of inscriber process - * - * @return type of process the inscriber is doing - */ - @Nonnull - InscriberProcessType getProcessType(); -} diff --git a/src/api/java/appeng/api/features/IInscriberRecipeBuilder.java b/src/api/java/appeng/api/features/IInscriberRecipeBuilder.java deleted file mode 100644 index a8ad18c38..000000000 --- a/src/api/java/appeng/api/features/IInscriberRecipeBuilder.java +++ /dev/null @@ -1,107 +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 . - */ - -package appeng.api.features; - - -import java.util.Collection; - -import javax.annotation.Nonnull; - -import net.minecraft.item.ItemStack; - - -/** - * Builder for an inscriber recipe - * - * @author thatsIch - * @version rv2 - * @since rv2 - */ -public interface IInscriberRecipeBuilder -{ - /** - * Creates an inscriber recipe with inputs. - * Needs to be invoked. - * - * @param inputs new inputs for the recipe - * - * @return currently used builder - */ - @Nonnull - IInscriberRecipeBuilder withInputs( @Nonnull Collection inputs ); - - /** - * Creates an inscriber recipe with output. - * Needs to be invoked. - * - * @param output new output for the recipe - * - * @return currently used builder - */ - @Nonnull - IInscriberRecipeBuilder withOutput( @Nonnull ItemStack output ); - - /** - * Creates an inscriber recipe with top. - * Either this or bot needs to be invoked. - * - * @param topOptional new top for the recipe - * - * @return currently used builder - */ - @Nonnull - IInscriberRecipeBuilder withTopOptional( @Nonnull ItemStack topOptional ); - - /** - * Creates an inscriber recipe with bot. - * Either this or top needs to be invoked. - * - * @param bottomOptional new bot for the recipe - * - * @return currently used builder - */ - @Nonnull - IInscriberRecipeBuilder withBottomOptional( @Nonnull ItemStack bottomOptional ); - - /** - * Creates an inscriber recipe with type. - * Needs to be invoked. - * - * @param type new type for the recipe - * - * @return currently used builder - */ - @Nonnull - IInscriberRecipeBuilder withProcessType( @Nonnull InscriberProcessType type ); - - /** - * Finalizes the process of making the recipe. - * Needs to be invoked to fetch inscriber recipe. - * - * @return legal inscriber recipe - * - * @throws IllegalStateException when input is not defined - * @throws IllegalStateException when input has no size - * @throws IllegalStateException when output is not defined - * @throws IllegalStateException when both optionals are not defined - * @throws IllegalStateException when process type is not defined - */ - @Nonnull - IInscriberRecipe build(); -} diff --git a/src/api/java/appeng/api/features/IInscriberRegistry.java b/src/api/java/appeng/api/features/IInscriberRegistry.java deleted file mode 100644 index 3c931fcf7..000000000 --- a/src/api/java/appeng/api/features/IInscriberRegistry.java +++ /dev/null @@ -1,97 +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 . - */ - -package appeng.api.features; - - -import java.util.Collection; -import java.util.Set; - -import javax.annotation.Nonnull; - -import net.minecraft.item.ItemStack; - - -/** - * Lets you manipulate Inscriber Recipes, by adding or editing existing ones. - * - * @author thatsIch - * @version rv5 - * @since rv2 - */ -public interface IInscriberRegistry -{ - /** - * Extensible way to create an inscriber recipe. - * - * @return builder for inscriber recipes - */ - @Nonnull - IInscriberRecipeBuilder builder(); - - /** - * An immutable copy of currently registered recipes. - * - * Use the provided methods to actually modify the inscriber recipes. - * - * @see IInscriberRegistry#addRecipe(IInscriberRecipe) - * @see IInscriberRegistry#removeRecipe(IInscriberRecipe) - * - * @return currentlyRegisteredRecipes - */ - @Nonnull - Collection getRecipes(); - - /** - * Optional items which are used in the top or bottom slot. - * - * @return set of all optional items - */ - @Nonnull - Set getOptionals(); - - /** - * Get all registered items which are valid inputs. - * - * @return set of all input items - */ - @Nonnull - Set getInputs(); - - /** - * add a new recipe the easy way, duplicates will not be added. - * Added recipes will be automatically added to the optionals and inputs. - * - * @param recipe new recipe - * - * @return true, when successfully added - * - * @throws IllegalArgumentException if null is added - */ - boolean addRecipe( IInscriberRecipe recipe ); - - /** - * Removes all equal recipes from the registry. - * - * @param toBeRemovedRecipe to be removed recipe, can be null, makes just no sense. - * - * @return true, when successfully removed - */ - boolean removeRecipe( IInscriberRecipe toBeRemovedRecipe ); - -} diff --git a/src/api/java/appeng/api/features/IRegistryContainer.java b/src/api/java/appeng/api/features/IRegistryContainer.java index 7b3f97f2f..114325ff6 100644 --- a/src/api/java/appeng/api/features/IRegistryContainer.java +++ b/src/api/java/appeng/api/features/IRegistryContainer.java @@ -67,11 +67,6 @@ public interface IRegistryContainer */ ICellRegistry cell(); - /** - * Manage inscriber recipes via API - */ - IInscriberRegistry inscriber(); - /** * Manage charger via API */ diff --git a/src/main/java/appeng/client/render/tesr/InscriberTESR.java b/src/main/java/appeng/client/render/tesr/InscriberTESR.java index c3a908b2a..a2391402e 100644 --- a/src/main/java/appeng/client/render/tesr/InscriberTESR.java +++ b/src/main/java/appeng/client/render/tesr/InscriberTESR.java @@ -2,25 +2,31 @@ package appeng.client.render.tesr; +import appeng.recipes.handlers.InscriberRecipe; import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.IVertexBuilder; +import com.mojang.blaze3d.vertex.MatrixApplyingVertexBuilder; import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.model.ItemCameraTransforms; +import net.minecraft.client.renderer.model.Material; +import net.minecraft.client.renderer.texture.AtlasTexture; +import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.tileentity.TileEntityRenderer; +import net.minecraft.inventory.container.PlayerContainer; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.TextureStitchEvent; +import net.minecraftforge.client.model.pipeline.TransformerConsumer; import net.minecraftforge.items.IItemHandler; -import appeng.api.features.IInscriberRecipe; import appeng.client.render.FacingToRotation; import appeng.core.AppEng; -import appeng.tile.AEBaseTile; import appeng.tile.misc.TileInscriber; @@ -32,14 +38,20 @@ public final class InscriberTESR extends TileEntityRenderer private static final float ITEM_RENDER_SCALE = 1.0f / 1.2f; - private static final ResourceLocation TEXTURE_INSIDE = new ResourceLocation( AppEng.MOD_ID, "block/inscriber_inside" ); - - private static TextureAtlasSprite textureInside; + private static final Material TEXTURE_INSIDE = new Material(PlayerContainer.LOCATION_BLOCKS_TEXTURE, new ResourceLocation( AppEng.MOD_ID, "block/inscriber_inside" )); public InscriberTESR(TileEntityRendererDispatcher rendererDispatcherIn) { super(rendererDispatcherIn); } + // See https://easings.net/#easeOutBack + private static float ease(float x) { + float c1 = 1.70158f; + float c3 = c1 + 1; + + return (float) (1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2)); + } + @Override public void render(TileInscriber tile, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffers, int combinedLight, int combinedOverlay) { @@ -50,22 +62,8 @@ public final class InscriberTESR extends TileEntityRenderer FacingToRotation.get( tile.getForward(), tile.getUp() ).push(ms); ms.translate( -0.5F, -0.5F, -0.5F ); - // FIXME RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); - // FIXME RenderSystem.disableLighting(); - // FIXME RenderSystem.disableRescaleNormal(); - // render sides of stamps - Minecraft mc = Minecraft.getInstance(); -// FIXME RenderingEngine.getInstance().bindTexture( AtlasTexture.LOCATION_BLOCKS_TEXTURE ); - - // << 20 | light << 4; - // FIXME final int br = combinedLight; - // FIXME final int var11 = br % 65536; - // FIXME final int var12 = br / 65536; - - // FIXME OpenGlHelper.setLightmapTextureCoords( OpenGlHelper.lightmapTexUnit, var11, var12 ); - long absoluteProgress = 0; if( tile.isSmash() ) @@ -84,51 +82,49 @@ public final class InscriberTESR extends TileEntityRenderer if( progress > 1.0f ) { progress = 1.0f - ( progress - 1.0f ); + } else { + // Only apply the easing function on the way down + progress = ease(progress); } + float press = 0.2f; press -= progress / 5.0f; - IVertexBuilder buffer = buffers.getBuffer(RenderType.getSolid()); - -// final BufferBuilder buffer = Tessellator.getInstance().getBuffer(); - // FIXME buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX ); - float middle = 0.5f; middle += 0.02f; final float TwoPx = 2.0f / 16.0f; final float base = 0.4f; - final TextureAtlasSprite tas = textureInside; - if( tas != null ) - { - // Bottom of Top Stamp - buffer.pos( TwoPx, middle + press, TwoPx ).tex( tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 13 ) ).endVertex(); - buffer.pos( 1.0 - TwoPx, middle + press, TwoPx ).tex( tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 13 ) ).endVertex(); - buffer.pos( 1.0 - TwoPx, middle + press, 1.0 - TwoPx ).tex( tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 2 ) ).endVertex(); - buffer.pos( TwoPx, middle + press, 1.0 - TwoPx ).tex( tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 2 ) ).endVertex(); + final TextureAtlasSprite tas = TEXTURE_INSIDE.getSprite(); - // Front of Top Stamp - buffer.pos( TwoPx, middle + base, TwoPx ).tex( tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 3 - 16 * ( press - base ) ) ).endVertex(); - buffer.pos( 1.0 - TwoPx, middle + base, TwoPx ).tex( tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 3 - 16 * ( press - base ) ) ).endVertex(); - buffer.pos( 1.0 - TwoPx, middle + press, TwoPx ).tex( tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 3 ) ).endVertex(); - buffer.pos( TwoPx, middle + press, TwoPx ).tex( tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 3 ) ).endVertex(); + IVertexBuilder buffer = buffers.getBuffer(RenderType.getSolid()); - // Top of Bottom Stamp - middle -= 2.0f * 0.02f; - buffer.pos( 1.0 - TwoPx, middle - press, TwoPx ).tex( tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 13 ) ).endVertex(); - buffer.pos( TwoPx, middle - press, TwoPx ).tex( tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 13 ) ).endVertex(); - buffer.pos( TwoPx, middle - press, 1.0 - TwoPx ).tex( tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 2 ) ).endVertex(); - buffer.pos( 1.0 - TwoPx, middle - press, 1.0 - TwoPx ).tex( tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 2 ) ).endVertex(); + // Bottom of Top Stamp + addVertex( buffer, ms, TwoPx, middle + press, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 13 ), combinedOverlay, combinedLight, 0, -1, 0); + addVertex( buffer, ms, 1.0f - TwoPx, middle + press, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 13 ), combinedOverlay, combinedLight, 0, -1, 0); + addVertex( buffer, ms, 1.0f - TwoPx, middle + press, 1.0f - TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 2 ), combinedOverlay, combinedLight, 0, -1, 0); + addVertex( buffer, ms, TwoPx, middle + press, 1.0f - TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 2 ), combinedOverlay, combinedLight, 0, -1, 0); - // Front of Bottom Stamp - buffer.pos( 1.0 - TwoPx, middle + -base, TwoPx ).tex( tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 3 - 16 * ( press - base ) ) ).endVertex(); - buffer.pos( TwoPx, middle - base, TwoPx ).tex( tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 3 - 16 * ( press - base ) ) ).endVertex(); - buffer.pos( TwoPx, middle - press, TwoPx ).tex( tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 3 ) ).endVertex(); - buffer.pos( 1.0 - TwoPx, middle - press, TwoPx ).tex( tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 3 ) ).endVertex(); - } + // Front of Top Stamp + addVertex( buffer, ms, TwoPx, middle + base, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 3 - 16 * ( press - base ) ), combinedOverlay, combinedLight, 0, 0, -1); + addVertex( buffer, ms, 1.0f - TwoPx, middle + base, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 3 - 16 * ( press - base ) ), combinedOverlay, combinedLight, 0, 0, -1); + addVertex( buffer, ms, 1.0f - TwoPx, middle + press, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 3 ), combinedOverlay, combinedLight, 0, 0, -1); + addVertex( buffer, ms, TwoPx, middle + press, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 3 ), combinedOverlay, combinedLight, 0, 0, -1); + + // Top of Bottom Stamp + middle -= 2.0f * 0.02f; + addVertex( buffer, ms, 1.0f - TwoPx, middle - press, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 13 ), combinedOverlay, combinedLight, 0, 1, 0); + addVertex( buffer, ms, TwoPx, middle - press, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 13 ), combinedOverlay, combinedLight, 0, 1, 0); + addVertex( buffer, ms, TwoPx, middle - press, 1.0f - TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 2 ), combinedOverlay, combinedLight, 0, 1, 0); + addVertex( buffer, ms, 1.0f - TwoPx, middle - press, 1.0f - TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 2 ), combinedOverlay, combinedLight, 0, 1, 0); + + // Front of Bottom Stamp + addVertex( buffer, ms, 1.0f - TwoPx, middle + -base, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 3 - 16 * ( press - base ) ), combinedOverlay, combinedLight, 0, 0, -1); + addVertex( buffer, ms, TwoPx, middle - base, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 3 - 16 * ( press - base ) ), combinedOverlay, combinedLight, 0, 0, -1); + addVertex( buffer, ms, TwoPx, middle - press, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 14 ), tas.getInterpolatedV( 3 ), combinedOverlay, combinedLight, 0, 0, -1); + addVertex( buffer, ms, 1.0f - TwoPx, middle - press, TwoPx, 1, 1, 1, 1, tas.getInterpolatedU( 2 ), tas.getInterpolatedV( 3 ), combinedOverlay, combinedLight, 0, 0, -1); // render items. -// FIXME RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F ); IItemHandler tileInv = tile.getInternalInventory(); @@ -152,7 +148,7 @@ public final class InscriberTESR extends TileEntityRenderer if( is.isEmpty() ) { - final IInscriberRecipe ir = tile.getTask(); + final InscriberRecipe ir = tile.getTask(); if( ir != null ) { is = ir.getOutput().copy(); @@ -169,8 +165,16 @@ public final class InscriberTESR extends TileEntityRenderer } ms.pop(); - // FIXME RenderSystem.enableLighting(); - // FIXME GlStateManager.enableRescaleNormal(); + } + + private static void addVertex(IVertexBuilder vb, MatrixStack ms, float x, float y, float z, float red, float green, float blue, float alpha, float texU, float texV, int overlayUV, int lightmapUV, float normalX, float normalY, float normalZ) { + vb.pos(ms.getLast().getMatrix(), x, y, z); + vb.color(red, green, blue, alpha); + vb.tex(texU, texV); + vb.overlay(overlayUV); + vb.lightmap(lightmapUV); + vb.normal(ms.getLast().getNormal(), normalX, normalY, normalZ); + vb.endVertex(); } private void renderItem( MatrixStack ms, final ItemStack stack, final float o, IRenderTypeBuffer buffers, int combinedLight, int combinedOverlay ) @@ -197,8 +201,10 @@ public final class InscriberTESR extends TileEntityRenderer } } - public static void registerTexture( TextureStitchEvent.Pre event ) + public static void registerTexture( TextureStitchEvent.Pre evt ) { - // FIXME textureInside = event.getMap().registerSprite( TEXTURE_INSIDE ); + if (evt.getMap().getTextureLocation().equals(TEXTURE_INSIDE.getAtlasLocation())) { + evt.addSprite(TEXTURE_INSIDE.getTextureLocation()); + } } } diff --git a/src/main/java/appeng/container/implementations/ContainerInscriber.java b/src/main/java/appeng/container/implementations/ContainerInscriber.java index 0a517cbf3..ae590a454 100644 --- a/src/main/java/appeng/container/implementations/ContainerInscriber.java +++ b/src/main/java/appeng/container/implementations/ContainerInscriber.java @@ -21,13 +21,13 @@ package appeng.container.implementations; import appeng.api.AEApi; import appeng.api.definitions.IItemDefinition; -import appeng.api.features.IInscriberRecipe; import appeng.container.ContainerLocator; import appeng.container.guisync.GuiSync; import appeng.container.helper.TileContainerHelper; import appeng.container.interfaces.IProgressProvider; import appeng.container.slot.SlotOutput; import appeng.container.slot.SlotRestrictedInput; +import appeng.tile.misc.InscriberRecipes; import appeng.tile.misc.TileInscriber; import appeng.util.Platform; import net.minecraft.entity.player.PlayerEntity; @@ -80,12 +80,15 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres IItemHandler inv = te.getInternalInventory(); - this.addSlot( - this.top = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.INSCRIBER_PLATE, inv, 0, 45, 16, this.getPlayerInventory() ) ); - this.addSlot( - this.bottom = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.INSCRIBER_PLATE, inv, 1, 45, 62, this.getPlayerInventory() ) ); - this.addSlot( - this.middle = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.INSCRIBER_INPUT, inv, 2, 63, 39, this.getPlayerInventory() ) ); + SlotRestrictedInput top = new SlotRestrictedInput(SlotRestrictedInput.PlacableItemType.INSCRIBER_PLATE, inv, 0, 45, 16, this.getPlayerInventory()); + top.setStackLimit(1); + this.top = this.addSlot(top); + SlotRestrictedInput bottom = new SlotRestrictedInput(SlotRestrictedInput.PlacableItemType.INSCRIBER_PLATE, inv, 1, 45, 62, this.getPlayerInventory()); + bottom.setStackLimit(1); + this.bottom = this.addSlot(bottom); + SlotRestrictedInput middle = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.INSCRIBER_INPUT, inv, 2, 63, 39, this.getPlayerInventory() ); + middle.setStackLimit(1); + this.middle = this.addSlot(middle); this.addSlot( new SlotOutput( inv, 3, 113, 40, -1 ) ); } @@ -143,75 +146,26 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres return !press.isSameAs( is ); } - boolean matches = false; - for( final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes() ) - { - final boolean matchA = !top - .isEmpty() && ( Platform.itemComparisons().isSameItem( top, recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) || Platform - .itemComparisons() - .isSameItem( top, recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) ); - final boolean matchB = !bot - .isEmpty() && ( Platform.itemComparisons().isSameItem( bot, recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) || Platform - .itemComparisons() - .isSameItem( bot, recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) ); - - if( matchA || matchB ) - { - matches = true; - for( final ItemStack option : recipe.getInputs() ) - { - if( Platform.itemComparisons().isSameItem( is, option ) ) - { - return true; - } - } - } - } - if( matches ) - { - return false; - } + return InscriberRecipes.findRecipe(ti.getWorld(), is, top, bot, false) != null; } - else if( ( s == this.top && !bot.isEmpty() ) || ( s == this.bottom && !top.isEmpty() ) ) - { + else if( ( s == this.top && !bot.isEmpty() ) || ( s == this.bottom && !top.isEmpty() ) ) { ItemStack otherSlot; - if( s == this.top ) - { + if (s == this.top) { otherSlot = this.bottom.getStack(); - } - else - { + } else { otherSlot = this.top.getStack(); } // name presses final IItemDefinition namePress = AEApi.instance().definitions().materials().namePress(); - if( namePress.isSameAs( otherSlot ) ) - { - return namePress.isSameAs( is ); + if (namePress.isSameAs(otherSlot)) { + return namePress.isSameAs(is); } // everything else - for( final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes() ) - { - boolean isValid = false; - if( Platform.itemComparisons().isSameItem( otherSlot, recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) ) - { - isValid = Platform.itemComparisons().isSameItem( is, recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ); - } - else if( Platform.itemComparisons().isSameItem( otherSlot, recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) ) - { - isValid = Platform.itemComparisons().isSameItem( is, recipe.getTopOptional().orElse( ItemStack.EMPTY ) ); - } - - if( isValid ) - { - return true; - } - } - return false; + // test for a partial recipe match (ignoring the middle slot) + return InscriberRecipes.isValidOptionalIngredientCombination(ti.getWorld(), is, otherSlot); } - return true; } diff --git a/src/main/java/appeng/container/slot/SlotRestrictedInput.java b/src/main/java/appeng/container/slot/SlotRestrictedInput.java index 6e1d353be..439ea7e50 100644 --- a/src/main/java/appeng/container/slot/SlotRestrictedInput.java +++ b/src/main/java/appeng/container/slot/SlotRestrictedInput.java @@ -19,7 +19,9 @@ package appeng.container.slot; +import appeng.items.misc.ItemEncodedPattern; import appeng.recipes.handlers.GrinderRecipes; +import appeng.tile.misc.InscriberRecipes; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.Slot; @@ -169,15 +171,7 @@ public class SlotRestrictedInput extends AppEngSlot return true; } - for( final ItemStack optional : AEApi.instance().registries().inscriber().getOptionals() ) - { - if( Platform.itemComparisons().isSameItem( i, optional ) ) - { - return true; - } - } - - return false; + return InscriberRecipes.isValidOptionalIngredient(p.player.world, i); case INSCRIBER_INPUT: return true;/* @@ -244,15 +238,15 @@ public class SlotRestrictedInput extends AppEngSlot if( Platform.isClient() && ( this.which == PlacableItemType.ENCODED_PATTERN ) ) { final ItemStack is = super.getStack(); - // FIXME if( !is.isEmpty() && is.getItem() instanceof ItemEncodedPattern ) - // FIXME { - // FIXME final ItemEncodedPattern iep = (ItemEncodedPattern) is.getItem(); - // FIXME final ItemStack out = iep.getOutput( is ); - // FIXME if( !out.isEmpty() ) - // FIXME { - // FIXME return out; - // FIXME } - // FIXME } + if( !is.isEmpty() && is.getItem() instanceof ItemEncodedPattern) + { + final ItemEncodedPattern iep = (ItemEncodedPattern) is.getItem(); + final ItemStack out = iep.getOutput( is ); + if( !out.isEmpty() ) + { + return out; + } + } } return super.getStack(); } diff --git a/src/main/java/appeng/core/Registration.java b/src/main/java/appeng/core/Registration.java index 213fc15ad..525a213ce 100644 --- a/src/main/java/appeng/core/Registration.java +++ b/src/main/java/appeng/core/Registration.java @@ -44,6 +44,7 @@ import appeng.client.render.model.BiometricCardModel; import appeng.client.render.model.DriveModel; import appeng.client.render.model.MemoryCardModel; import appeng.client.render.model.SkyCompassModel; +import appeng.client.render.tesr.InscriberTESR; import appeng.client.render.tesr.SkyChestTESR; import appeng.container.AEBaseContainer; import appeng.container.ContainerOpener; @@ -769,6 +770,7 @@ final class Registration public void registerTextures(TextureStitchEvent.Pre event) { SkyChestTESR.registerTextures(event); + InscriberTESR.registerTexture(event); } public void registerCommands( final FMLServerStartingEvent evt ) diff --git a/src/main/java/appeng/core/features/registries/RegistryContainer.java b/src/main/java/appeng/core/features/registries/RegistryContainer.java index efc731413..3c5141a36 100644 --- a/src/main/java/appeng/core/features/registries/RegistryContainer.java +++ b/src/main/java/appeng/core/features/registries/RegistryContainer.java @@ -20,7 +20,6 @@ package appeng.core.features.registries; import appeng.api.features.IChargerRegistry; -import appeng.api.features.IInscriberRegistry; import appeng.api.features.ILocatableRegistry; import appeng.api.features.IMatterCannonAmmoRegistry; import appeng.api.features.IP2PTunnelRegistry; @@ -35,7 +34,6 @@ import appeng.api.parts.IPartModels; import appeng.api.storage.ICellRegistry; import appeng.core.features.registries.cell.CellRegistry; import appeng.core.features.registries.charger.ChargerRegistry; -import appeng.core.features.registries.inscriber.InscriberRegistry; /** @@ -49,7 +47,6 @@ import appeng.core.features.registries.inscriber.InscriberRegistry; */ public class RegistryContainer implements IRegistryContainer { - private final IInscriberRegistry inscriber = new InscriberRegistry(); private final IChargerRegistry charger = new ChargerRegistry(); private final ICellRegistry cell = new CellRegistry(); private final ILocatableRegistry locatable = new LocatableRegistry(); @@ -92,12 +89,6 @@ public class RegistryContainer implements IRegistryContainer return this.cell; } - @Override - public IInscriberRegistry inscriber() - { - return this.inscriber; - } - @Override public IChargerRegistry charger() { diff --git a/src/main/java/appeng/core/features/registries/inscriber/InscriberInscribeRecipe.java b/src/main/java/appeng/core/features/registries/inscriber/InscriberInscribeRecipe.java deleted file mode 100644 index 0b367f1c8..000000000 --- a/src/main/java/appeng/core/features/registries/inscriber/InscriberInscribeRecipe.java +++ /dev/null @@ -1,45 +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 . - */ - -package appeng.core.features.registries.inscriber; - - -import java.util.Collection; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import net.minecraft.item.ItemStack; - -import appeng.api.features.InscriberProcessType; - - -/** - * inscribe recipes do not use up the provided optional upon craft - * - * @author thatsIch - * @version rv2 - * @since rv2 - */ -public class InscriberInscribeRecipe extends InscriberRecipe -{ - InscriberInscribeRecipe( @Nonnull final Collection inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot ) - { - super( inputs, output, top, bot, InscriberProcessType.INSCRIBE ); - } -} diff --git a/src/main/java/appeng/core/features/registries/inscriber/InscriberRecipe.java b/src/main/java/appeng/core/features/registries/inscriber/InscriberRecipe.java deleted file mode 100644 index 820ae8a55..000000000 --- a/src/main/java/appeng/core/features/registries/inscriber/InscriberRecipe.java +++ /dev/null @@ -1,150 +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 . - */ - -package appeng.core.features.registries.inscriber; - - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import net.minecraft.item.ItemStack; - -import appeng.api.features.IInscriberRecipe; -import appeng.api.features.InscriberProcessType; - - -/** - * Basic inscriber recipe - * - * @author thatsIch - * @version rv2 - * @since rv2 - */ -public class InscriberRecipe implements IInscriberRecipe -{ - @Nonnull - private final List inputs; - - @Nonnull - private final ItemStack output; - - @Nonnull - private final Optional maybeTop; - - @Nonnull - private final Optional maybeBot; - - @Nonnull - private final InscriberProcessType type; - - InscriberRecipe( @Nonnull final Collection inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot, @Nonnull final InscriberProcessType type ) - { - this.inputs = new ArrayList<>( inputs.size() ); - this.inputs.addAll( inputs ); - - this.output = output; - this.maybeTop = Optional.ofNullable( top ); - this.maybeBot = Optional.ofNullable( bot ); - - this.type = type; - } - - @Nonnull - @Override - public final List getInputs() - { - return this.inputs; - } - - @Nonnull - @Override - public final ItemStack getOutput() - { - return this.output; - } - - @Nonnull - @Override - public final Optional getTopOptional() - { - return this.maybeTop; - } - - @Nonnull - @Override - public final Optional getBottomOptional() - { - return this.maybeBot; - } - - @Nonnull - @Override - public final InscriberProcessType getProcessType() - { - return this.type; - } - - @Override - public boolean equals( final Object o ) - { - if( this == o ) - { - return true; - } - if( !( o instanceof IInscriberRecipe ) ) - { - return false; - } - - final IInscriberRecipe that = (IInscriberRecipe) o; - - if( !this.inputs.equals( that.getInputs() ) ) - { - return false; - } - if( !this.output.equals( that.getOutput() ) ) - { - return false; - } - if( !this.maybeTop.equals( that.getTopOptional() ) ) - { - return false; - } - if( !this.maybeBot.equals( that.getBottomOptional() ) ) - { - return false; - } - return this.type == that.getProcessType(); - } - - @Override - public int hashCode() - { - int result = this.inputs.hashCode(); - result = 31 * result + this.output.hashCode(); - result = 31 * result + this.maybeTop.hashCode(); - result = 31 * result + this.maybeBot.hashCode(); - result = 31 * result + this.type.hashCode(); - return result; - } -} diff --git a/src/main/java/appeng/core/features/registries/inscriber/InscriberRegistry.java b/src/main/java/appeng/core/features/registries/inscriber/InscriberRegistry.java deleted file mode 100644 index 7bd3e33b2..000000000 --- a/src/main/java/appeng/core/features/registries/inscriber/InscriberRegistry.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * This file is part of Applied Energistics 2. - * Copyright (c) 2013 - 2015, 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 . - */ - -package appeng.core.features.registries.inscriber; - - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import javax.annotation.Nonnull; - -import com.google.common.base.Preconditions; - -import net.minecraft.item.ItemStack; - -import appeng.api.features.IInscriberRecipe; -import appeng.api.features.IInscriberRecipeBuilder; -import appeng.api.features.IInscriberRegistry; -import appeng.api.features.InscriberProcessType; - - -/** - * @author thatsIch - * @version rv3 - * @since rv2 - */ -public final class InscriberRegistry implements IInscriberRegistry -{ - private final Set recipes; - private final Set optionals; - private final Set inputs; - - public InscriberRegistry() - { - this.inputs = new HashSet<>(); - this.optionals = new HashSet<>(); - this.recipes = new HashSet<>(); - } - - @Nonnull - @Override - public Collection getRecipes() - { - return Collections.unmodifiableCollection( this.recipes ); - } - - @Nonnull - @Override - public Set getOptionals() - { - return this.optionals; - } - - @Nonnull - @Override - public Set getInputs() - { - return this.inputs; - } - - @Nonnull - @Override - public IInscriberRecipeBuilder builder() - { - return new Builder(); - } - - @Override - public boolean addRecipe( final IInscriberRecipe recipe ) - { - Preconditions.checkNotNull( recipe, "Tried to add (null) as inscriber recipe to the registry." ); - - if( this.recipes.add( recipe ) ) - { - recipe.getTopOptional().ifPresent( this.optionals::add ); - recipe.getBottomOptional().ifPresent( this.optionals::add ); - - this.inputs.addAll( recipe.getInputs() ); - - return true; - } - - return false; - } - - @Override - public boolean removeRecipe( final IInscriberRecipe toBeRemovedRecipe ) - { - Preconditions.checkNotNull( toBeRemovedRecipe, "Tried to remove (null) from the registry." ); - - boolean changed = false; - - for( final Iterator iterator = this.recipes.iterator(); iterator.hasNext(); ) - { - final IInscriberRecipe recipe = iterator.next(); - if( recipe.equals( toBeRemovedRecipe ) ) - { - changed = true; - iterator.remove(); - } - } - - return changed; - } - - /** - * Internal {@link IInscriberRecipeBuilder} implementation. - * Needs to be adapted to represent a correct {@link IInscriberRecipe} - */ - private static final class Builder implements IInscriberRecipeBuilder - { - private List inputs; - private ItemStack output; - private ItemStack topOptional; - private ItemStack bottomOptional; - private InscriberProcessType type; - - @Nonnull - @Override - public Builder withInputs( @Nonnull final Collection inputs ) - { - Preconditions.checkNotNull( inputs ); - Preconditions.checkArgument( !inputs.isEmpty() ); - - this.inputs = new ArrayList<>( inputs.size() ); - this.inputs.addAll( inputs ); - - return this; - } - - @Nonnull - @Override - public Builder withOutput( @Nonnull final ItemStack output ) - { - Preconditions.checkNotNull( output ); - Preconditions.checkArgument( !output.isEmpty() ); - - this.output = output; - - return this; - } - - @Nonnull - @Override - public Builder withTopOptional( @Nonnull final ItemStack topOptional ) - { - Preconditions.checkNotNull( topOptional ); - Preconditions.checkArgument( !topOptional.isEmpty() ); - - this.topOptional = topOptional; - - return this; - } - - @Nonnull - @Override - public Builder withBottomOptional( @Nonnull final ItemStack bottomOptional ) - { - Preconditions.checkNotNull( bottomOptional ); - Preconditions.checkArgument( !bottomOptional.isEmpty() ); - - this.bottomOptional = bottomOptional; - - return this; - } - - @Nonnull - @Override - public Builder withProcessType( @Nonnull final InscriberProcessType type ) - { - Preconditions.checkNotNull( type ); - - this.type = type; - - return this; - } - - @Nonnull - @Override - public IInscriberRecipe build() - { - Preconditions.checkState( this.inputs != null, "Input must be defined." ); - Preconditions.checkState( !this.inputs.isEmpty(), "Input must have a size." ); - Preconditions.checkState( !this.output.isEmpty(), "Output cannot be empty." ); - Preconditions.checkState( !this.topOptional.isEmpty() || !this.bottomOptional.isEmpty(), "One optional must be defined." ); - Preconditions.checkState( this.type != null, "Process type must be defined." ); - - return new InscriberRecipe( this.inputs, this.output, this.topOptional, this.bottomOptional, this.type ); - } - } -} diff --git a/src/main/java/appeng/tile/misc/InscriberRecipes.java b/src/main/java/appeng/tile/misc/InscriberRecipes.java new file mode 100644 index 000000000..f37fa62f3 --- /dev/null +++ b/src/main/java/appeng/tile/misc/InscriberRecipes.java @@ -0,0 +1,144 @@ +package appeng.tile.misc; + +import appeng.api.AEApi; +import appeng.api.definitions.IComparableDefinition; +import appeng.api.features.InscriberProcessType; +import appeng.core.AppEng; +import appeng.recipes.handlers.InscriberRecipe; +import com.google.common.collect.Iterables; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +import javax.annotation.Nullable; +import java.util.Collection; + +/** + * This class indexes all inscriber recipes to find valid inputs for the top and bottom + * optional slots. This speeds up checks whether inputs for those two slots are valid. + */ +public final class InscriberRecipes { + + public static final ResourceLocation NAMEPLATE_RECIPE_ID = new ResourceLocation(AppEng.MOD_ID, "nameplate"); + + private InscriberRecipes() { + } + + /** + * Returns an unmodifiable view of all registered inscriber recipes. + */ + public static Iterable getRecipes(World world) { + Collection> unfilteredRecipes = world.getRecipeManager().getRecipes(InscriberRecipe.TYPE).values(); + return Iterables.filter(unfilteredRecipes, InscriberRecipe.class); + } + + @Nullable + public static InscriberRecipe findRecipe(World world, ItemStack input, ItemStack plateA, ItemStack plateB, boolean supportNamePress) { + if (supportNamePress) { + IComparableDefinition namePress = AEApi.instance().definitions().materials().namePress(); + boolean isNameA = namePress.isSameAs(plateA); + boolean isNameB = namePress.isSameAs(plateB); + + if ((isNameA && isNameB) || isNameA && plateB.isEmpty()) { + return makeNamePressRecipe(input, plateA, plateB); + } else if (plateA.isEmpty() && isNameB) { + return makeNamePressRecipe(input, plateB, plateA); + } + } + + for( final InscriberRecipe recipe : getRecipes(world) ) + { + // The recipe can be flipped at will + final boolean matchA = recipe.getTopOptional().test(plateA) && recipe.getBottomOptional().test(plateB); + final boolean matchB = recipe.getTopOptional().test(plateB) && recipe.getBottomOptional().test(plateA); + + if( matchA || matchB ) + { + if (recipe.getMiddleInput().test(input)) { + return recipe; + } + } + } + + return null; + } + + private static InscriberRecipe makeNamePressRecipe( ItemStack input, ItemStack plateA, ItemStack plateB ) + { + String name = ""; + + if( !plateA.isEmpty() ) + { + final CompoundNBT tag = plateA.getOrCreateTag(); + name += tag.getString( "InscribeName" ); + } + + if( !plateB.isEmpty() ) + { + final CompoundNBT tag = plateB.getOrCreateTag(); + name += " " + tag.getString( "InscribeName" ); + } + + final Ingredient startingItem = Ingredient.fromStacks(input.copy()); + final ItemStack renamedItem = input.copy(); + + final CompoundNBT display = renamedItem.getOrCreateChildTag( "display" ); + if( !name.isEmpty() ) + { + display.putString("Name", name); + } + else + { + display.remove( "Name" ); + } + + final InscriberProcessType type = InscriberProcessType.INSCRIBE; + + return new InscriberRecipe( + NAMEPLATE_RECIPE_ID, + "", + startingItem, + renamedItem, + plateA.isEmpty() ? Ingredient.EMPTY : Ingredient.fromStacks(plateA), + plateB.isEmpty() ? Ingredient.EMPTY : Ingredient.fromStacks(plateB), + type + ); + } + + /** + * Checks if there is an inscriber recipe that supports the given combination of top/bottom presses. + * Both the given combination and the reverse will be searched. + */ + public static boolean isValidOptionalIngredientCombination(World world, ItemStack pressA, ItemStack pressB) { + for (InscriberRecipe recipe : getRecipes(world)) { + if (recipe.getTopOptional().test(pressA) && recipe.getBottomOptional().test(pressB) + || recipe.getTopOptional().test(pressB) && recipe.getBottomOptional().test(pressA)) + { + return true; + } + } + + return false; + } + + /** + * Checks if there is an inscriber recipe that would use the given item stack as an optional ingredient. + * Bottom and top can be used interchangeably here, because the inscriber will flip the recipe if needed. + */ + public static boolean isValidOptionalIngredient(World world, ItemStack is) { + for (InscriberRecipe recipe : getRecipes(world)) { + if (recipe.getTopOptional().test(is) + || recipe.getBottomOptional().test(is)) + { + return true; + } + } + + return false; + } + +} diff --git a/src/main/java/appeng/tile/misc/TileInscriber.java b/src/main/java/appeng/tile/misc/TileInscriber.java index dde8f10c9..4b3f72be3 100644 --- a/src/main/java/appeng/tile/misc/TileInscriber.java +++ b/src/main/java/appeng/tile/misc/TileInscriber.java @@ -26,7 +26,7 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import com.google.common.collect.Lists; +import appeng.recipes.handlers.InscriberRecipe; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; @@ -42,10 +42,7 @@ import appeng.api.AEApi; import appeng.api.config.Actionable; import appeng.api.config.PowerMultiplier; import appeng.api.config.Upgrades; -import appeng.api.definitions.IComparableDefinition; import appeng.api.definitions.ITileDefinition; -import appeng.api.features.IInscriberRecipe; -import appeng.api.features.IInscriberRecipeBuilder; import appeng.api.features.InscriberProcessType; import appeng.api.implementations.IUpgradeableHost; import appeng.api.networking.IGridNode; @@ -65,7 +62,6 @@ import appeng.tile.grid.AENetworkPowerTile; import appeng.tile.inventory.AppEngInternalInventory; import appeng.util.ConfigManager; import appeng.util.IConfigManagerHost; -import appeng.util.Platform; import appeng.util.inv.InvOperation; import appeng.util.inv.WrapperChainedItemHandler; import appeng.util.inv.WrapperFilteredItemHandler; @@ -98,7 +94,7 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable, private final IItemHandler bottomItemHandlerExtern; private final IItemHandler sideItemHandlerExtern; - private IInscriberRecipe cachedTask = null; + private InscriberRecipe cachedTask = null; private final IItemHandlerModifiable inv = new WrapperChainedItemHandler( this.topItemHandler, this.bottomItemHandler, this.sideItemHandler ); @@ -278,79 +274,24 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable, } @Nullable - public IInscriberRecipe getTask() + public InscriberRecipe getTask() { - if( this.cachedTask == null ) + if ( this.cachedTask == null && world != null ) { - this.cachedTask = this.getTask( this.sideItemHandler.getStackInSlot( 0 ), this.topItemHandler.getStackInSlot( 0 ), - this.bottomItemHandler.getStackInSlot( 0 ) ); + ItemStack input = this.sideItemHandler.getStackInSlot(0); + ItemStack plateA = this.topItemHandler.getStackInSlot(0); + ItemStack plateB = this.bottomItemHandler.getStackInSlot(0); + // If the player somehow managed to insert more than one item, we bail here + if( input.getCount() > 1 || plateA.getCount() > 1 || plateB.getCount() > 1 ) + { + return null; + } + + this.cachedTask = InscriberRecipes.findRecipe( world, input, plateA, plateB, true); } return this.cachedTask; } - @Nullable - private IInscriberRecipe getTask( final ItemStack input, final ItemStack plateA, final ItemStack plateB ) - { - if( input.isEmpty() || input.getCount() > 1 ) - { - return null; - } - - if( !plateA.isEmpty() && plateA.getCount() > 1 ) - { - return null; - } - - if( !plateB.isEmpty() && plateB.getCount() > 1 ) - { - return null; - } - - final IComparableDefinition namePress = AEApi.instance().definitions().materials().namePress(); - final boolean isNameA = namePress.isSameAs( plateA ); - final boolean isNameB = namePress.isSameAs( plateB ); - - if( ( isNameA && isNameB ) || isNameA && plateB.isEmpty() ) - { - return this.makeNamePressRecipe( input, plateA, plateB ); - } - else if( plateA.isEmpty() && isNameB ) - { - return this.makeNamePressRecipe( input, plateB, plateA ); - } - - for( final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes() ) - { - - final boolean matchA = ( plateA.isEmpty() && !recipe.getTopOptional().isPresent() ) || ( Platform.itemComparisons() - .isSameItem( plateA, - recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) ) && // and... - ( ( plateB.isEmpty() && !recipe.getBottomOptional().isPresent() ) || ( Platform.itemComparisons() - .isSameItem( plateB, - recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) ) ); - - final boolean matchB = ( plateB.isEmpty() && !recipe.getTopOptional().isPresent() ) || ( Platform.itemComparisons() - .isSameItem( plateB, - recipe.getTopOptional().orElse( ItemStack.EMPTY ) ) ) && // and... - ( ( plateA.isEmpty() && !recipe.getBottomOptional().isPresent() ) || ( Platform.itemComparisons() - .isSameItem( plateA, - recipe.getBottomOptional().orElse( ItemStack.EMPTY ) ) ) ); - - if( matchA || matchB ) - { - for( final ItemStack option : recipe.getInputs() ) - { - if( Platform.itemComparisons().isSameItem( input, option ) ) - { - return recipe; - } - } - } - } - - return null; - } - @Override public TickRateModulation tickingRequest( final IGridNode node, final int ticksSinceLastCall ) { @@ -359,7 +300,7 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable, this.finalStep++; if( this.finalStep == 8 ) { - final IInscriberRecipe out = this.getTask(); + final InscriberRecipe out = this.getTask(); if( out != null ) { final ItemStack outputCopy = out.getOutput().copy(); @@ -425,7 +366,7 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable, if( this.getProcessingTime() > this.getMaxProcessingTime() ) { this.setProcessingTime( this.getMaxProcessingTime() ); - final IInscriberRecipe out = this.getTask(); + final InscriberRecipe out = this.getTask(); if( out != null ) { final ItemStack outputCopy = out.getOutput().copy(); @@ -527,54 +468,6 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable, this.processingTime = processingTime; } - private IInscriberRecipe makeNamePressRecipe( ItemStack input, ItemStack plateA, ItemStack plateB ) - { - String name = ""; - - if( !plateA.isEmpty() ) - { - final CompoundNBT tag = plateA.getOrCreateTag(); - name += tag.getString( "InscribeName" ); - } - - if( !plateB.isEmpty() ) - { - final CompoundNBT tag = plateB.getOrCreateTag(); - name += " " + tag.getString( "InscribeName" ); - } - - final ItemStack startingItem = input.copy(); - final ItemStack renamedItem = input.copy(); - - final CompoundNBT display = renamedItem.getOrCreateChildTag( "display" ); - if( !name.isEmpty() ) - { - display.putString("Name", name); - } - else - { - display.remove( "Name" ); - } - - final List inputs = Lists.newArrayList( startingItem ); - final InscriberProcessType type = InscriberProcessType.INSCRIBE; - - final IInscriberRecipeBuilder builder = AEApi.instance().registries().inscriber().builder(); - builder.withInputs( inputs ).withOutput( renamedItem ).withProcessType( type ); - - if( !plateA.isEmpty() ) - { - builder.withTopOptional( plateA ); - } - - if( !plateB.isEmpty() ) - { - builder.withBottomOptional( plateB ); - } - - return builder.build(); - } - /** * This is an item handler that exposes the inscribers inventory while providing simulation capabilities that do not * reset the progress if there's already an item in a slot. Previously, the progress of the inscriber was reset when @@ -613,14 +506,7 @@ public class TileInscriber extends AENetworkPowerTile implements IGridTickable, { return true; } - for( final ItemStack optionals : AEApi.instance().registries().inscriber().getOptionals() ) - { - if( Platform.itemComparisons().isSameItem( stack, optionals ) ) - { - return true; - } - } - return false; + return InscriberRecipes.isValidOptionalIngredient(getWorld(), stack); } return true; }