// Path: src/main/java/guichaguri/betterfps/api/IFastHopper.java
// public interface IFastHopper extends IHopper {
// 
//     /**
//      * Whether this hopper is picking up dropped items
//      */
//     boolean canPickupItems();
// 
//     /**
//      * Updates {@link #canPickupItems}
//      */
//     void updateFastHopper();
// 
// }
// 
// Path: src/main/java/guichaguri/betterfps/transformers/Conditions.java
// public class Conditions {
// 
//     protected static final List<Mappings> patched = new ArrayList<Mappings>();
// 
//     public static final String FAST_HOPPER = "fastHopper";
//     public static final String FAST_BEACON = "fastBeacon";
//     public static final String FAST_SEARCH = "fastSearch";
//     public static final String FAST_BEAM_RENDER = "fastBeaconBeamRender";
//     public static final String FOG_DISABLED = "fogDisabled";
// 
//     /**
//      * Checks whether the condition identifier is met
//      */
//     public static boolean shouldPatch(String condition) {
//         BetterFpsConfig config = BetterFpsHelper.getConfig();
// 
//         if(condition.equals(FAST_HOPPER)) {
//             return config.fastHopper;
//         } else if(condition.equals(FAST_BEACON)) {
//             return config.fastBeacon;
//         } else if(condition.equals(FAST_SEARCH)) {
//             return config.fastSearch;
//         } else if(condition.equals(FAST_BEAM_RENDER)) {
//             return !config.beaconBeam;
//         } else if(condition.equals(FOG_DISABLED)) {
//             return !config.fog;
//         }
// 
//         return true;
//     }
// 
//     /**
//      * Checks whether the {@link Condition} annotation has its condition met
//      */
//     public static boolean shouldPatch(List<AnnotationNode> annotations) {
//         AnnotationNode condition = ASMUtils.getAnnotation(annotations, Condition.class);
//         if(condition != null) {
//             String id = ASMUtils.getAnnotationValue(condition, "value", String.class);
//             return id == null || shouldPatch(id);
//         }
//         return true;
//     }
// 
//     public static boolean isPatched(Mappings name) {
//         return patched.contains(name);
//     }
// 
// }
// 
// Path: src/main/java/guichaguri/betterfps/patchers/FastHopperPatcher.java
// public class FastHopperPatcher implements IClassPatcher {
// 
//     public static final String PICKUP_ITEMS = "pickupItems";
// 
//     @Override
//     public void patch(Patch patch) {
//         ClassNode source = patch.getSourceClass();
//         ClassNode target = patch.getTargetClass();
// 
//         MethodNode method = ASMUtils.findMethod(target, Mappings.M_captureDroppedItems);
//         if(method == null) return; // Method doesn't exist?
// 
//         MethodNode pickupItem = patch.getMethod(PICKUP_ITEMS);
// 
//         InsnList inst = method.instructions;
// 
//         List<JumpInsnNode> ifNullNodes = ASMUtils.findNodes(inst, JumpInsnNode.class, Opcodes.IFNULL);
//         LocalVariableNode inv = ASMUtils.findVariable(method, Mappings.C_IInventory);
// 
//         if(ifNullNodes == null || ifNullNodes.isEmpty() || inv == null) return; // Wut
// 
//         JumpInsnNode ifNull = null;
//         JumpInsnNode ifEnd = null;
// 
//         for(JumpInsnNode node : ifNullNodes) {
//             AbstractInsnNode previous = node.getPrevious();
// 
//             if(previous instanceof VarInsnNode) {
//                 if(((VarInsnNode)previous).var == inv.index) {
//                     ifNull = node;
//                     break;
//                 }
//             }
//         }
// 
//         if(ifNull == null) return; // Wut
// 
//         for(int i = inst.indexOf(ifNull.label) - 1; i >= 0; i--) {
//             AbstractInsnNode node = inst.get(i);
//             if(node instanceof JumpInsnNode && node.getOpcode() == Opcodes.GOTO) {
//                 ifEnd = (JumpInsnNode)node;
//                 break;
//             }
//         }
// 
//         if(ifEnd == null) return; // Wut
// 
//         InsnList ifCanPickupItems = ASMUtils.insertMethod(source, pickupItem, target, method, ifNull.label, false);
//         ifCanPickupItems.add(new JumpInsnNode(Opcodes.IFEQ, ifEnd.label));
//         inst.insert(ifNull.label, ifCanPickupItems);
//     }
// 
// }


import guichaguri.betterfps.api.IFastHopper;
import guichaguri.betterfps.transformers.Conditions;
import guichaguri.betterfps.transformers.annotations.Condition;
import guichaguri.betterfps.transformers.annotations.Copy;
import guichaguri.betterfps.transformers.annotations.Copy.Mode;
import guichaguri.betterfps.transformers.annotations.Patcher;
import guichaguri.betterfps.transformers.annotations.Reference;
import guichaguri.betterfps.patchers.FastHopperPatcher;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.IHopper;
import net.minecraft.tileentity.TileEntityHopper;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
package guichaguri.betterfps.patches.block;


/**
 * @author Guilherme Chaguri
 */
