com.blogspot.jabelarminecraft.blocksmith.proxy.CommonProxy.java Source code

Java tutorial

Introduction

Here is the source code for com.blogspot.jabelarminecraft.blocksmith.proxy.CommonProxy.java

Source

/**
Copyright (C) 2014 by jabelar
    
This file is part of jabelar's Minecraft Forge modding examples; as such,
you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
    
This program 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 General Public License for more details.
    
For a copy of the GNU General Public License see <http://www.gnu.org/licenses/>.
    
If you're interested in licensing the code under different terms you can
contact the author at julian_abelar@hotmail.com 
*/

package com.blogspot.jabelarminecraft.blocksmith.proxy;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.blogspot.jabelarminecraft.blocksmith.BlockSmith;
import com.blogspot.jabelarminecraft.blocksmith.EventHandler;
import com.blogspot.jabelarminecraft.blocksmith.OreGenEventHandler;
import com.blogspot.jabelarminecraft.blocksmith.TerrainGenEventHandler;
import com.blogspot.jabelarminecraft.blocksmith.commands.CommandStructureCapture;
import com.blogspot.jabelarminecraft.blocksmith.entities.EntityPigTest;
import com.blogspot.jabelarminecraft.blocksmith.gui.GuiHandler;
import com.blogspot.jabelarminecraft.blocksmith.networking.MessageExtendedReachAttack;
import com.blogspot.jabelarminecraft.blocksmith.networking.MessageRequestItemStackRegistryFromClient;
import com.blogspot.jabelarminecraft.blocksmith.networking.MessageSendItemStackRegistryToServer;
import com.blogspot.jabelarminecraft.blocksmith.networking.MessageSyncEntityToClient;
import com.blogspot.jabelarminecraft.blocksmith.networking.MessageToClient;
import com.blogspot.jabelarminecraft.blocksmith.networking.MessageToServer;
import com.blogspot.jabelarminecraft.blocksmith.tileentities.TileEntityCompactor;
import com.blogspot.jabelarminecraft.blocksmith.tileentities.TileEntityForge;
import com.blogspot.jabelarminecraft.blocksmith.tileentities.TileEntityGrinder;
import com.blogspot.jabelarminecraft.blocksmith.tileentities.TileEntityMovingLightSource;
import com.blogspot.jabelarminecraft.blocksmith.tileentities.TileEntityTanningRack;

import io.netty.buffer.ByteBuf;
import net.minecraft.advancements.Advancement;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatBasic;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent;
import net.minecraftforge.fml.common.event.FMLServerStartedEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.event.FMLServerStoppedEvent;
import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;

public class CommonProxy {

    protected int modEntityID = 0;

    /*
     * Sometimes useful to have list of all item types, including subtypes
     */
    protected List itemStackRegistry = new ArrayList();

    public void fmlLifeCycleEvent(FMLPreInitializationEvent event) {
        // load configuration before doing anything else
        // got config tutorial from http://www.minecraftforge.net/wiki/How_to_make_an_advanced_configuration_file
        initConfig(event);

        // register stuff
        //        registerBlocks();
        //        registerItems();
        registerTileEntities();
        //        registerModEntities();
        //        registerEntitySpawns();
        registerFuelHandlers();
        registerSimpleNetworking();
        //        VillagerRegistry.instance().registerVillagerId(10);
        //      VillagerRegistry.instance().registerVillageTradeHandler(10, new VillageTradeHandlerMagicBeans());
        //      VillagerRegistry.getRegisteredVillagers();
    }

    public void fmlLifeCycleEvent(FMLInitializationEvent event) {
        // register custom event listeners
        registerEventListeners();

        // register recipes here to allow use of items from other mods
        registerRecipes();

        // register Advancements here to allow use of items from other mods
        registerAdvancements();

        // register gui handlers
        registerGuiHandlers();

        //        registerDeconstructingInit(event);
    }

    public void registerGuiHandlers() {
        NetworkRegistry.INSTANCE.registerGuiHandler(BlockSmith.instance, new GuiHandler());
    }

