Jump to content

Switching facing texture of a block


Recommended Posts

After finishing some code up for one of my block i decided to change the face texture of the block during placement. I've got the texture switching on placement but its doing it for every single block. I'm also storing the facing direction in a tileEntity so it stays per block, but this doesn't help. I think what i'm doing wrong is changing the texture of the block which changes it for all block. Though i'm too tire right now to figure out how to correct it. So any suggestion on how to fix this would be helpful.

 

BlockCode

package net.minecraft.src.eui;

import java.util.Random;
import net.minecraft.src.*;
import net.minecraft.src.eui.grinder.GuiGrinder;
import net.minecraft.src.eui.grinder.TileEntityGrinder;
import net.minecraft.src.forge.*;

public class BlockMachine extends BlockContainer implements ITextureProvider
{
    
    private Random furnaceRand = new Random();  
    private static boolean keepFurnaceInventory = true;

    public BlockMachine(int par1)
    {
        super(par1, Material.iron);
    }
    public int idDropped(int par1, Random par2Random, int par3)
    {
        return this.blockID;
    }
    public int getBlockTextureFromSideAndMetadata(int side, int meta)
    {
    	// zero is bottom one is top
    	int facing = TileEntityMachine.getFacingDireciton();
        switch(meta)
        {
        case 0: 
        	if(side == 1)
        	{
        		return 6;
        	}
        	if(side == 0)
        	{
        		return 5;
        	}
        	if(side == facing)
        	{
        		return 2;
        	}
        	else
        	{
        		return 1;
        	}
        }
	return meta;
    }

    /**
     * Called upon block activation (left or right click on the block.). The three integers represent x,y,z of the
     * block.
     */
    public boolean blockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer)
    {
        if (par1World.isRemote)
        {
            return true;
        }
        else
        {
            TileEntity blockEntity = (TileEntity)par1World.getBlockTileEntity(par2, par3, par4);

            if (blockEntity != null)
            {
            	if(blockEntity instanceof TileEntityGrinder)
            	{
            	TileEntity var6 = (TileEntityGrinder)par1World.getBlockTileEntity(par2, par3, par4);
            	ModLoader.openGUI(par5EntityPlayer, new GuiGrinder(par5EntityPlayer.inventory, (TileEntityGrinder) var6 )); ;
            	}
            }

            return true;
        }
    }    
    @Override
    public TileEntity getBlockEntity(int meta)
    {
        switch(meta)
        {    
        case 0: return new TileEntityGrinder();
        }
	return null;
    }

    /**
     * Called when the block is placed in the world.
     */
    public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)
    {
        int var6 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
        TileEntityMachine blockEntity = (TileEntityMachine) par1World.getBlockTileEntity(par2, par3, par4);
        if (var6 == 0)
        {
            blockEntity.setFacingDireciton(2);
        }

        if (var6 == 1)
        {
        	blockEntity.setFacingDireciton(3);
        }

        if (var6 == 2)
        {
        	blockEntity.setFacingDireciton(4);
        }

        if (var6 == 3)
        {
        	blockEntity.setFacingDireciton(5);
        }
    }
/**
     * Called whenever the block is removed.
     */
    public void onBlockRemoval(World par1World, int par2, int par3, int par4)
    {
        if (!keepFurnaceInventory)
        {
            TileEntityGrinder var5 = (TileEntityGrinder)par1World.getBlockTileEntity(par2, par3, par4);

            if (var5 != null)
            {
                for (int var6 = 0; var6 < var5.getSizeInventory(); ++var6)
                {
                    ItemStack var7 = var5.getStackInSlot(var6);

                    if (var7 != null)
                    {
                        float var8 = this.furnaceRand.nextFloat() * 0.8F + 0.1F;
                        float var9 = this.furnaceRand.nextFloat() * 0.8F + 0.1F;
                        float var10 = this.furnaceRand.nextFloat() * 0.8F + 0.1F;

                        while (var7.stackSize > 0)
                        {
                            int var11 = this.furnaceRand.nextInt(21) + 10;

                            if (var11 > var7.stackSize)
                            {
                                var11 = var7.stackSize;
                            }

                            var7.stackSize -= var11;
                            EntityItem var12 = new EntityItem(par1World, (double)((float)par2 + var8), (double)((float)par3 + var9), (double)((float)par4 + var10), new ItemStack(var7.itemID, var11, var7.getItemDamage()));

                            if (var7.hasTagCompound())
                            {
                                var12.item.setTagCompound((NBTTagCompound)var7.getTagCompound().copy());
                            }

                            float var13 = 0.05F;
                            var12.motionX = (double)((float)this.furnaceRand.nextGaussian() * var13);
                            var12.motionY = (double)((float)this.furnaceRand.nextGaussian() * var13 + 0.2F);
                            var12.motionZ = (double)((float)this.furnaceRand.nextGaussian() * var13);
                            par1World.spawnEntityInWorld(var12);
                        }
                    }
                }
            }
        }

        super.onBlockRemoval(par1World, par2, par3, par4);
    }
