• 1

    posted a message on [1.3.2] Where is onTileEntityPowered?
    I decided to look at the dispenser since that's the first block that came to mind that uses both a tile entity and uses redstone. There's nothing in its tile entity that relies on power. Instead, the block itself (BlockDispenser) checks to see if it's being indirectly powered by neighboring blocks. If it is, it dispenses the item. In a quick glance it looks like note blocks are the same way.
    Posted in: Modification Development
  • 1

    posted a message on How to kill mobs in a certain radius?
    Quote from snuffysam

    It should, yes. But it doesn't.
    I did all the changes that you mentioned and told it to print out a list of entities.
    Nothing printed out.
    I'm trying to figure out what I did wrong.

    Well, I got mine to work. Here's the code:
    public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
        {
            double var6 = 50.0D;
            List var7 = par1World.getEntitiesWithinAABB(EntityLiving.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(par2 - var6, par3 - var6, par4 - var6, par2 + var6, par3 + 12.0D + var6, par4 + var6));
            Iterator var4 = var7.iterator();
            while (var4.hasNext())
            {
                System.out.println("Hurting entity!");
                Entity var5 = (Entity)var4.next();
                var5.onStruckByLightning(null);
            }
            return true;
        }


    For my experiment I made it occur when the block is right-clicked. I didn't test if it really worked for a radius of 50 blocks, but I got a whole lot of "Hurting entity!" printed out and found a lot of porkchops and feathers littering the ground for at least 15 blocks in any direction.
    Posted in: Modification Development
  • 1

    posted a message on How to kill mobs in a certain radius?
    I would begin with EntityLightningBolt. In its code it gets a list of all mobs within a certain radius (I believe it's a square rather than a proper circular radius):
    double var6 = 3.0D;
    List var7 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(this.posX - var6, this.posY - var6, this.posZ - var6, this.posX + var6, this.posY + 6.0D + var6, this.posZ + var6));
    Iterator var4 = var7.iterator();
    while (var4.hasNext())
    {
        Entity var5 = (Entity)var4.next();
        var5.onStruckByLightning(this);
    }


    var6 is the radius. var7 is a list of all the objects within that radius. Note that it creates a sort of bounding box using the lightning bolt's coordinates and the radius. This method excludes the lightning bolt, but World.java has other similar methods that you can easily call upon. It then begins going through the list and damaging everything in it. After looking at your options in World.java and doing a little experimenting it should be fairly easy for you to kill everything but spiders in a 100-block radius. Limiting the radius if the reactor is enclosed in lead blocks will probably require quite a bit more coding since you'll need to check every block in a wall to make sure it's sealed off, but it'll be doable.

    Focus on getting the entity list first, then experiment with testing for a lead room using world.getBlockId, and then decreasing the radius based on whether or not the room is enclosed will be a piece of cake.
    Posted in: Modification Development
  • 2

    posted a message on [Mods] Chronosmith's Advanced Tutorials [1.3.1]
    Big Buttons

    Today we'll be making our own 1500 megawatt heavy duty super colliding super GUI button. What's so super about it? It's big, but that's enough on its own for now. Some of you may have noticed that buttons are currently limited to 20 pixels high. No more, no less, and that's a bit limiting. Commence picture:



    Kudos if you can name all four characters, but ignore the images on the buttons, they're just there to show what purpose bigger buttons can serve. Also, for some reason hovering over the last button makes all the images turn yellow. Although adding images is not part of this tutorial, let me know if you experience that as well since it's a problem I'd prefer to have fixed. Also, this tutorial is going to focus on a separate button, though the code in this tutorial can easily be applied to GuiButton without ruining normal buttons if you'd rather not create new files.

    Well, let's start off with a blank Java class that extends from GuiButton:
    package net.minecraft.src;
    import net.minecraft.client.Minecraft;
    import org.lwjgl.opengl.GL11;
    public class GuiBigButton extends GuiButton
    {
    public GuiBigButton(int i, int j, int k, String s)
    {
    this(i, j, k, 200, 40, s);
    }
    
    public GuiBigButton(int i, int j, int k, int l, int i1, String s)
    {
    super(i, j, k, l, i1, s);
    }
    
    public void drawButton(Minecraft minecraft, int i, int j)
    {
    }
    }

    By default it's going to create a button with a height of 20, same as a normal button. But if we want our button to be bigger than the default 20 pixels, we'll have to do some more complicated things. Take a look at the code in GuiButton, in drawButton, and also look at /gui/gui.png if you need to. It draws two images: the left of the button, and the right, depending on how wide it is. We'll need to draw a minimum six images if we want it to be taller: a top-left corner, a top-right corner, a bottom-left corner, a bottom-right corner, and at least one left and right side. Let's add some stuff to drawButton. The first few lines are lifted from GuiButton:
    if(!drawButton)
    {
    return;
    }
    FontRenderer fontrenderer = minecraft.fontRenderer;
    GL11.glBindTexture(3553, minecraft.renderEngine.getTexture("/gui/gui.png"));
    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    boolean flag = i >= xPosition && j >= yPosition && i < xPosition + width && j < yPosition + height;
    int k = getHoverState(flag);


    First if-statement, if you don't want the buttons drawn, it saves the computer a lot of time to just skip the rest of the code. The next line sets up our font renderer so we can draw the text on top of the button. Our first GL11 gives us the texture we want to use. Notice it's the default GUI image. I've created another image which allows buttons up to 300 pixels tall and only requires the drawing of four images, but I'm going with the six images 1)It allows for ANY height, and 2)It doesn't require adding new images to Minecraft. The second line makes sure that the coloring is right. If you remember my first tutorial, you know that you can change those values to colorize your button, though I haven't tinkered with it in this context myself. The next two lines essentially detect if the mouse is hovering over the button. Okay, now for code that is actually mine:
    drawTexturedModalRect(xPosition, yPosition, 0, 46 + k * 20, width / 2, 3);
    drawTexturedModalRect(xPosition + width / 2, yPosition, 200 - width / 2, 46 + k * 20, width / 2, 3);


    This will create our top. A quick compare with the default button code shows that my code is almost exactly the same, except MUCH shorter. Two pixels is all that's needed for the top, so that's all we're rendering. Now for the middle:
    for(int i1 = 2; i1 < height - 3; i1 += 15)
    {
    if(i1 + 15 > height - 3)
    {
    	 drawTexturedModalRect(xPosition, yPosition + i1, 0, 46 + k * 20 + 2, width / 2, height - 3 - i1);
    	 drawTexturedModalRect(xPosition + width / 2, yPosition + i1, 200 - width / 2, 46 + k * 20 + 2, width / 2, height - 3 - i1);
    } else
    {
    	 drawTexturedModalRect(xPosition, yPosition + i1, 0, 46 + k * 20 + 2, width / 2, 15);
    	 drawTexturedModalRect(xPosition + width / 2, yPosition + i1, 200 - width / 2, 46 + k * 20 + 2, width / 2, 15);
    }
    }

    The middle is the only part that varies, so of course it's here that the code is most complicated. Of for-statement says that we'll start two pixels down (we already took care of the top two, remember?), and as long as we are less than the total height of the button we'll render the next 15 pixels. Let's focus on the else part first. It draws our left and right edges, but looking at gui.png you'll see there's only 15 pixels of middle content, so we only render 15 at a time. There's 2 pixels for the top, and 3 for the bottom. But we don't want our buttons to be restricted to increments of 15, which is what our if-statement is for. If we need less than 15 pixels we'll render the height of our button, minus 3 pixels for the bottom, minus the number of middle pixels we've already rendered. Hope that wasn't too complicated. Finally, we'll "top" it off with the bottom:
    drawTexturedModalRect(xPosition, yPosition + height - 3, 0, 63 + k * 20, width / 2, 3);
    drawTexturedModalRect(xPosition + width / 2, yPosition + height - 3, 200 - width / 2, 63 + k * 20, width / 2, 3);

    Same concept as the top, except we need three pixels instead of just two. Last, we'll include a bit more code from GuiButton to take care of the text:
    mouseDragged(minecraft, i, j);
    if(!enabled)
    {
    drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xffa0a0a0);
    } else
    if(flag)
    {
    drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xffffa0);
    } else
    {
    drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xe0e0e0);
    }


    Should be self-explanatory. The button can be called in the same way as a normal button, but I'll give you the code anyway. Include this in the initGui function of your GUI to add a button:
    controlList.add(new GuiBigButton(120, 20, height / 3 - 2, 52, 98, "Button1"));

    The parameters of the button in order of appearance are 120 (the button's ID), 20 (distance from the left edge of the screen), height / 3 - 2 (distance from the top of the screen), 52 (width of button), 98 (height of button), "Button1" (text of button, can be left as empty quotations)

    Now for our finished code:

    package net.minecraft.src;
    import net.minecraft.client.Minecraft;
    import org.lwjgl.opengl.GL11;
    public class GuiBigButton extends GuiButton
    {
    public GuiBigButton(int i, int j, int k, String s)
    {
    	 this(i, j, k, 200, 40, s);
    }
    
    public GuiBigButton(int i, int j, int k, int l, int i1, String s)
    {
    	 super(i, j, k, l, i1, s);
    }
    
    public void drawButton(Minecraft minecraft, int i, int j)
    {
    	 if(!drawButton)
    	 {
    		 return;
    	 }
    	 FontRenderer fontrenderer = minecraft.fontRenderer;
    	 GL11.glBindTexture(3553, minecraft.renderEngine.getTexture("/gui/gui.png"));
    	 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    	 boolean flag = i >= xPosition && j >= yPosition && i < xPosition + width && j < yPosition + height;
    	 int k = getHoverState(flag);
    	 drawTexturedModalRect(xPosition, yPosition, 0, 46 + k * 20, width / 2, 2);
    	 drawTexturedModalRect(xPosition + width / 2, yPosition, 200 - width / 2, 46 + k * 20, width / 2, 2);
    	 for(int i1 = 2; i1 < height - 3; i1 += 15)
    	 {
    		 if(i1 + 15 > height - 3)
    		 {
    			 drawTexturedModalRect(xPosition, yPosition + i1, 0, 46 + k * 20 + 2, width / 2, height - 3 - i1);
    			 drawTexturedModalRect(xPosition + width / 2, yPosition + i1, 200 - width / 2, 46 + k * 20 + 2, width / 2, height - 3 - i1);
    		 } else
    		 {
    			 drawTexturedModalRect(xPosition, yPosition + i1, 0, 46 + k * 20 + 2, width / 2, 15);
    			 drawTexturedModalRect(xPosition + width / 2, yPosition + i1, 200 - width / 2, 46 + k * 20 + 2, width / 2, 15);
    			
    		 }
    	 }
    	 drawTexturedModalRect(xPosition, yPosition + height - 3, 0, 63 + k * 20, width / 2, 3);
    	 drawTexturedModalRect(xPosition + width / 2, yPosition + height - 3, 200 - width / 2, 63 + k * 20, width / 2, 3);
    	 mouseDragged(minecraft, i, j);
    	 if(!enabled)
    	 {
    		 drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xffa0a0a0);
    	 } else
    	 if(flag)
    	 {
    		 drawCenteredString(fontrenderer, "Proof your code!", xPosition + width / 2, yPosition + (height - 8) / 2, 0xffffa0);
    	 } else
    	 {
    		 drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, 0xe0e0e0);
    	 }
    }
    }


    Sometime in the future I hope to take this button even further by animating it. In the meantime, feedback is always appreciated.
    Posted in: Tutorials
  • 1

    posted a message on Making an item act as an EnderEye
    I'm no expert at world generation so this seems pretty difficult to me. I can't spell out how to do it for you, but I can at least tell you what I found out and show you where to look. Ultimately World calls a function in MapGenStronghold (though it's inherited from MapGenStructure) called getNearestInstance. If your structure uses a MapGen, you can simply call getNearestInstance and you'll have a ChunkPosition with the xyz coordinates to go to. I'd recommend this approach since the class seems to give you other options such as specifying which biomes your structure can spawn in. It's also probably easier than copying the complicated code found in getNearestInstance.
    Posted in: Modification Development
  • 2

    posted a message on [Mods] Chronosmith's Advanced Tutorials [1.3.1]
    Quote from darklord987

    I'm confused I Have Java Experience But I Don't Know How To Make This Screen Have A Button To Access It. I'm Using It As A Credit Screen For My Mod.

    Have A Sheep! :Sheep:


    I don't think I'll turn it into a full-on tutorial, but here's how I open mine using ModLoader:
    package net.minecraft.src;
    import org.lwjgl.input.Keyboard;
    import net.minecraft.client.Minecraft;
    import java.util.Map;
    public class mod_testMod extends BaseMod
    {
    
    public mod_testMod()
    {
    }
    
    public void keyboardEvent(KeyBinding keybinding)
    {
    	 Minecraft mc = ModLoader.getMinecraftInstance();
    	 if(keybinding == this.AbilityGui && mc.currentScreen == null)
    	 {
    		 mc.displayGuiScreen(new GuiAbilities(mc.thePlayer));
    	 }
    }
    
    public KeyBinding AbilityGui = new KeyBinding("Open Abilities", Keyboard.KEY_T);
    
    public String getVersion()
    {
    	 return "3.1.1";
    }
    
    public void load()
    {
    	 ModLoader.registerKey(this, this.AbilityGui, true);
    	 ModLoader.addLocalization("Abilities", "Opens abilities GUI");
    }
    
    }


    keyboardEvent obviously is what my keypress does. If the key is pressed and there's no other GUI open, open the GUI. The second part you'll see is where I set up the key. I set mine up to use 'T' (originally designed for single player), but since that opens the chat line you might want to pick something else. The two lines in load notify Minecraft of the key you've set up and allow for localization, though the one for localization is optional. And that's the basics of keybinding.

    You say you're using it as a credits screen for your mod. Although some people would look down on modifying a base class, I would look at GuiOptions to figure out how to add a button to a GUI and then by modifying something like GuiMainMenu you can add a credits button for your mod to the front page. Optimally you'd find some way to open the credits without modifying a base class, but I can also understand that not everyone wants the credits to pop up when they accidentally press '\' or some other key.
    Posted in: Tutorials
  • 5

    posted a message on [Mods] Chronosmith's Advanced Tutorials [1.3.1]
    Chronosmith's Advanced Tutorials

    Intro
    I've released or planned to release several mods, all of which are either too small to justify maintaining, or have been one-upped by somebody else. Still, some of the things I've done within these mods are useful and I think others would appreciate knowing how to do it, hence these tutorials.

    Most of these tutorials are advanced and build upon the simpler tutorials that are plentiful on these forums. For example, my GUI background tutorial is designed on the assumption that you already know how to make a basic GUI. If you do not understand the basics, bookmark this page and come back to it when you feel confident enough to teach the basics to somebody else.

    Also, although I will sometimes use ModLoader in my tutorials, some of my mods have changed core aspects of the game and therefore require modifying base classes. If you're dead-set on not changing base classes, you're welcome to develop your own work-around.

    FAQ

    Q: Could you do a mod on [insert topic here]?
    A: Probably not, but you can always ask and I might feel inspiration strike.

    Q: Could you help me with your tutorial?
    A: Let me answer your question with a question: Have you ever solved a null pointer exception all on your own? Some of these tutorials I consider to be advanced material. If you're doing well and I really think you need help, I'll give you the answer. If I think you're good and can solve it with a little nudge, I'll give you a hint. If I think a tutorial is beyond you, I'll politely point you elsewhere.

    Q: Can I use your mod in my mod?
    A: Certainly. I'd be a terrible person if I made a tutorial and didn't let anyone apply what they learned. But keep in mind that although my tutorials teach specific things, they're supposed to teach concepts and get you thinking about new ways to apply it.

    Q: I know how to make your mod more efficient.
    A: Not a question, but I always appreciate constructive criticism. If I agree with you, I'll update my tutorial with your method and give credit.

    Q: Can you use videos?
    A: If I need, I'll upload a video to show off the mod we're making, but my tutorial will NEVER be a video. Programming is text-based and videos of text are a waste of space.

    Q: Your mod is printing stuff all over my debug window!
    A: Ah, so you found that. At the bottom of every mod I include the finished code in case you're having trouble piecing all the individual pieces together. But I don't like the idea of copying code without gaining an understanding of it. It defeats the purpose of a tutorial. So within that finished code I always place a System.out.println that tells you to proof your code instead of just copying it. Sometimes it will be displayed once. Sometimes it will be displayed constantly. Hopefully in searching for it you'll be forced to review the code and ensure that you understand it.

    Current Tutorials
    -GUI Backgrounds
    -Big Buttons

    Upcoming Tutorials
    -Limited distance teleporting (e.g. combat, not transport)
    -Chain lightning attack
    -Socket an item
    -Randomly-generated quests
    -Animating the big button
    -Chests that can hold more than 54 stacks (multiple pages)

    GUI Backgrounds

    Personally, I think darkened backgrounds aren't bad, but I think it's a good idea for people to realize there are other options out there, such as the snazzy background used for achievements. So in one of my mods (roughly based on Diablo), I set about creating my own randomly generated background. Commence picture:



    Yes, the lava is actually animated. Excited? In the above picture I've stripped out all the buttons and extras to show exactly what I'm teaching in this tutorial. First, let's set up a basic GUI:

    package net.minecraft.src;
    import java.util.List;
    import net.minecraft.client.Minecraft;
    import org.lwjgl.input.Keyboard;
    import java.util.Random;
    import org.lwjgl.opengl.GL11;
    import org.lwjgl.input.Mouse;
    
    public class GuiAbilities extends GuiScreen
    {
    protected String screenTitle;
    
    public GuiAbilities(EntityPlayer entityplayer)
    {
    	 screenTitle = "Advanced GUI";
    }
    
    public void initGui()
    
    {
    }
    
    protected void actionPerformed(GuiButton guibutton)
    {
    }
    
    public void drawScreen(int i, int j, float f)
    
    {
    	 drawDefaultBackground();
    	 drawCenteredString(fontRenderer, screenTitle, width / 2, 20, 0x99ccff);
    	 super.drawScreen(i, j, f);
    }
    
    public boolean doesGuiPauseGame()
    {
    	 return false;
    }
    }


    This should give you a basic GUI. Nothing fancy, just a darkened screen with a title. But let's take care of that title while it's there. As you can see, screen title has been set early in the code as "Advanced GUI". I like the variable, but you could just as easily get rid of it and put the quotes in its place in the drawCenteredString. Next is the placement of that string. You have access to two variables: width, and height (height is used later in the tutorial). Simply, they are the width and height of the window. I put width / 2, placing my text flat in the middle of the screen. width / 4 would place the text centered on a quarter from the left of the screen, and 0 would put the text flat against the left (but some of your text would be cut off). Why all the math instead of just a number? Because window sizes change one computer to another another. In a 600 x 400 resolution, 300 would be center, but somebody playing on 1920x1080 would see the text very far to the left of their screen. The 20 is the height, though if you wanted it, say, at the bottom, you could put height - 20. That last thing is the color of the hex. Just look up hex color and put the number corresponding to the color you want in there with a 0x in front like I did. If this is too off-topic for you, let me know and I'll make a separate topic about text.

    Now for the background. This part uses a fair amount of code, so I made a new function called genBackground, like so:
    protected void genBackground(int i, int j, float f)
    {
    }


    Place the call for it in the drawScreen function, like so:
    drawDefaultBackground();
    genBackground(i, j, f);
    drawCenteredString(fontRenderer, screenTitle, width / 2, 20, 0x99ccff);


    It's important that it go between the default background (not even sure if we still need that) and the drawCenteredString so we don't cover up our title with our snazzy background. Next we start adding code to our genBackground function. Begin with these few lines:
    int i1 = mc.renderEngine.getTexture("/terrain.png");
    zLevel = 0.0F;
    GL11.glPushMatrix();
    mc.renderEngine.bindTexture(i1);


    The first line is our texture. The beautiful thing about this is we can choose any picture we want. If you want to use an image of your own design that incorporates blue sky and clouds, you can. Just make sure it's 256x256 pixels and each texture within that png is 16x16. With some ingenuity you can make those images 32x32 or most anything you want, but I won't explain how to do that here. Just know that a good coder can expand on this tutorial to accomplish much more. The next two lines I'm not very familiar with, but the third line is what tells Minecraft to use the texture we specified in the first line.

    Next, add these two lines:
    Random random = new Random();
    random.setSeed(1234);

    This is what makes our image semi-random. But there's a problem. Without that second line, our background will become a frothing mess of rapidly changing textures. By setting the seed, we ensure that our background will be randomly generated, but will stay that random way. With this method, the background will be the same EVERY time, though you'll have one background for windowed mode and one for fullscreen. Once again, a little ingenuity and tinkering and you should be able to make it truly random every time.

    Now for the good stuff. But first, take a look back up at that picture. Notice how toward the top the bricks are all perfect, but as they get lower more and more of them become cracked and moss-covered? This is how I decide the odds of one brick appearing at a certain level:
    for(int l7 = 0; l7 < height; l7 += 16)
    {
    for(int i8 = 0; i8 < width; i8 += 16)
    {
    	 int k8 = Block.stoneBrick.blockIndexInTexture;
    	 if(l7 >= height - 16 || (l7 >= height - 48 && random.nextInt(4) == 0) || (l7 >= height - 32 && random.nextInt(2) == 0))
    	 {
    		 k8 = Block.lavaStill.blockIndexInTexture;
    	 } else
    	 if(l7 >= height - 96 && random.nextInt(4) == 0)
    	 {
    		 k8 = Block.stoneBrick.blockIndexInTexture + 47;
    	 } else
    	 if(l7 >= height - 96 && random.nextInt(4) == 0)
    	 {
    		 k8 = Block.stoneBrick.blockIndexInTexture + 46;
    	 } else
    	 if(l7 >= height / 4 && random.nextInt(8) == 0)
    	 {
    		 k8 = Block.stoneBrick.blockIndexInTexture + 47;
    	 } else
    	 if(l7 >= height / 4 && random.nextInt(8) == 0)
    	 {
    		 k8 = Block.stoneBrick.blockIndexInTexture + 46;
    	 } else
    	 if(l7 >= 32 && random.nextInt(16) == 0)
    	 {
    		 k8 = Block.stoneBrick.blockIndexInTexture + 47;
    	 } else
    	 if(l7 >= 32 && random.nextInt(16) == 0)
    	 {
    		 k8 = Block.stoneBrick.blockIndexInTexture + 46;
    	 } else k8 = Block.stoneBrick.blockIndexInTexture;
    	 drawTexturedModalRect(i8, l7, k8 % 16 << 4, (k8 >> 4) << 4, 16, 16);
    }
    }


    We're drawing in two dimensions, so two for-loops. Our first loop, as you can see, has to do with our height, while our second deals with our width. We will be figuring out all the textures for a row, then doing all the textures for the next row, and so on. If you have an idea that requires horizontal orientation, it shouldn't be very hard to figure out the adjustment.

    By default we have stone bricks as our texture. Why? Because stone bricks are going to be the most common. The one exception to this rule is the very bottom, which is our first if-statement. There are three parts to that first if-statement and respectively translate that all blocks on the bottom will be lava, half of all blocks second from the bottom will be lava, and one-in-four blocks the row above that will be lava. If it's a lava block, the code stops right there and skips down to our drawTexturedModalRect function, which draws the lava block.

    If the texture is not a lava block, it must be either a mossy brick or a cracked brick (46 and 47 respectively). There are three different phases, and both cracked and mossy brick have an equal chance of being drawn in all three phases. The first phase governs all rows within 6 blocks of the bottom, giving them a one-in-four chance of being drawn, or a 50-50 chance that if it isn't lava, it will be one of the two types of damaged brick. The next phase, height / 4, gives us a lesser chance of having damaged bricks. The final phase, is for anything more than three rows from the top. Using your head a little, you can add a bit more or less control if you want it. Last, everything else (including everything in the first three rows) becomes a perfect stone brick. It's a little redundant since we established a default earlier, but on lengthy if trees and switch statements I like to make sure there's a default.

    To wrap up our function, add these two lines to the very end of the function:
    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    GL11.glPopMatrix();


    I don't claim to have a mastery over OpenGL, but this I can say: the first line is crucial if you want to pass my extra-credit section. But first, let's post our completed code:
    package net.minecraft.src;
    import java.util.List;
    import net.minecraft.client.Minecraft;
    import org.lwjgl.input.Keyboard;
    import java.util.Random;
    import org.lwjgl.opengl.GL11;
    import org.lwjgl.input.Mouse;
    
    public class GuiAbilities extends GuiScreen
    {
    protected String screenTitle;
    
    public GuiAbilities(EntityPlayer entityplayer)
    {
    	 screenTitle = "Advanced GUI";
    }
    
    public void initGui()
    
    {
    System.out.println("I copied and pasted without proofing the code!");
    }
    
    protected void actionPerformed(GuiButton guibutton)
    {
    }
    
    public void drawScreen(int i, int j, float f)
    
    {
    	 drawDefaultBackground();
    	 genBackground(i, j, f);
    	 drawCenteredString(fontRenderer, screenTitle, width / 2, 20, 0x99ccff);
    	 super.drawScreen(i, j, f);
    }
    
    protected void genBackground(int i, int j, float f)
    {
    	 int i1 = mc.renderEngine.getTexture("/terrain.png");
    	 zLevel = 0.0F;
    	 GL11.glPushMatrix();
    	 mc.renderEngine.bindTexture(i1);
    	 Random random = new Random();
    	 random.setSeed(1234);
    	 for(int l7 = 0; l7 < height; l7 += 16)
    	 {
    		 for(int i8 = 0; i8 < width; i8 += 16)
    		 {
    			 int k8 = Block.stoneBrick.blockIndexInTexture;
    			 if(l7 >= height - 16 || (l7 >= height - 48 && random.nextInt(4) == 0) || (l7 >= height - 32 && random.nextInt(2) == 0))
    			 {
    				 k8 = Block.lavaStill.blockIndexInTexture;
    			 } else
    			 if(l7 >= height - 96 && random.nextInt(4) == 0)
    			 {
    				 k8 = Block.stoneBrick.blockIndexInTexture + 47;
    			 } else
    			 if(l7 >= height - 96 && random.nextInt(4) == 0)
    			 {
    				 k8 = Block.stoneBrick.blockIndexInTexture + 46;
    			 } else
    			 if(l7 >= height / 4 && random.nextInt(8) == 0)
    			 {
    				 k8 = Block.stoneBrick.blockIndexInTexture + 47;
    			 } else
    			 if(l7 >= height / 4 && random.nextInt(8) == 0)
    			 {
    				 k8 = Block.stoneBrick.blockIndexInTexture + 46;
    			 } else
    			 if(l7 >= 32 && random.nextInt(16) == 0)
    			 {
    				 k8 = Block.stoneBrick.blockIndexInTexture + 47;
    			 } else
    			 if(l7 >= 32 && random.nextInt(16) == 0)
    			 {
    				 k8 = Block.stoneBrick.blockIndexInTexture + 46;
    			 } else k8 = Block.stoneBrick.blockIndexInTexture;
    			 drawTexturedModalRect(i8, l7, k8 % 16 << 4, (k8 >> 4) << 4, 16, 16);
    		 }
    	 }
    
    	 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    	 GL11.glPopMatrix();
    }
    
    public boolean doesGuiPauseGame()
    {
    	 return false;
    }
    }

    Hopefully at this point it runs just fine, but you might have noticed your GUI still doesn't quite look like mine. The difference is the lighting, which seems to be radiating from the lava. To get that effect, add these two lines in between our two for-statements:
    float color = 1.0F - ((float)(height - l7) / 100F) * 0.3F;
    GL11.glColor4f(color + 0.05F, color, color, 1.0F);


    This is how I made the color darker the further it was from the lava. Tinker with the first line to get exactly the darkness or lightness you want at a certain level. Tinker with the second line to get the shade you want. Hint: I made my GUI slightly more red to fit with the Diablo theme. That line I earlier said is crucial for the extra-credit section resets the color back to what it should be when it's done. Otherwise your entire GUI will be dark.
    Posted in: Tutorials
  • 1

    posted a message on Gui Image file
    I know there has to be a GL option for scaling, but I don't know what it is. What's happening is Minecraft has been programmed to look for images 128x128 pixels. Since yours is smaller, it scales the image up to 128x128. So when your image is only 16x16 in an image scaled to 128x128 your code only displays a small part of what appears to be a huge image.

    The fix is simple: make your image 128x128 pixels. Yes, there will be lots of white space, which you can now use for other things if you desire, but your image will be the right size.
    Posted in: Modification Development
  • 1

    posted a message on Is there a method that returns Block when you give it blockID?
    Off the top of my head, I can't think of a method. However, there's an array in Block.java called blocksList. If I remember correctly, the block ID is which element the block is stored in. So for example, if stone has an ID of 1, it will be in blocksList[1]. So just use Block.blocksList[blockID] to get whatever block you're after.
    Posted in: Modification Development
  • 1

    posted a message on [GUI Help]Select Bock on Click [Hardish]
    It's late, and I'm going to bed after this, but here's the code I use for teleporting. First, lemme explain why it's applicable. I don't want to teleport deep into the ground where I'll quickly die. So my code uses where the player is looking, checks if there's a block there, and teleports the player only that far.

    float d = 50F;
    Vec3D vec3d = getPosition(1.0F);
    Vec3D vec3d1 = getLook(1.0F);
    Vec3D vec3d2 = vec3d.addVector(vec3d1.xCoord * d, vec3d1.yCoord * d, vec3d1.zCoord * d);
    if(currentAbility == 0)
    {
    	d = abilities[5][0] * 5; //increasing d increases distance the game looks for blocks
    	vec3d2 = vec3d.addVector(vec3d1.xCoord * d, vec3d1.yCoord * d, vec3d1.zCoord * d);
    	MovingObjectPosition movingobjectposition = worldObj.rayTraceBlocks(vec3d, vec3d2);
    	if(movingobjectposition != null)
    	{
    		Vec3D temp = movingobjectposition.hitVec;
    		setPositionAndRotation(temp.xCoord, temp.yCoord + 2, temp.zCoord, rotationYaw + 180, rotationPitch * -1 + 12);
    	} else
    	{
    		setPositionAndRotation(vec3d2.xCoord, vec3d.yCoord + 2, vec3d.zCoord, rotationYaw + 180, rotationPitch * -1 + 12);
    	}
    }


    The important thing in that code is if movingobjectposition does not equal null. If you look at MovingObjectPosition.java, you'll see wonderful values that do things like specify what you're looking at and what the coordinates are of the block. Using those coordinates you should be able to use something like World's getBlockId function to find what kind of block you're looking at. If it's the kind of block that would have a tile entity associated with it (like a furnace or chest block), then you can access it since you know the coordinates. Personally, I consider this advanced stuff, so be prepared to do a lot of tinkering and bug checking.
    Posted in: Modification Development
  • To post a comment, please .