    public void fmlLifeCycleEvent(FMLPostInitializationEvent event) {
        // can do some inter-mod stuff here
        initItemStackRegistry();
    }

    public void fmlLifeCycleEvent(FMLServerAboutToStartEvent event) {
        // TODO Auto-generated method stub

    }

    public void fmlLifeCycleEvent(FMLServerStartedEvent event) {
        // TODO Auto-generated method stub

    }

    public void fmlLifeCycleEvent(FMLServerStoppingEvent event) {
        // TODO Auto-generated method stub

    }

    public void fmlLifeCycleEvent(FMLServerStoppedEvent event) {
        // TODO Auto-generated method stub

    }

    public void fmlLifeCycleEvent(FMLServerStartingEvent event) {
        // // register server commands
        event.registerServerCommand(new CommandStructureCapture());
    }

    /*
     * Thanks to diesieben07 tutorial for this code
     */
    /**
     * Registers the simple networking channel and messages for both sides
     */
    protected void registerSimpleNetworking() {
        // DEBUG
        System.out.println("registering simple networking");
        BlockSmith.network = NetworkRegistry.INSTANCE.newSimpleChannel(BlockSmith.NETWORK_CHANNEL_NAME);

        int packetId = 0;
        // register messages from client to server
        BlockSmith.network.registerMessage(MessageToServer.Handler.class, MessageToServer.class, packetId++,
                Side.SERVER);
        // register messages from server to client
        BlockSmith.network.registerMessage(MessageToClient.Handler.class, MessageToClient.class, packetId++,
                Side.CLIENT);
        BlockSmith.network.registerMessage(MessageSyncEntityToClient.Handler.class, MessageSyncEntityToClient.class,
                packetId++, Side.CLIENT);
        BlockSmith.network.registerMessage(MessageExtendedReachAttack.Handler.class,
                MessageExtendedReachAttack.class, packetId++, Side.SERVER);
        BlockSmith.network.registerMessage(MessageSendItemStackRegistryToServer.Handler.class,
                MessageSendItemStackRegistryToServer.class, packetId++, Side.SERVER);
        BlockSmith.network.registerMessage(MessageRequestItemStackRegistryFromClient.Handler.class,
                MessageRequestItemStackRegistryFromClient.class, packetId++, Side.CLIENT);
    }

    /*   
     * Thanks to CoolAlias for this tip!
     */
    /**
     * Returns a side-appropriate EntityPlayer for use during message handling
     */
    public EntityPlayer getPlayerEntityFromContext(MessageContext ctx) {
        return ctx.getServerHandler().player;
    }

    /**
     * Process the configuration
     * @param event
     */
    protected void initConfig(FMLPreInitializationEvent event) {
        // might need to use suggestedConfigFile (event.getSuggestedConfigFile) location to publish
        BlockSmith.configFile = event.getSuggestedConfigurationFile();
        // DEBUG
        System.out.println(BlockSmith.MODNAME + " config path = " + BlockSmith.configFile.getAbsolutePath());
        System.out.println("Config file exists = " + BlockSmith.configFile.canRead());

        BlockSmith.config = new Configuration(BlockSmith.configFile);

        syncConfig();
    }