@Override
public TileEntity getBlockEntity() {
	// TODO Auto-generated method stub
	return null;
}
@Override
public String getTextureFile() {
	// TODO Auto-generated method stub
	return "/eui/blocks.png";
}
}

TileEntityMachine Code

package net.minecraft.src.eui;

import net.minecraft.src.*;
import net.minecraft.src.ueapi.*;

public class TileEntityMachine extends TileEntity {
 private static int facing = 0;
public static int getFacingDireciton()
{
	return facing;
}   
public static void setFacingDireciton(int side)
{
	facing = side;
}
 public void writeToNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.writeToNBT(par1NBTTagCompound);
        par1NBTTagCompound.setInteger("facing", (int)this.facing);
        
    }
 public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.readFromNBT(par1NBTTagCompound);
        this.facing = par1NBTTagCompound.getInteger("facing");
    }

}

Link to comment
Share on other sites

If you look at the furnace block, it faces whatever direction you place it. Maybe you can look at that as reference.

I did, the way the furnace does it is by using metadata to change facing direction. Since i plan to put 16 machines in this one block i cant do that. Right now i know ic2 and redpower use tileEntities to control the textures, but since i can't look at there code i don't know how they do it.

Link to comment
Share on other sites

If you look at the furnace block, it faces whatever direction you place it. Maybe you can look at that as reference.

I did, the way the furnace does it is by using metadata to change facing direction. Since i plan to put 16 machines in this one block i cant do that. Right now i know ic2 and redpower use tileEntities to control the textures, but since i can't look at there code i don't know how they do it.

 

They just lookup the TE in the callback and pass the arguments to it and return what it returns, simple.

Link to comment
Share on other sites

If you look at the furnace block, it faces whatever direction you place it. Maybe you can look at that as reference.

I did, the way the furnace does it is by using metadata to change facing direction. Since i plan to put 16 machines in this one block i cant do that. Right now i know ic2 and redpower use tileEntities to control the textures, but since i can't look at there code i don't know how they do it.

 

They just lookup the TE in the callback and pass the arguments to it and return what it returns, simple.

that's what i thought so i added a function in my tileentity and got it to return the facing side. It worked at first but then the blocks started to all change facing direction with each other. They textures rotate on placement so i know its at least storing and getting the facing direction. However, i think what happening is when i go to change the texture i do it for every block instead of just one.

Link to comment
Share on other sites

If you look at the furnace block, it faces whatever direction you place it. Maybe you can look at that as reference.

I did, the way the furnace does it is by using metadata to change facing direction. Since i plan to put 16 machines in this one block i cant do that. Right now i know ic2 and redpower use tileEntities to control the textures, but since i can't look at there code i don't know how they do it.

 

They just lookup the TE in the callback and pass the arguments to it and return what it returns, simple.

that's what i thought so i added a function in my tileentity and got it to return the facing side. It worked at first but then the blocks started to all change facing direction with each other. They textures rotate on placement so i know its at least storing and getting the facing direction. However, i think what happening is when i go to change the texture i do it for every block instead of just one.

Then you are not doing it all possible situations.  If you do it in 1, you must do it in all, else you will get what you see.

Link to comment
Share on other sites

Then you are not doing it all possible situations.  If you do it in 1, you must do it in all, else you will get what you see.

Didn't quite understand that but, how would i go by making it so it only changes the texture of one instance of the block.

By making it change to the other image when it is *not* that instance.  You need to cover all cases.  It is more functional and less procedural per block, think of it that way.

Link to comment
Share on other sites

Try this: http://www.minecraftforum.net/topic/1154044-12520412-duckys-modding-tutorials-make-your-blocks-nice-now-with-cables-api/

 

Instead of using the metadata, use a variable stored in the tile entity.

I'm not using metadata for changing textures. I'm using it to change what the block does and its tileEntity.

 

:/ was actual about to just make my own custom render but was trying to avoid that. Though i could do some cool things with a custom model and render for the block. If i can't get this working using a normal block i'll try that :) . Also i've used that tut to make my steam pipes worked out well so far.

 

