Removed Inscriber Recipe Registry

Fixed Inscriber TESR rendering and added a small easing function
This commit is contained in:
Sebastian Hartte
2020-06-14 11:27:24 +02:00
parent 8e1d90a873
commit 9599a31893
15 changed files with 258 additions and 990 deletions
@@ -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<TileInscriber>
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<TileInscriber>
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<TileInscriber>
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<TileInscriber>
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<TileInscriber>
}
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<TileInscriber>
}
}
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());
}
}
}
@@ -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;
}
@@ -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();
}
@@ -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 )
@@ -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()
{
@@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot )
{
super( inputs, output, top, bot, InscriberProcessType.INSCRIBE );
}
}
@@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<ItemStack> inputs;
@Nonnull
private final ItemStack output;
@Nonnull
private final Optional<ItemStack> maybeTop;
@Nonnull
private final Optional<ItemStack> maybeBot;
@Nonnull
private final InscriberProcessType type;
InscriberRecipe( @Nonnull final Collection<ItemStack> 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<ItemStack> getInputs()
{
return this.inputs;
}
@Nonnull
@Override
public final ItemStack getOutput()
{
return this.output;
}
@Nonnull
@Override
public final Optional<ItemStack> getTopOptional()
{
return this.maybeTop;
}
@Nonnull
@Override
public final Optional<ItemStack> 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;
}
}
@@ -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 <http://www.gnu.org/licenses/lgpl>.
*/
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<IInscriberRecipe> recipes;
private final Set<ItemStack> optionals;
private final Set<ItemStack> inputs;
public InscriberRegistry()
{
this.inputs = new HashSet<>();
this.optionals = new HashSet<>();
this.recipes = new HashSet<>();
}
@Nonnull
@Override
public Collection<IInscriberRecipe> getRecipes()
{
return Collections.unmodifiableCollection( this.recipes );
}
@Nonnull
@Override
public Set<ItemStack> getOptionals()
{
return this.optionals;
}
@Nonnull
@Override
public Set<ItemStack> 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<IInscriberRecipe> 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<ItemStack> inputs;
private ItemStack output;
private ItemStack topOptional;
private ItemStack bottomOptional;
private InscriberProcessType type;
@Nonnull
@Override
public Builder withInputs( @Nonnull final Collection<ItemStack> 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 );
}
}
}
@@ -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<InscriberRecipe> getRecipes(World world) {
Collection<IRecipe<IInventory>> 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;
}
}
+17 -131
View File
@@ -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<ItemStack> 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;
}