    /*
     * sync the configuration
     * want it public so you can handle case of changes made in-game
     */
    public void syncConfig() {
        BlockSmith.config.load();
        BlockSmith.allowDeconstructUnrealistic = BlockSmith.config
                .get(Configuration.CATEGORY_GENERAL, "All Craftables Can Deconstruct", false,
                        "Allow unrealistic deconstruction like pumpkins back from pumpkin seeds")
                .getBoolean(false);
        // DEBUG
        System.out.println("Allow unrealistic deconstruction = " + BlockSmith.allowDeconstructUnrealistic);
        BlockSmith.allowHorseArmorCrafting = BlockSmith.config.get(Configuration.CATEGORY_GENERAL,
                "Can Craft Horse Armor", true, "Allow crafting of horse armor and SADDLEs").getBoolean(true);
        // DEBUG
        System.out.println("Allow horse armor crafting = " + BlockSmith.allowHorseArmorCrafting);
        BlockSmith.allowDeconstructEnchantedBooks = BlockSmith.config.get(Configuration.CATEGORY_GENERAL,
                "Can Deconstruct Enchanted Books", true, "Allow enchanted books to deconstruct like a regular book")
                .getBoolean(true);
        // DEBUG
        System.out.println("Allow enchanted book deconstruction = " + BlockSmith.allowDeconstructEnchantedBooks);
        BlockSmith.allowPartialDeconstructing = BlockSmith.config
                .get(Configuration.CATEGORY_GENERAL, "Allow Partial Deconstruction", true,
                        "Allow deconstruction of stacks that are less than crafting output")
                .getBoolean(true);
        // DEBUG
        System.out.println("Allow partial deconstruction = " + BlockSmith.allowPartialDeconstructing);

        // save is useful for the first run where config might not exist, and doesn't hurt
        BlockSmith.config.save();
    }

    /**
     * Registers blocks
     */
    //    public void registerBlocks()
    //    {
    //        //example: GameRegistry.registerBlock(blockTomato, "tomatoes");
    //        GameRegistry.register(BlockSmith.blockTanningRack);
    //        GameRegistry.register(BlockSmith.blockGrinder);
    //        GameRegistry.register(BlockSmith.blockCompactor);
    //        GameRegistry.register(BlockSmith.blockDeconstructor);
    //        GameRegistry.register(BlockSmith.blockForge);
    ////        GameRegistry.registerBlock(BlockSmith.blockForgeLit, BlockSmith.blockForgeLit.getUnlocalizedName().substring(5));
    //        GameRegistry.register(BlockSmith.blockMovingLightSource);
    //        
    //        // each instance of your block should have a name that is unique within your mod.  use lower case.
    //        // you don't need to register an item corresponding to the block, GameRegistry.registerBlock does this automatically.
    //        
    //    }

    /** 
     * Registers fluids
     */
    public void registerFluids() {
        // see tutorial at http://www.minecraftforge.net/wiki/Create_a_Fluid
        // Fluid testFluid = new Fluid("testfluid");
        // FluidRegistry.registerFluid(testFluid);
        // testFluid.setLuminosity(0).setDensity(1000).setViscosity(1000).setGaseous(false) ;
    }

    /**
     * Registers items
     */
    //    private void registerItems()
    //    {
    //        // DEBUG
    //        System.out.println("Registering items");
    //
    //        GameRegistry.register(BlockSmith.cowHide);
    //        GameRegistry.register(BlockSmith.sheepSkin);
    //        GameRegistry.register(BlockSmith.pigSkin);
    //        GameRegistry.register(BlockSmith.horseHide);
    //        GameRegistry.register(BlockSmith.swordExtended);
    //    }

    /**
     * Registers tile entities
     */
    public void registerTileEntities() {
        // DEBUG
        System.out.println("Registering tile entities");
        GameRegistry.registerTileEntity(TileEntityGrinder.class, "tileEntityGrinder");
        GameRegistry.registerTileEntity(TileEntityCompactor.class, "tileEntityCompactor");
        GameRegistry.registerTileEntity(TileEntityTanningRack.class, "tileEntityTanningRack");
        GameRegistry.registerTileEntity(TileEntityForge.class, "tileEntityForge");
        GameRegistry.registerTileEntity(TileEntityMovingLightSource.class, "tileEntityMovingLightSource");
        // example: GameRegistry.registerTileEntity(TileEntityMagicBeanStalk.class, "tileEntityMagicBeanStalk");
    }