Also i am using a variable stored in the tile entity which is resulting in a texture change. Just for some reason it changes the texture for all blocks of the same type and stores the same value. Now that i'm thinking of it i can store a value to change what the block does. Is there a way to add data to a tileEntity when you place it?

Link to comment
Share on other sites

Also i am using a variable stored in the tile entity which is resulting in a texture change. Just for some reason it changes the texture for all blocks of the same type and stores the same value. Now that i'm thinking of it i can store a value to change what the block does. Is there a way to add data to a tileEntity when you place it?

 

Would help if you posted your current code for your getBlockTextureFromSideAndMetadata function, because if you are still using the one that calls the static function:

int facing = TileEntityMachine.getFacingDireciton();

Then that would not work for sure.  So post your current version of that function and the function in your TE that it calls?  Remember that all of it must not be static or it will not work.

Link to comment
Share on other sites

here is my current tileEntityMachine code

package net.minecraft.src.eui;

import net.minecraft.src.*;
import net.minecraft.src.ueapi.*;

public class TileEntityMachine extends TileEntity {
 private int facing = 0;
public int getFacingDireciton()
{
	return this.facing;
}   
public void setFacingDireciton(int side)
{
	this.facing = side;
}
 public void writeToNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.writeToNBT(par1NBTTagCompound);
        par1NBTTagCompound.setInteger("facing", (int)this.facing);
        
    }
 public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.readFromNBT(par1NBTTagCompound);
        this.facing = par1NBTTagCompound.getInteger("facing");
    }
 	 public int getBlockTexture(int side, int meta)
    {
    	// zero is bottom one is top
    	int facing = this.getFacingDireciton();
        switch(meta)
        {
        case 0: 
        	if(side == 1)
        	{
        		return 6;
        	}
        	if(side == 0)
        	{
        		return 5;
        	}
        	if(side == facing)
        	{
        		return 2;
        	}
        	else
        	{
        		return 1;
        	}
        }
		return meta;
    }

}

I'm trying to recode the block code right now but can't seem to get it's xyz coords inorder to get the tileEntity at its location.

it hasn't changed much but i moving some of the texture code inside the tileEntity

package net.minecraft.src.eui;

import java.util.Random;
import net.minecraft.src.*;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.eui.grinder.GuiGrinder;
import net.minecraft.src.eui.grinder.TileEntityGrinder;
import net.minecraft.src.forge.*;

public class BlockMachine extends BlockContainer implements ITextureProvider
{
    
    private Random furnaceRand = new Random();  
    private static boolean keepFurnaceInventory = true;

    public BlockMachine(int par1)
    {
        super(par1, Material.iron);
    }
    public int idDropped(int par1, Random par2Random, int par3)
    {
        return this.blockID;
    }
    public int getBlockTextureFromSideAndMetadata(int side, int meta)
    {
    	TileEntity blockEntity = (TileEntity)World.getBlockTileEntity(, par3, par4); //error here since i can't get par2, par3 and par4 inside this method
    	return ((TileEntityMachine) blockEntity).getBlockTexture(side,meta);
    }

    /**
     * Called upon block activation (left or right click on the block.). The three integers represent x,y,z of the
     * block.
     */
    public boolean blockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer)
    {
        if (par1World.isRemote)
        {
            return true;
        }
        else
        {
            TileEntity blockEntity = (TileEntity)par1World.getBlockTileEntity(par2, par3, par4);

            if (blockEntity != null)
            {
            	if(blockEntity instanceof TileEntityGrinder)
            	{
            	TileEntity var6 = (TileEntityGrinder)par1World.getBlockTileEntity(par2, par3, par4);
            	ModLoader.openGUI(par5EntityPlayer, new GuiGrinder(par5EntityPlayer.inventory, (TileEntityGrinder) var6 )); ;
            	}
            }

            return true;
        }
    }    
    @Override
    public TileEntity getBlockEntity(int meta)
    {
        switch(meta)
        {    
        case 0: return new TileEntityGrinder();
        }
	return null;
    }

    /**
     * Called when the block is placed in the world.
     */
    public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)
    {
        int var6 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
        TileEntityMachine blockEntity = (TileEntityMachine) par1World.getBlockTileEntity(par2, par3, par4);
        if (var6 == 0)
        {
            blockEntity.setFacingDireciton(2);
        }

        if (var6 == 1)
        {
        	blockEntity.setFacingDireciton(3);
        }

        if (var6 == 2)
        {
        	blockEntity.setFacingDireciton(4);
        }

        if (var6 == 3)
        {
        	blockEntity.setFacingDireciton(5);
        }
    }
