diff --git a/CHANGELOG.md b/CHANGELOG.md index 82b040b11..a0bf39d7b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Added support for ore dictionary substitutions in Crafting Patterns (raoulvdberge) - Added Disk Manipulator (way2muchnoise) - Added ingame config (way2muchnoise) +- Added the ability to see the output of a Pattern by shift clicking (raoulvdberge) - When a machine is in use by a crafting pattern, inserting of items from other patterns will be avoided (raoulvdberge) - Exporter in fluid mode no longer duplicates fluids that are less than 1 bucket (raoulvdberge) - Updated Dutch translation (raoulvdberge) diff --git a/src/main/java/refinedstorage/item/ItemPattern.java b/src/main/java/refinedstorage/item/ItemPattern.java index 635fca140..ef59f7953 100755 --- a/src/main/java/refinedstorage/item/ItemPattern.java +++ b/src/main/java/refinedstorage/item/ItemPattern.java @@ -21,12 +21,15 @@ import refinedstorage.api.storage.CompareUtils; import refinedstorage.apiimpl.autocrafting.CraftingPattern; import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class ItemPattern extends ItemBase implements ICraftingPatternProvider { + /** + * A cache that maps a stack to a crafting pattern. + * Only used client side for rendering and tooltips, to avoid crafting pattern allocations and crafting pattern output calculation (which is expensive). + */ + private static Map PATTERN_CACHE = new HashMap<>(); + private static final String NBT_SLOT = "Slot_%d"; private static final String NBT_OUTPUTS = "Outputs"; private static final String NBT_OREDICTED = "Oredicted"; @@ -35,13 +38,21 @@ public class ItemPattern extends ItemBase implements ICraftingPatternProvider { super("pattern"); } + public static CraftingPattern getPatternFromCache(World world, ItemStack stack) { + if (!PATTERN_CACHE.containsKey(stack)) { + PATTERN_CACHE.put(stack, new CraftingPattern(world, null, stack)); + } + + return PATTERN_CACHE.get(stack); + } + @Override public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean advanced) { if (!stack.hasTagCompound()) { return; } - ICraftingPattern pattern = create(player.worldObj, stack, null); + ICraftingPattern pattern = getPatternFromCache(player.worldObj, stack); if (pattern.isValid()) { if (GuiScreen.isShiftKeyDown() || isProcessing(stack)) { diff --git a/src/main/java/refinedstorage/item/PatternBakedModel.java b/src/main/java/refinedstorage/item/PatternBakedModel.java new file mode 100755 index 000000000..f1fb4d9f9 --- /dev/null +++ b/src/main/java/refinedstorage/item/PatternBakedModel.java @@ -0,0 +1,75 @@ +package refinedstorage.item; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import refinedstorage.apiimpl.autocrafting.CraftingPattern; +import refinedstorage.gui.GuiBase; + +import javax.annotation.Nullable; +import java.util.List; + +public class PatternBakedModel implements IBakedModel { + private IBakedModel patternModel; + + public PatternBakedModel(IBakedModel patternModel) { + this.patternModel = patternModel; + } + + @Override + public List getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) { + return patternModel.getQuads(state, side, rand); + } + + @Override + public boolean isAmbientOcclusion() { + return patternModel.isAmbientOcclusion(); + } + + @Override + public boolean isGui3d() { + return patternModel.isGui3d(); + } + + @Override + public boolean isBuiltInRenderer() { + return patternModel.isBuiltInRenderer(); + } + + @Override + public TextureAtlasSprite getParticleTexture() { + return patternModel.getParticleTexture(); + } + + @Override + @SuppressWarnings("deprecation") + public ItemCameraTransforms getItemCameraTransforms() { + return patternModel.getItemCameraTransforms(); + } + + @Override + public ItemOverrideList getOverrides() { + return new ItemOverrideList(patternModel.getOverrides().getOverrides()) { + @Override + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) { + CraftingPattern pattern = ItemPattern.getPatternFromCache(world, stack); + + if (GuiBase.isShiftKeyDown() && pattern.isValid() && pattern.getOutputs().size() == 1) { + ItemStack output = pattern.getOutputs().get(0); + + return Minecraft.getMinecraft().getRenderItem().getItemModelWithOverrides(output, world, entity); + } + + return super.handleItemState(originalModel, stack, world, entity); + } + }; + } +} diff --git a/src/main/java/refinedstorage/proxy/ClientProxy.java b/src/main/java/refinedstorage/proxy/ClientProxy.java index cbd0c95a8..64aa8e38a 100755 --- a/src/main/java/refinedstorage/proxy/ClientProxy.java +++ b/src/main/java/refinedstorage/proxy/ClientProxy.java @@ -42,6 +42,10 @@ public class ClientProxy extends CommonProxy { e.getModelRegistry().putObject(model, ModelMultipartContainer.fromBlock(e.getModelRegistry().getObject(model), cable)); } } + + if (model.getResourceDomain().equals(RefinedStorage.ID) && model.getResourcePath().equals("pattern")) { + e.getModelRegistry().putObject(model, new PatternBakedModel(e.getModelRegistry().getObject(model))); + } } }