    /**
     * Registers recipes
     */
    public void registerRecipes() {
        //        // DEBUG
        //        System.out.println("Registering recipes");
        //                       
        //        // examples:
        //        //        GameRegistry.addRecipe(recipe);
        //        //        GameRegistry.addShapedRecipe(output, params);
        //        //        GameRegistry.addShapelessRecipe(output, params);
        //        //        GameRegistry.addSmelting(input, output, xp);
        //        GameRegistry.addShapedRecipe(new ItemStack(Item.getItemFromBlock(BlockSmith.blockGrinder), 1), 
        //                new Object[]
        //                {
        //                    "ABA",
        //                    "A A",
        //                    "CCC",
        //                    'A', Items.STICK, 'B', Blocks.STONE, 'C', Blocks.COBBLESTONE
        //                });
        //        GameRegistry.addShapedRecipe(new ItemStack(BlockSmith.blockDeconstructor), 
        //                new Object[]
        //                {
        //                    "SSS", 
        //                    "SXS", 
        //                    "SSS", 
        //                    'X', Blocks.CRAFTING_TABLE, 'S', Blocks.COBBLESTONE
        //                });
        //        GameRegistry.addShapedRecipe(new ItemStack(Items.IRON_HORSE_ARMOR), 
        //                new Object[]
        //                {
        //                    "  S", 
        //                    "SXS", 
        //                    "SSS", 
        //                    'X', Blocks.WOOL, 'S', Items.IRON_INGOT
        //                });
        //        GameRegistry.addShapedRecipe(new ItemStack(Items.GOLDEN_HORSE_ARMOR), 
        //                new Object[]
        //                {
        //                    "  S", 
        //                    "SXS", 
        //                    "SSS", 
        //                    'X', Blocks.WOOL, 'S', Items.GOLD_INGOT
        //                });
        //        GameRegistry.addShapedRecipe(new ItemStack(Items.DIAMOND_HORSE_ARMOR), 
        //                new Object[]
        //                {
        //                    "  S", 
        //                    "SXS", 
        //                    "SSS", 
        //                    'X', Blocks.WOOL, 'S', Items.DIAMOND
        //                });
        //        GameRegistry.addShapedRecipe(new ItemStack(Items.SADDLE), 
        //                new Object[]
        //                {
        //                    "SSS", 
        //                    "SXS", 
        //                    "X X", 
        //                    'X', Items.IRON_INGOT, 'S', Items.LEATHER
        //                });
        //
    }

    /**
     * Registers entities as mod entities
     */
    protected void registerModEntities() {
        // DEBUG
        System.out.println("Registering entities");
        // if you want it with a spawn egg use
        // registerModEntityWithEgg(EntityManEatingTiger.class, "Tiger", 0xE18519, 0x000000);
        // or without spawn egg use

        // example: registerModEntity(EntityGoldenGoose.class, "golden_goose");
        registerModEntityWithEgg(EntityPigTest.class, "Test Pig", 0xE18519, 0x000000);
    }

    /**
     * Registers an entity as a mod entity with no tracking
     * @param parEntityClass
     * @param parEntityName
     */
    protected void registerModEntity(Class parEntityClass, String parEntityName) {
        final ResourceLocation resourceLocation = new ResourceLocation(BlockSmith.MODID, parEntityName);
        EntityRegistry.registerModEntity(resourceLocation, parEntityClass, parEntityName, ++modEntityID,
                BlockSmith.instance, 80, 3, false);
    }

    /**
     * Registers an entity as a mod entity with fast tracking.  Good for fast moving objects like throwables
     * @param parEntityClass
     * @param parEntityName
     */
    protected void registerModEntityFastTracking(Class parEntityClass, String parEntityName) {
        final ResourceLocation resourceLocation = new ResourceLocation(BlockSmith.MODID, parEntityName);
        EntityRegistry.registerModEntity(resourceLocation, parEntityClass, parEntityName, ++modEntityID,
                BlockSmith.instance, 80, 10, true);
    }

    public void registerModEntityWithEgg(Class parEntityClass, String parEntityName, int parEggColor,
            int parEggSpotsColor) {
        final ResourceLocation resourceLocation = new ResourceLocation(BlockSmith.MODID, parEntityName);
        EntityRegistry.registerModEntity(resourceLocation, parEntityClass, parEntityName, ++modEntityID,
                BlockSmith.instance, 80, 3, false, parEggColor, parEggSpotsColor);
    }