/**
     * Called whenever the block is removed.
     */
    public void onBlockRemoval(World par1World, int par2, int par3, int par4)
    {
        if (!keepFurnaceInventory)
        {
            TileEntityGrinder var5 = (TileEntityGrinder)par1World.getBlockTileEntity(par2, par3, par4);

            if (var5 != null)
            {
                for (int var6 = 0; var6 < var5.getSizeInventory(); ++var6)
                {
                    ItemStack var7 = var5.getStackInSlot(var6);

                    if (var7 != null)
                    {
                        float var8 = this.furnaceRand.nextFloat() * 0.8F + 0.1F;
                        float var9 = this.furnaceRand.nextFloat() * 0.8F + 0.1F;
                        float var10 = this.furnaceRand.nextFloat() * 0.8F + 0.1F;

                        while (var7.stackSize > 0)
                        {
                            int var11 = this.furnaceRand.nextInt(21) + 10;

                            if (var11 > var7.stackSize)
                            {
                                var11 = var7.stackSize;
                            }

                            var7.stackSize -= var11;
                            EntityItem var12 = new EntityItem(par1World, (double)((float)par2 + var8), (double)((float)par3 + var9), (double)((float)par4 + var10), new ItemStack(var7.itemID, var11, var7.getItemDamage()));

                            if (var7.hasTagCompound())
                            {
                                var12.item.setTagCompound((NBTTagCompound)var7.getTagCompound().copy());
                            }

                            float var13 = 0.05F;
                            var12.motionX = (double)((float)this.furnaceRand.nextGaussian() * var13);
                            var12.motionY = (double)((float)this.furnaceRand.nextGaussian() * var13 + 0.2F);
                            var12.motionZ = (double)((float)this.furnaceRand.nextGaussian() * var13);
                            par1World.spawnEntityInWorld(var12);
                        }
                    }
                }
            }
        }

        super.onBlockRemoval(par1World, par2, par3, par4);
    }
@Override
public TileEntity getBlockEntity() {
	// TODO Auto-generated method stub
	return null;
}
@Override
public String getTextureFile() {
	// TODO Auto-generated method stub
	return "/eui/blocks.png";
}
}

Link to comment
Share on other sites

duo, i fill stupid missed this

public int getBlockTexture(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
    {
        return this.getBlockTextureFromSideAndMetadata(par5, par1IBlockAccess.getBlockMetadata(par2, par3, par4));
    }

started scanning threw the block.class as i was think what you meant and found it. Should help me get this working now that i can get the xyz.  Thank you again for help me and not doing it for me.

 

Edit: had to do a little more but that was basically it once i moved the texture code back into the block class. Spent 10 mins correcting the directions when place and i am done. Here is a simply version of my code for the next person who needs it.

TileEntity***.class

public class TileEntity*** extends TileEntity {
 private int facing;
public int getFacingDireciton()
{
	return this.facing;
}   
public void setFacingDireciton(int side)
{
	this.facing = side;
}
 public void writeToNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.writeToNBT(par1NBTTagCompound);
        par1NBTTagCompound.setInteger("facing", (int)this.facing);
        
    }
 public void readFromNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.readFromNBT(par1NBTTagCompound);
        this.facing = par1NBTTagCompound.getInteger("facing");
    } 	

}

and Block***.class

public block extends Block
{
//normal block code snipped
  public int getBlockTexture(IBlockAccess par1IBlockAccess, int x, int y, int z, int side)
    {
    
    	TileEntity blockEntity = par1IBlockAccess.getBlockTileEntity(x, y, z);
    	int meta = par1IBlockAccess.getBlockMetadata(x, y, z); 
    	if(side == 1)
        {
			 switch(meta)
			 {
			 case 0: return #;
			 default: return #;
			 }
        }
        if(side == ((TileEntity***)blockEntity).getFacingDireciton())
        {
        	switch(meta)
        	{
        	case 0: return #;
        	default: return #;
        	}
        }
	return #;
    }
public void onBlockPlacedBy(World par1World, int par2, int par3, int par4, EntityLiving par5EntityLiving)
    {
        int var6 = MathHelper.floor_double((double)(par5EntityLiving.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
        TileEntity blockEntity = (TileEntity) par1World.getBlockTileEntity(par2, par3, par4);
        //0-4 are directions the player is facing on the compass, though i don't know which is which, but trial and error got me the write answers
        if (var6 == 0)
        {
           ((TileEntity***)blockEntity).setFacingDireciton(2);
        }

        if (var6 == 1)
        {
        	((TileEntity***)blockEntity).setFacingDireciton(5);
        }

        if (var6 == 2)
        {
        	((TileEntity***)blockEntity).setFacingDireciton(3);
        }

        if (var6 == 3)
        {
        	((TileEntity***)blockEntity).setFacingDireciton(4);
        }
       
    }
}
public TileEntity getBlockEntity(int meta)
    {
        switch(meta)
        {    
        case 0: return new TileEntity***();
        }
	return null;
    }

This code should work :)

 

Link to comment
Share on other sites

A lot of machines seems to require rotation of,it's textures. You think it's a good idea I include something like that in the API?

No.

 

Because every block does it different, even the blocks in my mod do.  Sometimes they need to rotate only on one axis, something the faces need to rotate around an axis while having the body also rotate around.  Sometimes it needs to be stored in metadata, other times Tile Entities.  Some times it is generated based on some state, some times it might just be a variable.  In all cases it is still very simple to do.

Link to comment
Share on other sites

Just giving code like most tutorials do does not help the person to learn.  Copy/Paste coding is not coding.  The best way to learn is to examine things through the MC source, debug around and follow the flow control paths, etc...  :)

