Jump to content

Tall Block help


Dodzh

Recommended Posts

Hello to all and nice to meet you since this is my first post here  :)

 

Ive read similar post about my question but since no two issues are alike im making this post hoping one of you can help me.

 

Im making my first mod and made a custom block that is 2 blocks tall

now i managed to get it render properly and place on the world.

 

the problem i have is this the lower block works just fine but i cant click on the second top block nor has any collation on it.

 

here is the code im using

 

package com.projects.tallblocksample.blocks;

import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import com.projects.tallblocksample.tallblocksample;
import com.projects.tallblocksample.tileentity.TileEntityTallBlock;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class TallBlockBlock extends BlockContainer {

public TallBlockBlock() {
	super(Material.wood);
	this.setHardness(2.0F);
	this.setResistance(5.0F);
	this.setBlockBounds(0.05F, 0.05F, 0.05F, 0.95F, 2F, 0.95F);
	this.setCreativeTab(tallblocksample.tabtallblocksample);

}

public int getRenderType() {
	return -1;
}

public boolean isOpaqueCube() {
	return false;
}

public boolean renderAsNormalBlock() {
	return false;
}

@Override
public TileEntity createNewTileEntity(World var1, int var2) {
	return new TileEntityTallBlock();
}

@SideOnly(Side.CLIENT)
public void registerBlockIcons(IIconRegister iconRegister) {
	this.blockIcon = iconRegister.registerIcon(tallblocksample.modid + ":" + this.getUnlocalizedName().substring(5));
}

public Item getItemDropped(int i, Random random, int j) {
	return Item.getItemFromBlock(tallblocksample.blockTallBlock);
}

public void onBlockAdded(World world, int x, int y, int z) {
	super.onBlockAdded(world, x, y, z);
	if(world.getBlockMetadata(x, y, z) == 0)
	{
		this.setDefaultDirection(world, x, y, z);
	}		

}

private void setDefaultDirection(World world, int x, int y, int z) {
	if(!world.isRemote) {
		Block b1 = world.getBlock(x, y, z - 1);
		Block b2 = world.getBlock(x,  y,  z + 1);
		Block b3 = world.getBlock(x - 1, y, z);
		Block b4  = world.getBlock(x + 1, y, z);

		byte b0 = 3;

		if(b1.func_149730_j() && !b2.func_149730_j()) {
			b0 = 3;	
		}

		if(b2.func_149730_j() && !b1.func_149730_j()) {
			b0 = 2;	
		}

		if(b3.func_149730_j() && !b4.func_149730_j()) {
			b0 = 5;	
		}

		if(b4.func_149730_j() && !b3.func_149730_j()) {
			b0 = 4;	
		}

		world.setBlockMetadataWithNotify(x, y, x, b0, 2);
	}

}

public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entityplayer, ItemStack itemstack) 
{
	int l = MathHelper.floor_double((double)(entityplayer.rotationYaw * 4.0F / 360.F) + 0.5D) & 3;
	if(l == 0) 
	{
		world.setBlockMetadataWithNotify(x, y, z, 3, 1); 
	}
	if(l == 1) 
	{
		world.setBlockMetadataWithNotify(x, y, z, 4, 1); 
	}
	if(l == 2) 
	{
		world.setBlockMetadataWithNotify(x, y, z, 1, 1);
	}
	if(l == 3) 
	{
		world.setBlockMetadataWithNotify(x, y, z, 2, 1);
	}
	if(itemstack.hasDisplayName()) 
	{
		//TO DO
	}
}
}

 

i realize this might be easy for some of you but please understand im new to MC modding (not new to coding)

 

thank you very much in advance

 

ps: sry English not my first language doing my best  ::)

Link to comment
Share on other sites