    /**
     * Registers entity natural spawns
     */
    protected void registerEntitySpawns() {
        /*
         *  register natural spawns for entities
         * EntityRegistry.addSpawn(MyEntity.class, spawnProbability, minSpawn, maxSpawn, enumCreatureType, [spawnBiome]);
         * See the constructor in Biome.java to see the rarity of vanilla mobs; Sheep are probability 10 while Endermen are probability 1
         * minSpawn and maxSpawn are about how groups of the entity spawn
         * enumCreatureType represents the "rules" Minecraft uses to determine spawning, based on creature type. By default, you have three choices:
         *    EnumCreatureType.creature uses rules for animals: spawn everywhere it is light out.
         *    EnumCreatureType.monster uses rules for monsters: spawn everywhere it is dark out.
         *    EnumCreatureType.waterCreature uses rules for water creatures: spawn only in water.
         * [spawnBiome] is an optional parameter of type Biome that limits the creature spawn to a single biome type. Without this parameter, it will spawn everywhere. 
         */

        // DEBUG
        System.out.println("Registering natural spawns");

        // // savanna
        // EntityRegistry.addSpawn(EntityLion.class, 6, 1, 5, EnumCreatureType.creature, Biome.savanna); //change the values to vary the spawn rarity, biome, etc.              
        // EntityRegistry.addSpawn(EntityElephant.class, 10, 1, 5, EnumCreatureType.creature, Biome.savanna); //change the values to vary the spawn rarity, biome, etc.              
    }

    protected void addSpawnAllBiomes(EntityLiving parEntity, int parChance, int parMinGroup, int parMaxGroup) {
        Iterator<ResourceLocation> allBiomesIterator = Biome.REGISTRY.getKeys().iterator();
        while (allBiomesIterator.hasNext()) {
            Biome nextBiome = Biome.REGISTRY.getObject(allBiomesIterator.next());
            EntityRegistry.addSpawn(parEntity.getClass(), parChance, parMinGroup, parMaxGroup,
                    EnumCreatureType.CREATURE, nextBiome); //change the values to vary the spawn rarity, biome, etc.              
        }
    }

    /**
    * Register fuel handlers
    */
    protected void registerFuelHandlers() {
        // DEBUG
        System.out.println("Registering fuel handlers");

        // example: GameRegistry.registerFuelHandler(handler);
    }

    /**
     * Register event listeners
     */
    protected void registerEventListeners() {
        // DEBUG
        System.out.println("Registering event listeners");

        MinecraftForge.EVENT_BUS.register(new EventHandler());
        MinecraftForge.TERRAIN_GEN_BUS.register(new TerrainGenEventHandler());
        MinecraftForge.ORE_GEN_BUS.register(new OreGenEventHandler());
    }