yes your are right but i spent a week figuring this out. Even though i like it when people learn, sometimes it help if they have something too start with. Then they can learn when they go to edit the code i have up there to meet there needs. Similar to how i started, i copied and pasted code for the few things i did. Then i started to change how it worked too meet my needs. After that i was deep into figuring things out myself, with a few post like this when i got stuck. With a  little bit of using what i figured out and i usual get how to code it each time.

I have a question. I have a similar block that rotates but when right clicked with a wrench. Everything rotates fine. The problem is that the block doesn't update it's texture unless another block is either broken or placed. How can I update the block's texture?

Reading that just made me release if i use your wrench from the base mod How do i rotate my machines. Would i just make a method that gets the item the player is right clicking with? and then do the rotations stuff.

Link to comment
Share on other sites

You saw the Universal Components page right? I included in there the object reference for the wrench item. Basically do this.

 

//First of course you import the Universal Components package
import net.minecraft.src.universalelectricity.components

//Then in the on the blockActivated method check if the user is holding a wrench. If so, then rotate it!

               /**
        	 * Check if the player is holding a wrench or an electric item. If so, do not open the GUI.
        	 */
        	if(par5EntityPlayer.inventory.getCurrentItem() != null)
        	{
        		if(par5EntityPlayer.inventory.getCurrentItem().itemID == UniversalComponents.ItemWrench.shiftedIndex)
            	{
        			//Reorient the block
        			int metadata = par1World.getBlockMetadata(par2, par3, par4);
        			switch(metadata)
        			{
                                        //In your case, set the tile entity data.
        			case 2: par1World.setBlockMetadataWithNotify(par2, par3, par4, 5); break;
        			case 5: par1World.setBlockMetadataWithNotify(par2, par3, par4, 3); break;
        			case 3: par1World.setBlockMetadataWithNotify(par2, par3, par4, 4); break;
        			case 4: par1World.setBlockMetadataWithNotify(par2, par3, par4, 2); break;
        			}
        			
        			return true;
            	}
        		else if(par5EntityPlayer.inventory.getCurrentItem().getItem() instanceof UEItemElectric)
        		{
        			return false;
        		}
        	}

Link to comment
Share on other sites

You are probably calling world.setBlockMetadata, you need to call world.setBlockMetadataWithNotify I think.

 

I changed my code to setBlockMetadataWithNotify . The texture still doesn't update unless there is a block change nearby.

 

EDIT: I figured it out. I need to set this:

this.setRequiresSelfNotify();

 

EDIT 2: OK I have another problem now. I decided NOT to use metadata to save the direction and to use the tile entity instead. After the change, the texture of the block will not change or update unless a block besides it changes. Same problem. I tried cheating by setting the block metadata into the same metadata but it doesn't work.

Link to comment
Share on other sites

You are probably calling world.setBlockMetadata, you need to call world.setBlockMetadataWithNotify I think.

 

I changed my code to setBlockMetadataWithNotify . The texture still doesn't update unless there is a block change nearby.

 

EDIT: I figured it out. I need to set this:

this.setRequiresSelfNotify();

 

EDIT 2: OK I have another problem now. I decided NOT to use metadata to save the direction and to use the tile entity instead. After the change, the texture of the block will not change or update unless a block besides it changes. Same problem. I tried cheating by setting the block metadata into the same metadata but it doesn't work.

have you tried to call the getTexture method when changing direction. Not sure if it will work but its worth a try. Also try set block needs updating similar to how redstone wire calls for updating.

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.



×
×
  • Create New...

Important Information

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