@Patcher(FastHopperPatcher.class)
@Condition(Conditions.FAST_HOPPER)
// Path: src/main/java/guichaguri/betterfps/api/IFastHopper.java
// public interface IFastHopper extends IHopper {
// 
//     /**
//      * Whether this hopper is picking up dropped items
//      */
//     boolean canPickupItems();
// 
//     /**
//      * Updates {@link #canPickupItems}
//      */
//     void updateFastHopper();
// 
// }
// 
// Path: src/main/java/guichaguri/betterfps/transformers/Conditions.java
// public class Conditions {
// 
//     protected static final List<Mappings> patched = new ArrayList<Mappings>();
// 
//     public static final String FAST_HOPPER = "fastHopper";
//     public static final String FAST_BEACON = "fastBeacon";
//     public static final String FAST_SEARCH = "fastSearch";
//     public static final String FAST_BEAM_RENDER = "fastBeaconBeamRender";
//     public static final String FOG_DISABLED = "fogDisabled";
// 
//     /**
//      * Checks whether the condition identifier is met
//      */
//     public static boolean shouldPatch(String condition) {
//         BetterFpsConfig config = BetterFpsHelper.getConfig();
// 
//         if(condition.equals(FAST_HOPPER)) {
//             return config.fastHopper;
//         } else if(condition.equals(FAST_BEACON)) {
//             return config.fastBeacon;
//         } else if(condition.equals(FAST_SEARCH)) {
//             return config.fastSearch;
//         } else if(condition.equals(FAST_BEAM_RENDER)) {
//             return !config.beaconBeam;
//         } else if(condition.equals(FOG_DISABLED)) {
//             return !config.fog;
//         }
// 
//         return true;
//     }
// 
//     /**
//      * Checks whether the {@link Condition} annotation has its condition met
//      */
//     public static boolean shouldPatch(List<AnnotationNode> annotations) {
//         AnnotationNode condition = ASMUtils.getAnnotation(annotations, Condition.class);
//         if(condition != null) {
//             String id = ASMUtils.getAnnotationValue(condition, "value", String.class);
//             return id == null || shouldPatch(id);
//         }
//         return true;
//     }
// 
//     public static boolean isPatched(Mappings name) {
//         return patched.contains(name);
//     }
// 
// }
// 
// Path: src/main/java/guichaguri/betterfps/patchers/FastHopperPatcher.java
// public class FastHopperPatcher implements IClassPatcher {
// 
//     public static final String PICKUP_ITEMS = "pickupItems";
// 
//     @Override
//     public void patch(Patch patch) {
//         ClassNode source = patch.getSourceClass();
//         ClassNode target = patch.getTargetClass();
// 
//         MethodNode method = ASMUtils.findMethod(target, Mappings.M_captureDroppedItems);
//         if(method == null) return; // Method doesn't exist?
// 
//         MethodNode pickupItem = patch.getMethod(PICKUP_ITEMS);
// 
//         InsnList inst = method.instructions;
// 
//         List<JumpInsnNode> ifNullNodes = ASMUtils.findNodes(inst, JumpInsnNode.class, Opcodes.IFNULL);
//         LocalVariableNode inv = ASMUtils.findVariable(method, Mappings.C_IInventory);
// 
//         if(ifNullNodes == null || ifNullNodes.isEmpty() || inv == null) return; // Wut
// 
//         JumpInsnNode ifNull = null;
//         JumpInsnNode ifEnd = null;
// 
//         for(JumpInsnNode node : ifNullNodes) {
//             AbstractInsnNode previous = node.getPrevious();
// 
//             if(previous instanceof VarInsnNode) {
//                 if(((VarInsnNode)previous).var == inv.index) {
//                     ifNull = node;
//                     break;
//                 }
//             }
//         }
// 
//         if(ifNull == null) return; // Wut
// 
//         for(int i = inst.indexOf(ifNull.label) - 1; i >= 0; i--) {
//             AbstractInsnNode node = inst.get(i);
//             if(node instanceof JumpInsnNode && node.getOpcode() == Opcodes.GOTO) {
//                 ifEnd = (JumpInsnNode)node;
//                 break;
//             }
//         }
// 
//         if(ifEnd == null) return; // Wut
// 
//         InsnList ifCanPickupItems = ASMUtils.insertMethod(source, pickupItem, target, method, ifNull.label, false);
//         ifCanPickupItems.add(new JumpInsnNode(Opcodes.IFEQ, ifEnd.label));
//         inst.insert(ifNull.label, ifCanPickupItems);
//     }
// 
// }


// Path: src/main/java/guichaguri/betterfps/patches/block/FastHopper.java
import guichaguri.betterfps.api.IFastHopper;
import guichaguri.betterfps.transformers.Conditions;
import guichaguri.betterfps.transformers.annotations.Condition;
import guichaguri.betterfps.transformers.annotations.Copy;
import guichaguri.betterfps.transformers.annotations.Copy.Mode;
import guichaguri.betterfps.transformers.annotations.Patcher;
import guichaguri.betterfps.transformers.annotations.Reference;
import guichaguri.betterfps.patchers.FastHopperPatcher;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.IHopper;
import net.minecraft.tileentity.TileEntityHopper;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

package guichaguri.betterfps.patches.block;


/**
 * @author Guilherme Chaguri
 */
@Patcher(FastHopperPatcher.class)
@Condition(Conditions.FAST_HOPPER)
public abstract class FastHopper extends TileEntityHopper implements IFastHopper {