I'd make an invisible filler block for the top that has the same breaking characteristics and calls the bottom's methods for things like onblockdestroy or onRightClick... (Whatever you're using). The bottom block would destroy the top one on onBlockDesteoy.

 

interesting suggestion, ty, but do you know of anyway to set the size of the model to 2x blocks high?

Link to comment
Share on other sites

I'd make an invisible filler block for the top that has the same breaking characteristics and calls the bottom's methods for things like onblockdestroy or onRightClick... (Whatever you're using). The bottom block would destroy the top one on onBlockDesteoy.

 

UPDATE: hey david ive been doing some test based on ur idea and is looking promising, ty again for the idea

Link to comment
Share on other sites

I have done this for several blocks in my mod, was pretty hard to figure out, but now I know how, it is really easy.

 

Now it is impossible to make a block larger than 1x1x1 without gag blocks, at least, I couldn't figure it out, and so used this method, but it works great, gui's work, dont have to break all the gag blocks individually etc.

 

Now please for the sake of learning how to do this, don't copy and paste, you wont learn anything, and wont know how to fix any problems, or adapt my code to fit your code. For me, the only acception for copying and pasting code, is if you absolutely understand how it works, and what it all does, and wont learn anything you don't already know.

 

Here I will show you how to make a block more than one meter high, and also, at the end, a trick to make it look like the blocks bounding box is all one, where in reality, it is several blocks.

Method:

 

 

in your block class (the main block with the gui) add the following:

 

 

OnBlockAdded()

        public void onBlockAdded(World world, int x, int y, int z) {
	super.onBlockAdded(world, x, y, z);
	for (int i = 0; i < this.height; i++) {
		world.setBlock(x, y+1+i, z, YourMod.blockYourGagBlock, i, 2);
	}
}

 

Now where it says "this.height" I have an integer for the height of the block, and this just makes it easily changed. Also, in world.setBlock I have used the one that sets the metadata for the height in the structure, so the 5th variable "i" sets the metadata to i The reason for this, I will get to in a minute.

 

Next you need the breakblock method to break the block above.

        public void breakBlock(World world, int x, int y, int z, Block block, int par6) {
	for (int i = 0; i < this.height; i++) {
		world.setBlockToAir(x, y+1+i, z);
	}

Now this is pretty simple, just removes the blocks upto the height of the structure when broken.

 

That is pretty much all for the min block, even dont need anything in onBlockActivated()

 

 

 

Now for your gag block class.

 

 

First you want to make this block have no render, as you are using a model. Do the following:

        public int getRenderType() {
	return -1;
}

@Override
public boolean renderAsNormalBlock() {
	return false;
}

@Override
public boolean isOpaqueCube() {
	return false;
}

So the render type, as you probably know, sets the model, if it is -1, there is no model, you use your own. The renderAsNormalBlock makes it so it is not a full 1x1x1 meter cube, and isOpaqueCube allows light to pass through. I think renderAsNormalBlock also makes it so that the faces of adjacent blocks are rendered, otherwise, you would see through the world.

 

Next you want to set the metadata values.

        public void getSubBlocks(Item itemStack, CreativeTabs tab, List list) {
	for (int i = 0; i < blockYourMainBlock.height; ++i) {
		list.add(new ItemStack(itemStack, 1, i));
	}
}

This basically makes this block have as many metadata sub types as your main blocks height. again, why the height variable is useful, you dont have to go round looking for all the places you have used this to change it.

 

Next, you need your onBlockActivated method, you said that you cant make it so when the top block is clicked, it opens the gui of the bottom, this is actually easy, just give it the coords of the bottom.

        public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitx, float hity, float hitz) {

	for (int i = 0; i < blockYourMainBlock.height + 1; i++) {
		TileEntity tile = world.getTileEntity(x, y - i, z);

		if (tile instanceof TileEntityYourMainBlocksTile) {
			TileEntityYourMainBlocksTile main = (TileEntityYourMainBlocksTile) world.getTileEntity(x, i, z);
			FMLNetworkHandler.openGui(player, YourMod.INSTANCE, YourMod.guiIdYourGuiId, world, x, y - i, z);
			return true;
		}
	}
	return true;
}

So what this does is it searches for the main block when clicked, it searches downwards for the height of the structure plus one, because the height is only the number of blocks added above, you want it to search one extra to find the main one.

The if statement checks if the tileentity is an instance of your main blocks tileentity before setting it to the main tile, if it didn't do this, you might get a ClassCastException if it didn't find the main tile. it also will only open the gui if the tile at those coords is the main tile.

And also, you can pass the coords of the openGui to open a gui at different coords, I diddnt figure this out and spent ages trying to find a way, but this does work.

 

Next, you want the breakBlock method. This one is a bit complicated, and messy, and I have used if statements, where I could have used a switch statment, but that can be easily changed.

        public void breakBlock(World world, int x, int y, int z, Block block, int par6) {

	if (world.getBlockMetadata(x, y, z) == 0) { // only one above the main block
		world.setBlockToAir(x, y-1, z);
		world.setBlockToAir(x, y+8, z);
	} else if (world.getBlockMetadata(x, y, z) == 1) { //only two above the main block
		world.setBlockToAir(x, y-2, z);
		world.setBlockToAir(x, y+7, z);
	} else if (world.getBlockMetadata(x, y, z) == 2) { // three etc
		world.setBlockToAir(x, y-3, z);
		world.setBlockToAir(x, y+6, z);
	} else if (world.getBlockMetadata(x, y, z) == 3) {
		world.setBlockToAir(x, y-4, z);
		world.setBlockToAir(x, y+5, z);
	} else if (world.getBlockMetadata(x, y, z) == 4) {
		world.setBlockToAir(x, y-5, z);
		world.setBlockToAir(x, y+4, z);
	} else if (world.getBlockMetadata(x, y, z) == 5) {
		world.setBlockToAir(x, y-6, z);
		world.setBlockToAir(x, y+3, z);
	} else if (world.getBlockMetadata(x, y, z) == 6) {
		world.setBlockToAir(x, y-7, z);
		world.setBlockToAir(x, y+2, z);
	} else if (world.getBlockMetadata(x, y, z) == 7) {
		world.setBlockToAir(x, y-8, z);
		world.setBlockToAir(x, y+1, z);
	} else if (world.getBlockMetadata(x, y, z) ==  {
		world.setBlockToAir(x, y-9, z);
		world.setBlockToAir(x, y+0, z);
	}
}

Now I did find this one a bit difficult to get working with the structure height variable, so you would have to change these numbers to your needs, and also, my structure is 9 blocks tall (it is a wind turbine). This is where it is really down to you to play around, and find the right numbers.

 

Now this really isn't needed, but it makes the block bounds look nicer.

        public void setBlockBoundsBasedOnState(IBlockAccess iblockAccess, int x, int y, int z) {

	if (iblockAccess.getBlockMetadata(x, y, z) == 0) {
		this.setBlockBounds(0.0F, -1.0F, 0.0F, 1.0F, 8.5F, 1.0F);
	} else if(iblockAccess.getBlockMetadata(x, y, z) == 1) {
		this.setBlockBounds(0.0F, -2.0F, 0.0F, 1.0F, 7.5F, 1.0F);
	} else if(iblockAccess.getBlockMetadata(x, y, z) == 2) {
		this.setBlockBounds(0.0F, -3.0F, 0.0F, 1.0F, 6.5F, 1.0F);
	} else if(iblockAccess.getBlockMetadata(x, y, z) == 3) {
		this.setBlockBounds(0.0F, -4.0F, 0.0F, 1.0F, 5.5F, 1.0F);
	} else if(iblockAccess.getBlockMetadata(x, y, z) == 4) {
		this.setBlockBounds(0.0F, -5.0F, 0.0F, 1.0F, 4.5F, 1.0F);
	} else if(iblockAccess.getBlockMetadata(x, y, z) == 5) {
		this.setBlockBounds(0.0F, -6.0F, 0.0F, 1.0F, 3.5F, 1.0F);
	} else if(iblockAccess.getBlockMetadata(x, y, z) == 6) {
		this.setBlockBounds(0.0F, -7.0F, 0.0F, 1.0F, 2.5F, 1.0F);
	} else if(iblockAccess.getBlockMetadata(x, y, z) == 7) {
		this.setBlockBounds(0.0F, -8.0F, 0.0F, 1.0F, 1.5F, 1.0F);
	} else if(iblockAccess.getBlockMetadata(x, y, z) ==  {
		this.setBlockBounds(0.0F, -9.0F, 0.0F, 1.0F, 0.5F, 1.0F);
	} else {
		this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
	}
}

Basically, this was another reason I used metadata for each height in the structure. What this does is make each metadata value of the gag block have a different block bound, so what you can do is make it so that for example, if you mouse over gag block one, the bounds extend down over the bottom, and up over as many blocks high the structure is, and gag two extends two blocks down etc. It makes it look like the block bounds are onlu one block.

 

 

 

 

 

Hope this helped.

 

Ps- I noticed that you are setting the blocks rotation with metadata in the main block class, now if you have a model, this wont work, the block will rotate, but the model wont, so unless you have already done so, rotate the model with GL11.rotatef(amount, rotateX, rotateY, rotateZ); and do this based on the metadata in the main block.

Just pointing that out.

I ask complicated questions, and apparently like to write really long detailed posts. But I also help others when I can.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.