    /**
     * Register Advancements
     */
    protected void registerAdvancements() {
        //        BlockSmith.AdvancementTanningAHide = new Advancement("Advancement.tanningahide", "tanningahide", 0, 0, Items.LEATHER, (Advancement)null);
        //        BlockSmith.AdvancementTanningAHide.registerStat().initIndependentStat(); // Eclipse is having trouble chaining these in previous line
        ////      BlockSmith.AdvancementGiantSlayer = new Advancement("Advancement.giantslayer", "giantslayer", 2, 1, (Item)null, BlockSmith.AdvancementTanningAHide).setSpecial();
        ////      BlockSmith.AdvancementGiantSlayer.registerStat(); // Eclipse is having trouble chaining this in previous line
        //        BlockSmith.craftTable = new Advancement("createDecraftTable", "createDecraftTable", 1 - 2 - 2, -1 - 3, BlockSmith.blockDeconstructor, null).registerStat();
        //        BlockSmith.deconstructAny = new Advancement("deconstructAnything", "deconstructAnything", 2 - 2, -2 - 2, Items.DIAMOND_HOE, BlockSmith.craftTable).registerStat();
        //        BlockSmith.deconstructDiamondHoe = new Advancement("deconstructDiamondHoe", "deconstructDiamondHoe", 2 - 2, 0 - 2, Items.DIAMOND_HOE, BlockSmith.deconstructAny).registerStat();
        //        BlockSmith.deconstructJunk = new Advancement("deconstructJunk", "deconstructJunk", 1 - 2, -1 - 2, Items.LEATHER_BOOTS, BlockSmith.deconstructAny).registerStat();
        //        BlockSmith.deconstructDiamondShovel = new Advancement("deconstructDiamondShovel", "deconstructDiamondShovel", 3 - 2, -1 - 2, Items.DIAMOND_SHOVEL, BlockSmith.deconstructAny).registerStat();
        //        BlockSmith.theHatStandAdvancement = new Advancement("porteManteauAdvancement", "porteManteauAdvancement", 3 - 2, -4 - 2, Blocks.OAK_FENCE, BlockSmith.craftTable).registerStat();
        //        AdvancementPage.registerAdvancementPage(new AdvancementPage("BlockSmith",
        //                new Advancement[]
        //                {
        //                BlockSmith.craftTable, BlockSmith.deconstructAny, BlockSmith.deconstructDiamondHoe, BlockSmith.deconstructJunk, BlockSmith.deconstructDiamondShovel, BlockSmith.theHatStandAdvancement
        //                }));
        //
        //        BlockSmith.deconstructedItemsStat = (StatBasic) (new StatBasic("stat.deconstructeditems", new TextComponentTranslation("stat.deconstructeditems", new Object[0])).registerStat());
        //        
    }

    protected void initItemStackRegistry() {
        return;
    }

    public void setItemStackRegistry(List parRegistry) {
        itemStackRegistry = parRegistry;
    }

    public List getItemStackRegistry() {
        return itemStackRegistry;
    }

    /*
     * Works directly on passed in ByteBuf to put ItemStack registry into packet payload to be sent to the server
     */
    public void convertItemStackListToPayload(ByteBuf parBuffer) {
        Iterator theIterator = itemStackRegistry.iterator();

        while (theIterator.hasNext()) {
            ItemStack theStack = (ItemStack) theIterator.next();

            // write item id and metadata
            parBuffer.writeInt(Item.getIdFromItem(theStack.getItem()));
            parBuffer.writeInt(theStack.getMetadata());

            //            // DEBUG
            //            System.out.println(Item.getIdFromItem(theStack.getItem())+" "+theStack.getMetadata());
            boolean hasNBT = theStack.hasTagCompound();
            parBuffer.writeBoolean(hasNBT);
            if (hasNBT) {
                // DEBUG
                System.out.println(
                        "The stack " + theStack.toString() + " has NBT = " + theStack.getTagCompound().toString());
                ByteBufUtils.writeTag(parBuffer, theStack.getTagCompound());
            }
            theIterator.remove(); // avoids a ConcurrentModificationException
        }

        return;
    }

    /*
     * Provides a list of item stacks giving every registered item along with its metadata variants
     * based on a message payload from the client that gives the valid metadata values for those
     * items with variants. Also will include NBT for mods like Tinker's Construct that use NBT on the
     * ItemStacks to make variants instead of metadata.
     */
    public List<ItemStack> convertPayloadToItemStackList(ByteBuf theBuffer) {
        List<ItemStack> theList = new ArrayList();

        while (theBuffer.isReadable()) {
            int theID = theBuffer.readInt();
            int theMetadata = theBuffer.readInt();
            ItemStack theStack = new ItemStack(Item.getItemById(theID), 1, theMetadata);

            // Handle the case of mods like Tinker's Construct that use NBT instead of metadata
            boolean hasNBT = theBuffer.readBoolean();
            if (hasNBT) {
                theStack.setTagCompound(ByteBufUtils.readTag(theBuffer));
                // DEBUG
                System.out.println(
                        "The stack " + theStack.toString() + " has NBT = " + theStack.getTagCompound().toString());
            }

            theList.add(theStack);
        }

        // DEBUG
        System.out.println(theList.toString());

        return theList;
    }
}