• 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Sorry for being absent as of late, A lot going on. I'm going back on track and working some more tutorials. Going to go into (try any way) more Mob based stuff.

    Though it may go as Advanced, I think the first I will do is a "dwarftech" robo miner. Basically, you give it some fuel, and set it's parameters (in the works, but things such as area and depth) and let it go. Will also look to see that you "arm" it properly with a pick (that can break over time). Hoping that I can get this to then mine an area for you (collecting the items mined), and possibly returning to a marked point. Ya, got some of it in the works, but a little ways to go.

    I will also go back to tamable, though tamable is a broad concept. Taming is quite easy, if all it means is following you around. Will attempt to make it so it attacks monster mob types in the area, as well as some basic commands (stay, follow, protect, guard area). Riding will come later as nothing much has changed with that.

    I will also try and do a bit of Techne (youtube) video when working the body of the robo miner.

    Quote from charlie50000

    how do i install JDK and which one do i down load


    As I have said often, I use Eclipse SDK 3.7.0

    EDIT (and eating crow): sorry, also jdk-6u26-windows-i586.exe (JDK) google it.
    Posted in: Tutorials
  • 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Quote from Whiteheat

    Hi inlanoche, I have gotten my vendor gui to work, currently the user is able to see what items or blocks are currently being sold and buy it using gold ingots, I used and modified some of the code that is used for the Creative mode GUI, here is what I have so far: GUI
    // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://www.kpdus.com/jad.html
    // Decompiler options: packimports(3) braces deadcode 
    
    package net.minecraft.src;
    
    import net.minecraft.client.Minecraft;
    
    import org.lwjgl.input.Mouse;
    import org.lwjgl.opengl.GL11;
    
    // Referenced classes of package net.minecraft.src:
    //            GuiContainer, ContainerChest, IInventory, FontRenderer, 
    //            RenderEngine
    
    public class AbGUINPCMobInventory extends GuiContainer
    {
                  
        public AbGUINPCMobInventory(EntityPlayer entityplayer)
        { 
            super(new AbContainerNPCMob(entityplayer));
            field_35312_g = 0.0F;
    
        } 
     
        public void updateScreen()
        {
        }
    
        protected void func_35309_a(Slot slot, int i, int j, boolean flag)
        {
            if(slot != null)
            {
                if(slot.inventory == inventory)
                {
                    InventoryPlayer inventoryplayer = mc.thePlayer.inventory;
                    ItemStack itemstack1 = inventoryplayer.getItemStack();
                    ItemStack itemstack4 = slot.getStack();
                  //Player trying to pick up a stack from creative inventory
                    //Check if the player has any gold at all
                    if(inventoryplayer.hasItem(Item.ingotGold.shiftedIndex))
                    {
                       //Find out a total amount of gold
                       int totalGold = 0;
                       int salePrice;
                       for(int ctr = 0; ctr < inventoryplayer.mainInventory.length; ctr++)
                       {
                          if(inventoryplayer.mainInventory[ctr] != null)
                             if(inventoryplayer.mainInventory[ctr].itemID == Item.ingotGold.shiftedIndex)
                                totalGold += inventoryplayer.mainInventory[ctr].stackSize;
                       }
                          
                       //Find out how much the item they want costs.
                       switch(itemstack4.itemID)
                       {
                       case 24+256: //Item.stick item id is 24. Add 256 for item shiftedIndex.
                          salePrice = 2;
                          break;
                       case 26+256: //Item.bowlSoup item id is 26. Add 256 for item shiftedIndex.
                          salePrice = 3;
                          break;
                       case 1: //Block.stone block id is 1. Don't add 256 for blocks.
                          salePrice = 4;
                          break;
                       default:
                          salePrice = 1;
                       }
                          
                       //Now we know how much gold the player has and how much the item costs.
                       //Check if they can afford the item.
                       if(totalGold >= salePrice)
                       {
                          //Subtract the gold from the player inventory.
                          for(int ctr = 0; ctr < inventoryplayer.mainInventory.length; ctr++)
                             if(inventoryplayer.mainInventory[ctr] != null)
                                if(inventoryplayer.mainInventory[ctr].itemID == Item.ingotGold.shiftedIndex)
                                   if(inventoryplayer.mainInventory[ctr].stackSize >= salePrice)
                                   {
                                      inventoryplayer.mainInventory[ctr].stackSize -= salePrice;
                                      break;
                                   }
                             
                             if(itemstack1 == null)
                             {
                                inventoryplayer.setItemStack(ItemStack.copyItemStack(itemstack4));
                                ItemStack itemstack2 = inventoryplayer.getItemStack();
                             }
                             else
                             {
                                if(itemstack1.itemID == itemstack4.itemID)
                                   itemstack1.stackSize++;
                             }
    
                             /*if(flag) //If the player is holding shift give them max stack size.
                            {
                                itemstack2.stackSize = itemstack2.getMaxStackSize();
                             }*/
                          }
                       }
                     
                    if(itemstack1 != null && itemstack4 != null && itemstack1.itemID == itemstack4.itemID)
                    {
                        if(j == 0)
                        {
                            if(flag)
                            {
                                itemstack1.stackSize = itemstack1.getMaxStackSize();
                            } else
                            if(itemstack1.stackSize < itemstack1.getMaxStackSize())
                            {
                                itemstack1.stackSize++;
                            }
                        } else
                        if(itemstack1.stackSize <= 1)
                        {
                            inventoryplayer.setItemStack(null);
                        } else
                        {
                            itemstack1.stackSize--;
                             
                        }
                    } else
                    if(itemstack1 != null)
                    {
                        inventoryplayer.setItemStack(null);
                    } else
                    if(itemstack4 == null)
                    {
                        inventoryplayer.setItemStack(null);
                    } else
                    if(itemstack1 == null || itemstack1.itemID != itemstack4.itemID)
                    {
                        inventoryplayer.setItemStack(ItemStack.copyItemStack(itemstack4));
                        ItemStack itemstack2 = inventoryplayer.getItemStack();
                        if(flag)
                        {
                            itemstack2.stackSize = itemstack2.getMaxStackSize();
                        }
                    }
                } else
                {
                    inventorySlots.slotClick(slot.slotNumber, j, flag, mc.thePlayer);
                    ItemStack itemstack = inventorySlots.getSlot(slot.slotNumber).getStack();
                    mc.playerController.func_35637_a(itemstack, (slot.slotNumber - inventorySlots.inventorySlots.size()) + 9 + 36);
                    
                   
               }
            } else
            	
            {
                InventoryPlayer inventoryplayer1 = mc.thePlayer.inventory;
                if(inventoryplayer1.getItemStack() != null)
                {
                    if(j == 0)
                    {
                        mc.thePlayer.dropPlayerItem(inventoryplayer1.getItemStack());
                        mc.playerController.func_35639_a(inventoryplayer1.getItemStack());
                        inventoryplayer1.setItemStack(null);
                    }
                    if(j == 1)
                    {
                        ItemStack itemstack3 = inventoryplayer1.getItemStack().splitStack(1);
                        mc.thePlayer.dropPlayerItem(itemstack3);
                        mc.playerController.func_35639_a(itemstack3);
                        if(inventoryplayer1.getItemStack().stackSize == 0)
                        {
                            inventoryplayer1.setItemStack(null);
                        }
                    }
                }
            }
        }
    
        public void initGui()
        {
           
            controlList.clear();
        }
    
        protected void drawGuiContainerForegroundLayer()
        {
            fontRenderer.drawString("Trade", 72, 6, 0x404040);
            String s = "Press 'E' to close";
            fontRenderer.drawString(s, 39, ySize + 1, 0x555555); 
            fontRenderer.drawString(s, 40, ySize + 2, 0xffffff);
        }
    
        public void handleMouseInput()
        {
            super.handleMouseInput();
             ((AbContainerNPCMob)inventorySlots).func_35374_a(field_35312_g);
        
        }
    
        public void drawScreen(int i, int j, float f)
        {
            super.drawScreen(i, j, f);
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            GL11.glDisable(2896 /*GL_LIGHTING*/);
            int i2 = mc.renderEngine.getTexture("/mod/Inv.png");
            mc.renderEngine.bindTexture(i2);
        }
    
        protected void drawGuiContainerBackgroundLayer(float f)
        {
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            int i = mc.renderEngine.getTexture("/mod/Inv.png");
            mc.renderEngine.bindTexture(i);
            int j = (width - xSize) / 2;
            int k = (height - ySize) / 2;
            drawTexturedModalRect(j, k, 0, 0, xSize, ySize + 24);
        }
    
        protected void actionPerformed(GuiButton guibutton)
        {
           
        }
    
        static InventoryBasic getInventory()
        {
            return inventory;
        }
    
        private static InventoryBasic inventory = new InventoryBasic("tmp", 72);
        private float field_35312_g;
     }
    Container
    // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
    // Jad home page: http://www.kpdus.com/jad.html
    // Decompiler options: packimports(3) braces deadcode 
    
    package net.minecraft.src;
    
    import java.util.ArrayList;
    import java.util.List;
    
    // Referenced classes of package net.minecraft.src:
    //            Container, IInventory, Slot, ItemStack, 
    //            EntityPlayer
    
    public class AbContainerNPCMob extends Container
    {
    
        public AbContainerNPCMob(EntityPlayer entityplayer)
        {
        	 itemList = new ArrayList();
             Block ablock[] = {
                 Block.cobblestone, Block.stone, Block.oreDiamond, Block.oreGold, Block.oreIron, Block.oreCoal, Block.oreLapis, Block.oreRedstone, Block.stoneBrick, /*Block.stoneBrick, 
                 Block.stoneBrick, Block.blockClay, Block.blockDiamond, Block.blockGold, Block.blockSteel, Block.bedrock, Block.blockLapis, Block.brick, Block.cobblestoneMossy, Block.stairSingle, 
                 Block.stairSingle, Block.stairSingle, Block.stairSingle, Block.stairSingle, Block.stairSingle, Block.obsidian, Block.netherrack, Block.slowSand, Block.glowStone, Block.wood, 
                 Block.wood, Block.wood, Block.leaves, Block.dirt, Block.grass, Block.sand, Block.sandStone, Block.gravel, Block.web, Block.planks, 
                 Block.sapling, Block.sapling, Block.sapling, Block.deadBush, Block.sponge, Block.ice, Block.blockSnow, Block.plantYellow, Block.plantRed, Block.mushroomBrown, 
                 Block.mushroomRed, Block.reed, Block.cactus, Block.melon, Block.pumpkin, Block.pumpkinLantern, Block.vine, Block.fenceIron, Block.thinGlass, Block.chest, 
                 Block.workbench, Block.glass, Block.tnt, Block.bookShelf, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, 
                 Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, Block.cloth, 
                 Block.dispenser, Block.stoneOvenIdle, Block.music, Block.jukebox, Block.pistonStickyBase, Block.pistonBase, Block.fence, Block.fenceGate, Block.ladder, Block.rail, 
                 Block.railPowered, Block.railDetector, Block.torchWood, Block.stairCompactPlanks, Block.stairCompactCobblestone, Block.stairsBrick, Block.stairsStoneBrickSmooth, Block.lever, Block.pressurePlateStone, Block.pressurePlatePlanks, 
                 Block.torchRedstoneActive, Block.button, Block.cake, Block.trapdoor*/
             };
             int i = 0;
             int j = 0;
             int k = 0;
             int l = 0;
             int i1 = 0;
             for(int j1 = 0; j1 < ablock.length; j1++)
             {
                 int i2 = 0;
                 if(ablock[j1] == Block.cloth)
                 {
                     i2 = i++;
                 } else
                 if(ablock[j1] == Block.stairSingle)
                 {
                     i2 = j++;
                 } else
                 if(ablock[j1] == Block.wood)
                 {
                     i2 = k++;
                 } else
                 if(ablock[j1] == Block.sapling)
                 {
                     i2 = l++;
                 } else
                 if(ablock[j1] == Block.stoneBrick)
                 {
                     i2 = i1++;
                 }
                 itemList.add(new ItemStack(ablock[j1], 1, i2));
             }
    
    //         for(int k1 = 256; k1 < Item.itemsList.length; k1++)
    //         {
    //             if(Item.itemsList[k1] != null)
    //             {
    //                 itemList.add(new ItemStack(Item.itemsList[k1]));
    //             }
    //         }
    //
    //         for(int l1 = 1; l1 < 16; l1++)
    //         {
    //             itemList.add(new ItemStack(Item.dyePowder.shiftedIndex, 1, l1));
    //         }
    
             InventoryPlayer inventoryplayer = entityplayer.inventory;
             for(int j2 = 0; j2 < 3; j2++)
             {
                 for(int l2 = 0; l2 < 3; l2++)
                 {
                     addSlot(new Slot(AbGUINPCMobInventory.getInventory(), l2 + j2 * 3, 62 + l2 * 18, 17 + j2 * 18));
                 }
    
             }
             for(int k1 = 0; k1 < 3; k1++) 
             { 
                 for(int j1 = 0; j1 < 9; j1++) 
                 { 
                     addSlot(new Slot(inventoryplayer, j1 + k1 * 9 + 9, 8 + j1 * 18, 84 + k1 * 18)); 
                 } 
      
             } 
    
             for(int k2 = 0; k2 < 9; k2++)
             {
                 addSlot(new Slot(inventoryplayer, k2, 8 + k2 * 18, 142));
             }
    
             func_35374_a(0.0F);
         }
    
         public boolean canInteractWith(EntityPlayer entityplayer)
         {
             return true;
         }
    
         public void func_35374_a(float f)
         {
             int i = (itemList.size() / 8 - 8) + 1;
             int j = (int)((double)(f * (float)i) + 0.5D);
             if(j < 0)
             {
                 j = 0;
             }
             for(int k = 0; k < 9; k++)
             {
                 for(int l = 0; l < 8; l++)
                 {
                     int i1 = l + (k + j) * 8;
                     if(i1 >= 0 && i1 < itemList.size())
                     {
                    	 AbGUINPCMobInventory.getInventory().setInventorySlotContents(l + k * 8, (ItemStack)itemList.get(i1));
                     } else
                     {
                    	 AbGUINPCMobInventory.getInventory().setInventorySlotContents(l + k * 8, null);
                     }
                 }
    
             }
    
         }
    
         protected void func_35373_b(int i, int j, boolean flag, EntityPlayer entityplayer)
         {
         }
    
         public List itemList;
     }
    Now there is still a few bugs in the system i.e. checking if the player can afford an item or block(any help fixing this would be great). All that is left to do is to allow the user to sell items back and help with that would be great.


    First, I might make a new item (like gold coins) and make the stack size larger. I'm not sure what the limit is, but at least you won't have to carry around so many ingots. As to the price check, what is not working. I browsed the code, and it looks ok. I have not played with vending code at all, so I'm probably not the best to help there... yet.
    Posted in: Tutorials
  • 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Quote from TyberAlyx

    Thanks for the great tutorials inlanoche! It really helped me alot when I was starting to mod but you mentioned in my thread that you stopped modding, how come? :sad.gif:


    You mod was quite fun, and I needed a bit of a break. Actually waiting for 1.9
    Posted in: Tutorials
  • 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Quote from skillinazn

    Hey inlanoche,

    Does your rideable entity tutorial still work for 1.8.1? I was thinking of using that tutorial to make my own car, but I just wanted to confirm if it still worked though.



    Ya should still work, I have been looking into fixing the mounting code (though the vehicle one is still sound), but I still can't weed out the mount controling the rider look feed back loop. I think it's coded elsewhere, or I would have to re-write some of the code in entityplayer.
    Posted in: Tutorials
  • 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Quote from Virgoth098

    Regarding your trampoline block, I can't get it to work, i'll post the code below, but whenever i jump/walk on it, nothing happens! Any idea whats wrong?
    package net.minecraft.src;
    
    public class mod_myfirstmod extends BaseMod
    {
        public mod_myfirstmod()
        {
            int jumpBlockId = 120;
           
            Block jumpBlock = new BlockStone(jumpBlockId, 48);
            jumpBlock.setHardness(0.8F); 
            jumpBlock.setBlockName("jumpBlock"); 
          
            ModLoader.AddName(jumpBlock, "Trampoline");
          
            ModLoader.RegisterBlock(jumpBlock);
    
            ModLoader.AddRecipe(new ItemStack(jumpBlock, 1), new Object[] { "SSS", "FSF", Character.valueOf('F'), Item.feather, Character.valueOf('S'), Block.stone });
        }
    
        public void onEntityCollidedWithBlock(World world, int i, int j, int k, Entity entity)
        {
            if((int)entity.posY > j && entity.motionY < 0)
            {
                    entity.motionY = Math.abs(entity.motionY) + 2;               
            }
        }
    
        public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int i, int j, int k)
        {
            float f = 0.5F;
            return AxisAlignedBB.getBoundingBoxFromPool((float)i + f, j, (float)k + f, (float)(i + 1) - f, (float)(j + 1) - f, (float)(k + 1) - f);
        }
    
        @Override
        public String Version()
        {
            return "0.1";
        }
    }



    Sorry for the late reply. You need to read through the tutorial more closely. The code for the actions of the block need to go in the block code, not your main mod_ java file.
    Posted in: Tutorials
  • 1

    posted a message on [1.8.1]Tale Of Kingdoms Ver 1.0.5
    This mod kicks @$$. I'v stopped attempting to mod becuase of this...

    my only gripe is with the save system. Was it not possible to save the mod data in the same folder as the vanilla save data? I was attempting to start again (at the point I could make my kingdom - from a save copy) but the builder is where my old castle was. Plus I cannot rebuild my castle. Not a big thing, but would be nice for multiple saves.
    Posted in: Minecraft Mods
  • 0

    posted a message on [1.8.1]Tale Of Kingdoms Ver 1.0.5
    I made my own bed and house while I did my work building up money and the king rating. So I go the builder guy and made my castle walls. I had to go back to my old house to get my stuff, and I slept there and gathered a few things. Well, I went back to where my new town would be and the builder is gone. He's not at the guild either. Does he re-spawn? Is he lost for good? Would be better if he had a booth to protect him if he got killed or something... Now I just have walls, and not way to have the buildings made (aside from ding it the hard way...:sad.gif: )
    Posted in: Minecraft Mods
  • 0

    posted a message on Groxmapper's ModLoader Tutorials n' Tips (version 1.8.1)
    Nice. Hey don't mind the flak on starting at the begining... You don't know how many times I've had to point people back to the basics because they want to start at the hard stuff but don't know enough to get started. Keep it up!
    Posted in: Tutorials
  • 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Quote from AndrewSherman

    Hi can you tell me how to make the trees spawn less often? Thanks :GoldBar:


    I'm not exactly sure. Since MCP does not break down the var names, it's hard to read what all the vars do. It would seem that (if you look at the generate method in your WorldGen java file) the var flag decides when a try is to be made. If it is set to false, then the method just returns (ends). If you think it's happening too often, then you could go right below the last "return false;" line and add your own percent or range check. If it fails, return false, and no tree will be made. For instance, if you want to reduce the tree placement by 50%, then put in something like this:

            if (random.nextInt(100) > 50)
            {
            	return false;
            }


    I'm pretty sure that random is already defined in this method, or you could create your own (with a different name).
    Posted in: Tutorials
  • 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Quote from stephanstross

    The funny thing is, I did. This error only occurs when i try to run the minecraft client through MCP. If i actually install the mod in my minecraft.jar file in AppData, it works fine. Otherwise, it throws this error and i have no idea why! I'm gonna try to reinstall MCP and see what happens...

    Also, do you have any idea how to make a block viciously slaughter anything that touches it, while counting how much damage it does?



    I just made a horse and found that CASE does matter. I called the texture Horse.png, but was calling it as horse.png. Could be that mcp is more sentitive when it comes to case sensitivity.
    Posted in: Tutorials
  • 3

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Quote from MacPeaches

    This tutorial contains alot of stuff that I need, I'll read all of it as soon as possible but it's been great so far.



    No problem. More to come. Just remember that little green and white plus button :wink.gif:
    Posted in: Tutorials
  • 1

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Quote from thisguyisjoe

    Any chance you know of a way to get an entity to path to a given set of coordinates? As of now, I've got code that returns the coordinates of a block if it's within range of the entity, but haven't yet managed to get an entity to actively path towards the block.

    I toyed with this a bit in the past. 2 ways I was looking into. I first started to look at the pathing, which mostly pointed towards targeting an entity. So I was going to may a "way-point" entity that was small and invisible that I would have my mob follow. Then I found this when making my patrol code:

    PathEntity patrolPath = worldObj.getEntityPathToXYZ(entity,x,y,z,f);

    I think this is how it worked. I would look up the method in World.java. This was a whie back in 1.7.3, might have changed.
    Posted in: Tutorials
  • 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    Quote from Muserae

    You don't want the pig, you want the ModelQuadruped. The ModelPig extends ModelQuadruped so it has the same animations from ModelQuadruped without having the code into ModelPig.



    Sorry to have been away for a bit. Played a bit with one of the survival saves. If you extend ModelPig, you are still extending ModelQuadruped, so that is not it. If you've looked at my other tutorials, then you will know that these lines (here taken from ModelQuadruped) control the movement:
        public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5)
        {
            head.rotateAngleX = f4 / 57.29578F;
            head.rotateAngleY = f3 / 57.29578F;
            body.rotateAngleX = 1.570796F;
            leg1.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * f1;
            leg2.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 1.4F * f1;
            leg3.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.141593F) * 1.4F * f1;
            leg4.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * f1;
        }


    Now I don't have 1.7.3 open, but I beleive that the vars (f and f1) are the same. These set the swinging motion of both the arms (for bipeds) and legs. If this is not present (which it really shouldn't need to be, since you are still part of the Quad family extending the pig) you could always add it. If it is there and you do not have all these and you don't call the super class (super.setRotationAngles(f, f1, f2, f3, f4,f5)) then that is most likely your problem.
    Posted in: Tutorials
  • 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    ADVANCE TUTORIAL BELOW

    Fruit and Seeds

    Ok, we did the Block code, now the items code (and a jump back to leaves at the end).
    We need to create some definitions first in our main mod_ java file, in the items pocket:
    	//***ITEM101:START Item definition code---------------------------------------
    	/*HINTS:
    	 * ex. public static final Item  = (new aItemClass(ItemID).setItemName("aItem");
    	 * look at Item.java to see .set methods available.  .setItemName("") is required
    	 * can replace image by adding this line with 16x16 PNG file (pixels/inch must be 96):
    	 * aItem.iconIndex = ModLoader.addOverride("/gui/items.png", "/16x16Image.png"); 
    	 */
    	public static final Item SpawnIngot = new Item(8000).setItemName("SpawnIngot ");
    	public static final Item AppleFruit = new ILN_ItemTreeFruit(8001, 3, 0.5F, false).setItemName("AppleFruit").setMaxDamage(0).setIconIndex(14);	
    	public static final Item OrangeFruit = new ILN_ItemTreeFruit(8002, 3, 0.5F, false).setItemName("OrangeFruit").setMaxDamage(1).setIconIndex(14);	
    	public static final Item LemonFruit = new ILN_ItemTreeFruit(8003, 3, 0.5F, false).setItemName("LemonFruit").setMaxDamage(2).setIconIndex(14);	
    	public static final Item PlumFruit = new ILN_ItemTreeFruit(8004, 3, 0.5F, false).setItemName("PlumFruit").setMaxDamage(3).setIconIndex(14);	
    	public static final Item AppleSeeds = new ILN_ItemSeeds(8005).setItemName("AppleSeeds").setIconIndex(61).setMaxDamage(0);
    	public static final Item OrangeSeeds = new ILN_ItemSeeds(8006).setItemName("OrangeSeeds").setIconIndex(61).setMaxDamage(1);
    	public static final Item LemonSeeds = new ILN_ItemSeeds(8007).setItemName("LemonSeeds").setIconIndex(61).setMaxDamage(2);
    	public static final Item PlumSeeds = new ILN_ItemSeeds(8008).setItemName("PlumSeeds").setIconIndex(61).setMaxDamage(3);
    
    	private void MakeItems()
    	{
    		ModLoader.AddName(SpawnIngot, "Spawn Ingot");
    		SpawnIngot.iconIndex = ModLoader.addOverride("/gui/items.png", "/ILN/CustomOre1.png");
    		ModLoader.AddName(AppleFruit, "Apple Fruit");
    		ModLoader.AddName(OrangeFruit, "Orange Fruit");
    		ModLoader.AddName(LemonFruit, "Lemon Fruit");
    		ModLoader.AddName(PlumFruit, "Plum Fruit");
    		ModLoader.AddName(AppleSeeds, "Apple Seeds");
    		ModLoader.AddName(OrangeSeeds, "Orange Seeds");
    		ModLoader.AddName(LemonSeeds, "Lemon Seeds");
    		ModLoader.AddName(PlumSeeds, "Plum Seeds");
    	}
    	//***END Item definition code-------------------------------------------------
    So we have defined each fruit and seed. What really defines them is the setMaxDamage() call. In hind sight, I should have made my own set call, but this will do.
    With that set, let’s move on to the seeds:
    package net.minecraft.src;
    
    import java.util.ArrayList;
    
    
    // Referenced classes of package net.minecraft.src:
    //            Item, ItemStack
    
    public class ILN_ItemSeeds extends Item
    {
    	public int seedType;
    	
        public ILN_ItemSeeds(int i)
        { 
            super(i); 
            maxStackSize = 64;
        }
    
        protected Item setMaxDamage(int i)
        {
            seedType = i;
            return this;
        }
    
    
        public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int i, int j, int k, int l)
        {
            if(l != 1)
            {
                return false;
            }
            if(!entityplayer.func_35190_e(i, j, k) || !entityplayer.func_35190_e(i, j + 1, k))
            {
                return false;
            }
            int i1 = world.getBlockId(i, j, k);
            if((i1 == Block.tilledField.blockID) && world.isAirBlock(i, j + 1, k))
            {
            	
                world.setBlockAndMetadataWithNotify(i, j+1, k, mod_ILN.ILNSapling.blockID, seedType);  //start a specific tree
                itemstack.stackSize--;
                return true;
            } else
            {
                return false;
            }
        }
    }
    We change the code for adding a sapling now. We need to pass the value of 0-3 to the sapling so it knows what tree to grow, so we must use the setBlockAndMetadataWithNotify. We pass the seedType as it is set when the fruit was defined. We won’t change anything else here, just the metadata pass. If you want your seeds to look more distict, you could add a color tint like in the fruit, or change its icon. I’m going to leave them as is. Seeds are seeds to me :wink.gif:.
    Now let’s look at the fruit:
    package net.minecraft.src;
    
    import net.minecraft.client.Minecraft;
    
    
    // Referenced classes of package net.minecraft.src:
    //            ItemBlock, Block, BlockCloth, ItemDye, 
    //            ItemStack
    
    public class ILN_ItemTreeFruit extends ItemFood
    {
    
        public ILN_ItemTreeFruit(int i, int j, float f, boolean flag)
        {
        	/* passed vars (taken from ItemFood):
        	 * i - shiftedIndex
        	 * j - healAmount value
        	 * f - field_35428_c (not sure what this does)
        	 * flag - wolf's favourite food... waste...
        	 */
            super(i,j,f,flag);
            setMaxDamage(0);
            setHasSubtypes(true);
            maxStackSize = 30;
        }
            
        private int fColor = 0x00ffff;				//test value
        
        //stolen from Item.java to reuse it.
        private int maxDamage;
        protected Item setMaxDamage(int i)
        {
        	//do not change maxDamage, as it would show a damage bar if it's not 0
            fColor = i;
            return this;
        }
       
        public int getColorFromDamage(int i)
        {
        	//use this function (but not i) to set the type of fruit
        	int returnColor;
        	switch (fColor)
        	{
        		case 0: returnColor = 0xaa0000;	break;		//red tint for apple
        		case 1: returnColor = 0xcc8800;	break;		//orange tint for orange
        		case 2: returnColor = 0xffff55;	break;		//yellow tint for lemon
        		case 3: returnColor = 0x550088;	break;		//purple tint for plum
        		default: returnColor = 0xffffff;				//default color (white)
        	}
        	return returnColor;
        } 
    
        
        public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer)
        {
        	int size = itemstack.stackSize;
        	int count = 500;
            if(entityplayer.func_35197_b(field_35431_bw))
            {
                entityplayer.func_35199_b(itemstack, func_35411_c(itemstack));
                switch(fColor)
                {
                	case 0: entityplayer.inventory.addItemStackToInventory(new ItemStack(mod_ILN.AppleSeeds));	break;
                	case 1: entityplayer.inventory.addItemStackToInventory(new ItemStack(mod_ILN.OrangeSeeds));	break;
                	case 2: entityplayer.inventory.addItemStackToInventory(new ItemStack(mod_ILN.LemonSeeds));	break;
                	case 3: entityplayer.inventory.addItemStackToInventory(new ItemStack(mod_ILN.PlumSeeds));	break;
                }
            	
                /*
                if(entityplayer.inventory.consumeInventoryItem(mod_ILN.CyanFruit.shiftedIndex))		//bypasses eat feature
                {
                	entityplayer.dropPlayerItem(new ItemStack(Item.seeds, 1));		//change this to match seeds type (switch statement)
                	//would need to add manual healing with this code
                }
                */
            }
            return itemstack;
        }
        
        public EntityPlayer player;
        
        public EnumAction func_35412_b(ItemStack itemstack)
        {
            return EnumAction.eat;
        }
    
        
        public ItemFood func_35424_o()
        {
            field_35431_bw = true;
            return this;
        }
    
        private boolean field_35431_bw;   
    }
    So a bit more here, but not a lot new. We do a similar color tint adjustment to match the tree/fruit type. The extended code here is for when the seeds are created. Note on the seed creation. At this point in time, there is not indicator that I can find for when the fruit is actually eaten. So as soon as the player hits the right mouse button the seeds are made. They could just click and click and get tons of seeds. The other method I commented out. This was the old way, but it’s kind of an instant action, and no health is gained. You would have to do that manually. A third option could be that you could craft seeds from 1 fruit, or eat it for health, kind of a trade off. Your choice. I’m leaving this here as a sample of what can be done.
    Last we need to revisit the ILN_BlockLeaves code. Just like with the fruit producing the right seed, so must the tree product the right fruit. Find the idDropped() method and make the following changes:
        public int idDropped(int i, Random random)
        {
        	switch(aColor)
        	{
        		case 0: return mod_ILN.AppleFruit.shiftedIndex;
        		case 1: return mod_ILN.OrangeFruit.shiftedIndex;
        		case 2: return mod_ILN.LemonFruit.shiftedIndex;
        		case 3: return mod_ILN.PlumFruit.shiftedIndex;
        		default: return Item.appleGold.shiftedIndex;			//test for fail drop
        	}
        }
    I threw in a test default value to see that all is working. If you followed all this, the code should work fine. Again, make sure to start a whole new world, or it may crash on you. I set my seed to 22 and got one that was in a hill biome, in which we have set the trees to grow. I’ve also found that hurting yourself (jumping off ledges) is a good way to make the hunger go down. Seems that health regen makes you hungry.
    Posted in: Tutorials
  • 0

    posted a message on inLanoche's Tutorials [1.8] [ModLoader]
    ADVANCE TUTORIAL BELOW

    Advance Fruit Trees with Metadata

    So you have made a fruit tree, but you would like to have more tree types. With the limit to blocks, you want to be careful with your needs and wants. I’m going to show you how to make 4 different trees using only 3 blocks: log, leaves, and sapling. These were all created before (if you have jumped to here, go back and read the other tutorials on trees first!), now we are going to use metadata to get more use out of these 3 blocks. You will still have to make a fruit and seed item for each, but the limit to items is a lot higher. Also, we will use the existing textures (there is a cap on how many textures can be added as well). We need to start with our Gen code, in my case ILN_WorldGenFruitTrees.java:
    package net.minecraft.src; 
     
    import java.util.Random; 
     
    public class ILN_WorldGenFruitTrees extends WorldGenerator 
    { 
    	private int treeType;
    	private Random r = new Random();
    	
        public ILN_WorldGenFruitTrees(int passType) 
        { 
        	treeType = passType < 3 ? -1 : passType;			//specifies what tree to spawn.  -1 means random tree type (0-3)
        } 
     
        public boolean generate(World world, Random random, int i, int j, int k) 
        { 
        	int newType;
        	newType = treeType < 0 ? r.nextInt(4) : treeType;		//if type -1 is passed, randomize between 0 and 3
        		
            int l = random.nextInt(3) + 4; 
            boolean flag = true; 
            if(j < 1 || j + l + 1 > 128) 
            { 
                return false; 
            } 
            for(int i1 = j; i1 <= j + 1 + l; i1++) 
            { 
                byte byte0 = 1; 
                if(i1 == j) 
                { 
                    byte0 = 0; 
                } 
                if(i1 >= (j + 1 + l) - 2) 
                { 
                    byte0 = 2; 
                } 
                for(int i2 = i - byte0; i2 <= i + byte0 && flag; i2++) 
                { 
                    for(int l2 = k - byte0; l2 <= k + byte0 && flag; l2++) 
                    { 
                        if(i1 >= 0 && i1 < 128) 
                        { 
                            int j3 = world.getBlockId(i2, i1, l2); 
                            if(j3 != 0 && j3 != mod_ILN.ILNLeaves.blockID) 
                            { 
                                flag = false; 
                            } 
                        } else 
                        { 
                            flag = false; 
                        } 
                    } 
     
                } 
     
            } 
     
            if(!flag) 
            { 
                return false; 
            } 
            int j1 = world.getBlockId(i, j - 1, k); 
            if(j1 != Block.grass.blockID && j1 != Block.dirt.blockID || j >= 128 - l - 1) 
            { 
                return false; 
            } 
            world.setBlock(i, j - 1, k, Block.dirt.blockID); 
            for(int k1 = (j - 3) + l; k1 <= j + l; k1++) 
            { 
                int j2 = k1 - (j + l); 
                int i3 = 1 - j2 / 2; 
                for(int k3 = i - i3; k3 <= i + i3; k3++) 
                { 
                    int l3 = k3 - i; 
                    for(int i4 = k - i3; i4 <= k + i3; i4++) 
                    { 
                        int j4 = i4 - k; 
                        if((Math.abs(l3) != i3 || Math.abs(j4) != i3 || random.nextInt(2) != 0 && j2 != 0) && !Block.opaqueCubeLookup[world.getBlockId(k3, k1, i4)]) 
                        {
                            world.setBlockAndMetadata(k3, k1, i4, mod_ILN.ILNLeaves.blockID, newType); 		//type will define colors and fruit
                        } 
                    } 
     
                } 
     
            } 
     
            for(int l1 = 0; l1 < l; l1++) 
            { 
                int k2 = world.getBlockId(i, j + l1, k); 
                if(k2 == 0 || k2 == mod_ILN.ILNLeaves.blockID) 
                { 
                    world.setBlockAndMetadata(i, j + l1, k, mod_ILN.ILNLog.blockID, newType); 				//type will define colors and fruit
                } 
            } 
     
            return true; 
        } 
    }
    The first thing I did was to change the constructor. It now requires an int past to it. I did a quick assign here:
    treeType = passType < 3 ? -1 : passType;

    What this means (for those new to java) is to check if passType < 3. If it is return -1, if not return passType. Since this code is being assigned to treeType, it gets the outcome of the test. Since I only can have 4 tree types, the value cannot be higher than 3. But what about -1 you ask? We’ll get to that next.
    Then in the generate() method I add a new var, int newType. I then check to see if it is less than 0, similar to what we did above. This time, if it is less than 0, then set it to a random number from 0-3. If not, keep the number.
    The other changes I made are near the bottom. Instead of world.setBlock() I use world.setBlockAndMetadata(). This requires one more arg, which we are using newType. This will allow us to pass a number from 0 to 3 (the 2 bits of data) to the block we are creating. Each bit can be 1 or 0, so if you know your binary, with 2 bits you can count to 3 (starting at 0).
    This is how things are kicked off. You will notice that some of your code (sapling and main mod_ java file) has errors, because we need to have the classes that call this class include an int pass to it. Let’s next look at the generation code in your main mod_ java file:
    	//***WGEN101:START World/Surface Generation definition code-----------------------------
    	
        public void GenerateSurface(World world, Random random, int i, int j) 
        { 
            BiomeGenBase biomegenbase = world.getWorldChunkManager().getBiomeGenAt(i, j); 
            ILN_WorldGenFruitTrees mytrees = new ILN_WorldGenFruitTrees(-1); 
            if((biomegenbase instanceof BiomeGenSwamp) || (biomegenbase instanceof BiomeGenForest) || (biomegenbase instanceof BiomeGenHills)) 
            { 
                int k = i + random.nextInt(16) + 8; 
                int l = j + random.nextInt(16) + 8; 
                int i1 = world.getHeightValue(k, l); 
                mytrees.func_517_a(1.0D, 1.0D, 1.0D); 
                mytrees.generate(world, random, k, i1, l); 
            } 
        } 
    	//***WGEN101:END World/Surface Generation definition code-----------------------------	
     
    So here we add the int -1 to our creation of the ILN_WorldGenFruitTrees() object declaration. Passing -1 means we want to randomize the type of tree. Next we go to the other place we have trees generated, in our sapling block:
    package net.minecraft.src;
    
    import java.util.Random;
    
    // Referenced classes of package net.minecraft.src:
    //            BlockFlower, World, WorldGenTaiga2, WorldGenForest, 
    //            WorldGenTrees, WorldGenBigTree, WorldGenerator
    
    public class ILN_BlockSapling extends BlockFlower
    {
    
        protected ILN_BlockSapling(int i, int j)
        {
            super(i, j);
            float f = 0.4F;
            setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f);
        }
    
        public void updateTick(World world, int i, int j, int k, Random random)
        {
            if(world.multiplayerWorld)
            {
                return;
            }
            super.updateTick(world, i, j, k, random);
            if(world.getBlockLightValue(i, j + 1, k) >= 9 && random.nextInt(30) == 0)
            {
                int l = world.getBlockMetadata(i, j, k);
                if((l & 8) == 0)
                {
                    world.setBlockMetadataWithNotify(i, j, k, l | 8);
                } else
                {
                    growTree(world, i, j, k, random);
                }
            }
        }
    
        public int getBlockTextureFromSideAndMetadata(int i, int j)
        {
        	/*  Let's make all my saplings look the same, with color tint
            */
        	return 15;
        }
        
        private int aColor = -1;			//index of color based on type 
        
        public int getRenderColor(int i)
        {
        	//Assuming i is the metadata being passed...
        	//match leaves, logs and fruit colors
        	aColor = (i & 3);			//get last 2 bits for the type
        	return getAColor();			//orange like color
        }
    
        public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k)
        {
            int l = iblockaccess.getBlockMetadata(i, j, k);
            aColor = (l & 3);			//get last 2 bits for the type
        	return getAColor();
        }
        
    
        private int getAColor()
        {
        	//To return a color value (0x000000) based on the value of aColor.
        	int i;
        	switch (aColor)
        	{
        		case 0: i = 0xffcccc;	break;		//red tint for apple tree wood
        		case 1: i = 0xffaa55;	break;		//orange tint for orange tree wood
        		case 2: i = 0xffff55;	break;		//yellow tint for lemon tree wood
        		case 3: i = 0xccaaff;	break;		//purple tint for plum tree wood
        		default: i = 0xffffff;				//default color of wood
        	}
        	return i;
        }
    
        public void growTree(World world, int i, int j, int k, Random random)
        {
            int l = world.getBlockMetadata(i, j, k) & 3;				
            world.setBlock(i, j, k, 0);
            Object obj = null;
    
            obj = new ILN_WorldGenFruitTrees(aColor);						//used to define type
            if(!((WorldGenerator) (obj)).generate(world, random, i, j, k))
            {
                world.setBlockAndMetadata(i, j, k, blockID, aColor);			//if generate tree fails, leave the sapling
            }
        }
        
        public int idDropped(int i, Random random)
        {
        	return 0;		//cannot replant, unless with seeds.  If want seeds, return the seed shifted index
        }
    
        protected int damageDropped(int i)
        {
            return i & 3;
        }
    }
    Since the changes here are near the bottom, we will start from the bottom up. In the growTree() method, we add the global var aColor as an arg for the creation of our ILN_WorldGenFruitTrees object. We use aColor, because this gets set when setting the render color, which we will get to. Moving up the list, we come to my getAColor() method. Here we are checking the value of aColor. With some simple commenting, you can see the type of sapling this will be. Here I go a bit overboard with changing the color to match the type of fruit. You don’t need to do this really, all you need is to carry over the type value, but it makes the world a bit more colorful. If we go a bit further up to the overridden Block methods colorMultiplier() and getRenderColor(), we get the metadata that we set elsewhere (or will be setting). The metadata is 4 bits (int 0-15) but we only need the last 2 bits. If you know about bit masking, that is kind of what I am doing here. So say that (in getRenderColor) i = 13, or 1101. By mask of 3 would be 0011. So 1101 & 0011 returns 0001 (will only 1 if both bits are 1). So I get the value of the last 2 bits, which can only be from 0 (0000) to 3 (0011), our 4 tree types. I am pretty sure that the upper 2 bits are used for the tree growth (or from the sapling), so we are stuck with the last 2, which are currently used for wood texture, leaves texture, and sapling texture. They are going by texture, I am instead coloring based on these vales.
    With the explanation out of the way, we now move on. Let’s do both the logs and leaves.
    Logs:
    package net.minecraft.src;
    
    import java.util.Random;
    
    // Referenced classes of package net.minecraft.src:
    //            Block, Material, World, BlockLeaves, 
    //            EntityPlayer
    
    public class ILN_BlockLog extends Block
    {
    	
        protected ILN_BlockLog(int i, int j)
        {
            super(i, Material.wood);
            blockIndexInTexture = 20;		//the default wood texture for now
        }
    
        public int quantityDropped(Random random)
        {
            return 1;
        }
    
        public int idDropped(int i, Random random)
        {
            return mod_ILN.ILNLog.blockID;
        }
    
        public void harvestBlock(World world, EntityPlayer entityplayer, int i, int j, int k, int l)
        {
            super.harvestBlock(world, entityplayer, i, j, k, l);
        }
    
        public void onBlockRemoval(World world, int i, int j, int k)
        {
            byte byte0 = 4;
            int l = byte0 + 1;
            if(world.checkChunksExist(i - l, j - l, k - l, i + l, j + l, k + l))
            {
                for(int i1 = -byte0; i1 <= byte0; i1++)
                {
                    for(int j1 = -byte0; j1 <= byte0; j1++)
                    {
                        for(int k1 = -byte0; k1 <= byte0; k1++)
                        {
                            int l1 = world.getBlockId(i + i1, j + j1, k + k1);
                            if(l1 != mod_ILN.ILNLeaves.blockID)
                            {
                                continue;
                            }
                            int i2 = world.getBlockMetadata(i + i1, j + j1, k + k1);
                            if((i2 & 8) == 0)
                            {
                                world.setBlockMetadata(i + i1, j + j1, k + k1, i2 | 8);
                            }
                        }
    
                    }
    
                }
    
            }
        }
    
        public int getBlockTextureFromSideAndMetadata(int i, int j)
        {	
        	//i defines the side of the block.  1 being the top, 0 being the bottom.  Sides should be from 2-5.
            if(i == 1)
            {
                return 21;
            }
            if(i == 0)
            {
                return 21;
            }
            //j checks the type of tree (metadata), we are not using this
            return blockIndexInTexture;		//return the set wood texture
        }
    
        private int aColor = -1;			//index of color based on type 
        
        public int getRenderColor(int i)
        {
        	//Assuming i is the metadata being passed...
        	//match leaves, logs and fruit colors
        	aColor = (i & 3);			//get last 2 bits for the type
        	return getAColor();			//orange like color
        }
    
        public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k)
        {
            int l = iblockaccess.getBlockMetadata(i, j, k);
            aColor = (l & 3);			//get last 2 bits for the type
        	return getAColor();
        }
        
    
        private int getAColor()
        {
        	//To return a color value (0x000000) based on the value of aColor.
        	int i;
        	switch (aColor)
        	{
        		case 0: i = 0xffcccc;	break;		//red tint for apple tree wood
        		case 1: i = 0xffaa55;	break;		//orange tint for orange tree wood
        		case 2: i = 0xffff55;	break;		//yellow tint for lemon tree wood
        		case 3: i = 0xccaaff;	break;		//purple tint for plum tree wood
        		default: i = 0xffffff;				//default color of wood
        	}
        	return i;
        }
    
    
        protected int damageDropped(int i)
        {
            return i;
        }
    }

    Leaves:
    package net.minecraft.src;
    
    import java.util.Random;
    
    // Referenced classes of package net.minecraft.src:
    //            BlockLeavesBase, Material, ColorizerFoliage, IBlockAccess, 
    //            WorldChunkManager, World, Block, EntityPlayer, 
    //            ItemStack, Item, ItemShears, StatList, 
    //            Entity
    
    public class ILN_BlockLeaves extends BlockLeavesBase
    {
    	private int aColor = -1;
    
        protected ILN_BlockLeaves(int i, int j)
        {
            super(i, j, Material.leaves, false);
            baseIndexInPNG = j;
            setTickOnLoad(true);
        }
    
        public int func_35274_i()
        {
            double d = 0.5D;
            double d1 = 1.0D;
            //return ColorizerFoliage.getFoliageColor(d, d1);	//dropped, using my own code
        	return aColor;			
    
        }
        
        private int getAColor()
        {
        	int i;
        	switch (aColor)
        	{
        		case 0: i = 0xff3333;	break;		//red tint for apple tree leaves
        		case 1: i = 0xffaa00;	break;		//orange tint for orange tree leaves
        		case 2: i = 0xffff00;	break;		//yellow tint for lemon tree leaves
        		case 3: i = 0xaa00cc;	break;		//purple tint for plum tree leaves
        		default: i = 0x48b518;				//default color of leaves
        	}
        	return i;
        	
        }
    
        public int getRenderColor(int i)
        {
        	//Assuming i is the metadata being passed...
        	//match leaves, logs and fruit colors
        	aColor = (i & 3);			//get last 2 bits for the type
        	
        	return getAColor();
        }
    
        public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k)
        {
            int l = iblockaccess.getBlockMetadata(i, j, k);
            aColor = (l & 3);			//get last 2 bits for the type
        	return getAColor();
    
        }
    
        public void onBlockRemoval(World world, int i, int j, int k)
        {
            int l = 1;
            int i1 = l + 1;
            if(world.checkChunksExist(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1))
            {
                for(int j1 = -l; j1 <= l; j1++)
                {
                    for(int k1 = -l; k1 <= l; k1++)
                    {
                        for(int l1 = -l; l1 <= l; l1++)
                        {
                            int i2 = world.getBlockId(i + j1, j + k1, k + l1);
                            if(i2 == mod_ILN.ILNLeaves.blockID)
                            {
                                int j2 = world.getBlockMetadata(i + j1, j + k1, k + l1);
                                world.setBlockMetadata(i + j1, j + k1, k + l1, j2 | 8);
                            }
                        }
    
                    }
    
                }
    
            }
        }
    
        public void updateTick(World world, int i, int j, int k, Random random)
        {
            if(world.multiplayerWorld)
            {
                return;
            }
            int l = world.getBlockMetadata(i, j, k);
            if((l & 8) != 0 && (l & 4) == 0)
            {
                byte byte0 = 4;
                int i1 = byte0 + 1;
                byte byte1 = 32;
                int j1 = byte1 * byte1;
                int k1 = byte1 / 2;
                if(adjacentTreeBlocks == null)
                {
                    adjacentTreeBlocks = new int[byte1 * byte1 * byte1];
                }
                if(world.checkChunksExist(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1))
                {
                    for(int l1 = -byte0; l1 <= byte0; l1++)
                    {
                        for(int k2 = -byte0; k2 <= byte0; k2++)
                        {
                            for(int i3 = -byte0; i3 <= byte0; i3++)
                            {
                                int k3 = world.getBlockId(i + l1, j + k2, k + i3);
                                if(k3 == mod_ILN.ILNLog.blockID)
                                {
                                    adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = 0;
                                    continue;
                                }
                                if(k3 == mod_ILN.ILNLeaves.blockID)
                                {
                                    adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = -2;
                                } else
                                {
                                    adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = -1;
                                }
                            }
    
                        }
    
                    }
    
                    for(int i2 = 1; i2 <= 4; i2++)
                    {
                        for(int l2 = -byte0; l2 <= byte0; l2++)
                        {
                            for(int j3 = -byte0; j3 <= byte0; j3++)
                            {
                                for(int l3 = -byte0; l3 <= byte0; l3++)
                                {
                                    if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] != i2 - 1)
                                    {
                                        continue;
                                    }
                                    if(adjacentTreeBlocks[((l2 + k1) - 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] == -2)
                                    {
                                        adjacentTreeBlocks[((l2 + k1) - 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] = i2;
                                    }
                                    if(adjacentTreeBlocks[(l2 + k1 + 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] == -2)
                                    {
                                        adjacentTreeBlocks[(l2 + k1 + 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] = i2;
                                    }
                                    if(adjacentTreeBlocks[(l2 + k1) * j1 + ((j3 + k1) - 1) * byte1 + (l3 + k1)] == -2)
                                    {
                                        adjacentTreeBlocks[(l2 + k1) * j1 + ((j3 + k1) - 1) * byte1 + (l3 + k1)] = i2;
                                    }
                                    if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1 + 1) * byte1 + (l3 + k1)] == -2)
                                    {
                                        adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1 + 1) * byte1 + (l3 + k1)] = i2;
                                    }
                                    if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + ((l3 + k1) - 1)] == -2)
                                    {
                                        adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + ((l3 + k1) - 1)] = i2;
                                    }
                                    if(adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1 + 1)] == -2)
                                    {
                                        adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1 + 1)] = i2;
                                    }
                                }
    
                            }
    
                        }
    
                    }
    
                }
                int j2 = adjacentTreeBlocks[k1 * j1 + k1 * byte1 + k1];
                if(j2 >= 0)
                {
                    world.setBlockMetadata(i, j, k, l & -9);
                } else
                {
                    removeLeaves(world, i, j, k);
                }
            }
        }
    
        private void removeLeaves(World world, int i, int j, int k)
        {
            dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k));
            world.setBlockWithNotify(i, j, k, 0);
        }
    
        public int quantityDropped(Random random)
        {
            return random.nextInt(20) != 0 ? 0 : 1;
        }
    
        public int idDropped(int i, Random random)
        {
        	return mod_ILN.CyanFruit.shiftedIndex;			//instead of saplings.
        }
    
        public void harvestBlock(World world, EntityPlayer entityplayer, int i, int j, int k, int l)
        {
            if(!world.multiplayerWorld && entityplayer.getCurrentEquippedItem() != null && entityplayer.getCurrentEquippedItem().itemID == Item.shears.shiftedIndex)
            {
                entityplayer.addStat(StatList.mineBlockStatArray[blockID], 1);
                dropBlockAsItem_do(world, i, j, k, new ItemStack(mod_ILN.ILNLeaves.blockID, 1, l & 3));
            } else
            {
                super.harvestBlock(world, entityplayer, i, j, k, l);
            }
        }
    
        protected int damageDropped(int i)
        {
            return i & 3;
        }
    
        public int getBlockTextureFromSideAndMetadata(int i, int j)
        {
        	return blockIndexInTexture;
        }
    
        public boolean isOpaqueCube()
        {
        	return true;
        }
    
        public void setGraphicsLevel(boolean flag)
        {
            graphicsLevel = flag;
            blockIndexInTexture = baseIndexInPNG + (flag ? 0 : 1);
        }
    
        public void onEntityWalking(World world, int i, int j, int k, Entity entity)
        {
            super.onEntityWalking(world, i, j, k, entity);
        }
    
        public boolean shouldSideBeRendered(IBlockAccess iblockaccess, int i, int j, int k, int l)
        {
        	return true;
        }
        private int baseIndexInPNG;
        int adjacentTreeBlocks[];
    } 

    Do roughly the same thing in these 2 classes as with the sapling. Again, I do a color shift. You could instead (as they do) change the texture. See the original BlockLeaves and BlockLog.

    We don’t need to change anything for these blocks in the main mod_ java file, as we are going to keep them as is. Don’t run the code yet, let’s take a quick break.
    Posted in: Tutorials
  • To post a comment, please .