Jump to content

[1.7.10]Make Block Face Player


grand_mind1

Recommended Posts

Hi, I'm trying to make my block with a TileEntitySpecialRenderer face the player when he places it. I've looked into the furnace and anvil code to try to replicate it. At the moment, I'm not sure if it's the actual block not facing the correct direction or the model. I think it is probably the model, because the bounding box seems to change the correct orientation even when the model does not.

 

My Block Class:

 

public class BlockPoweredAnvil extends BlockContainer implements ITileEntityProvider
{
    private Random rand = new Random();

    public IIcon[] icons = new IIcon[2];

    public BlockPoweredAnvil()
    {
        super(Material.rock);
        this.setCreativeTab(CreativeTabPandM.PANDM_TAB);
        this.setBlockName(Names.POWERED_ANVIL);
        this.setBlockTextureName(this.getUnwrappedUnlocalizedName(this.getUnlocalizedName()));
    }

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

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

    @Override
    public int getRenderType()
    {
        return -1;
    }

    @Override
    public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entityLivingBase, ItemStack itemStack)
    {
        LogHelper.info("Block Placed");
        int l = MathHelper.floor_double((double)(entityLivingBase.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
        int i1 = world.getBlockMetadata(x, y, z) >> 2;
        ++l;
        l %= 4;

        if (l == 0)
        {
            LogHelper.info("0");
            world.setBlockMetadataWithNotify(x, y, z, 2 | i1 << 2, 2);
        }

        if (l == 1)
        {
            LogHelper.info("1");
            world.setBlockMetadataWithNotify(x, y, z, 3 | i1 << 2, 2);
        }

        if (l == 2)
        {
            LogHelper.info("2");
            world.setBlockMetadataWithNotify(x, y, z, 0 | i1 << 2, 2);
        }

        if (l == 3)
        {
            LogHelper.info("3");
            world.setBlockMetadataWithNotify(x, y, z, 1 | i1 << 2, 2);
        }
    }

    public void setBlockBoundsBasedOnState(IBlockAccess iBlockAccess, int x, int y, int z)
    {
        int l = iBlockAccess.getBlockMetadata(x, y, z) & 3;

        if (l != 3 && l != 1)
        {
            this.setBlockBounds(0.125F, 0.0F, 0.0F, 0.875F, 1.0F, 1.0F);
        }
        else
        {
            this.setBlockBounds(0.0F, 0.0F, 0.125F, 1.0F, 1.0F, 0.875F);
        }
    }

    @Override
    public void registerBlockIcons(IIconRegister iconRegister)
    {
        for (int i = 0; i < 2; i ++)
        {
            this.icons[i] = iconRegister.registerIcon(this.textureName + i);
        }
    }

    @Override
    public IIcon getIcon(int side, int meta)
    {
        if (side == 1)
        {
            return icons[0];
        }
        return icons[1];
    }

    @Override
    public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int meta, float hitX, float hitY, float hitZ)
    {
        if (!world.isRemote && world.getTileEntity(x, y, z) instanceof TileEntityPoweredAnvil)
        {
            entityPlayer.openGui(PandM.instance, GUIs.POWERED_ANVIL.ordinal(), world, x, y, z);
        }
        return true;
    }

    @Override
    public void breakBlock(World world, int x, int y, int z, Block block, int meta)
    {
        TileEntityPoweredAnvil poweredAnvil = (TileEntityPoweredAnvil) world.getTileEntity(x, y, z);
        if (poweredAnvil != null)
        {
            for (int i = 0; i < poweredAnvil.getSizeInventory(); i++)
            {
                ItemStack itemStack = poweredAnvil.getStackInSlot(i);
                if (itemStack != null)
                {
                    float f = this.rand.nextFloat() * 0.8F + 0.1F;
                    float f1 = this.rand.nextFloat() * 0.8F + 0.1F;
                    float f2 = this.rand.nextFloat() * 0.8F + 0.1F;

                    while (itemStack.stackSize > 0)
                    {
                        int j = this.rand.nextInt(21) + 10;

                        if (j > itemStack.stackSize)
                        {
                            j = itemStack.stackSize;
                        }
                        itemStack.stackSize -= j;
                        EntityItem entityitem = new EntityItem(world, (double) ((float) x + f), (double) ((float) y + f1), (double) ((float) z + f2), new ItemStack(itemStack.getItem(), j, itemStack.getItemDamage()));

                        if (itemStack.hasTagCompound())
                        {
                            entityitem.getEntityItem().setTagCompound((NBTTagCompound) itemStack.getTagCompound().copy());
                        }

                        float f3 = 0.05F;
                        entityitem.motionX = (double) ((float) this.rand.nextGaussian() * f3);
                        entityitem.motionY = (double) ((float) this.rand.nextGaussian() * f3 + 0.2F);
                        entityitem.motionZ = (double) ((float) this.rand.nextGaussian() * f3);
                        world.spawnEntityInWorld(entityitem);
                    }
                }
            }
            world.func_147453_f(x, y, z, block);
        }
        super.breakBlock(world, x, y, z, block, meta);
    }

    @Override
    public TileEntity createNewTileEntity(World world, int meta)
    {
        return new TileEntityPoweredAnvil();
    }

    @Override
    public String getUnlocalizedName()
    {
        return String.format("tile.%s%s", Reference.MOD_ID.toLowerCase() + ":", getUnwrappedUnlocalizedName(super.getUnlocalizedName()));
    }

    protected String getUnwrappedUnlocalizedName(String unlocalizedName)
    {
        return unlocalizedName.substring(unlocalizedName.indexOf(".") + 1);
    }
}

 

 

Some screenshots to hopefully better explain what I'm talking about:

http://puu.sh/eI4Zr/e42a09109e.jpg

http://puu.sh/eI52X/7306221137.jpg

The models on both are facing the same direction, however the bounding box is different depending on which direction I was facing when I placed it.

If you need to see any other classes, I can provide the code for them.

Any help is appreciated!

Thanks!

Link to comment
Share on other sites

This is probably not the most efficient way to do it, but I have managed to get my models to rotate depending on the placed direction.

 

Block code : https://github.com/Sudwood/AdvancedUtilities/blob/master/java/com/sudwood/advancedutilities/blocks/BlockSteamMachine.java#L151-190

 

Render code: https://github.com/Sudwood/AdvancedUtilities/blob/master/java/com/sudwood/advancedutilities/client/renders/RenderSteamSmeltry.java

 

Hope that helps!

Link to comment
Share on other sites

Block

public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack stack)
    {
//This gets the direction the player is facing as an int from 0 to 3
int dir = MathHelper.floor_double((player.rotationYaw * 4F) / 360F + 0.5D) & 3;
//You can use the block metadata to save the direction
world.setBlockMetadataWithNotify(x, y, z, dir, 3);
//Or you can save it in a tile entity if you are using one
createNewTileEntity(world, world.getBlockMetadata(x, y, z));
}

 

Custom Renderer

//Stuff to get the dir int, from the block metadata or the tile or whatever
//Check the dir and apply rotations

        if (dir == 0)
        {
            GL11.glRotatef(-180F, 0.0F, 1.0F, 0.0F);
        }

        if (dir % 2 != 0)
        {
            GL11.glRotatef(dir * (-90F), 0.0F, 1.0F, 0.0F);
        }

        if (dir % 2 == 0)
        {
            GL11.glRotatef(dir * (-180F), 0.0F, 1.0F, 0.0F);
        }

This probably can be optimized a bit more, but this way its readable

This is so commonly asked that it should be stickied somewhere ._.

Link to comment
Share on other sites

Thanks for your reply! I tried this, but I think I either implemented it incorrectly or I need extra code for it to work with my ItemRenderer for the block. My game crashes with the following report:

http://pastebin.com/b1V6yaU8

This is that class:

 

package com.darichey.PandM.item.itemRenderer;

import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.client.IItemRenderer;
import net.minecraftforge.common.util.ForgeDirection;
import org.lwjgl.opengl.GL11;

public class ItemRendererPoweredAnvil implements IItemRenderer
{
    private TileEntity tileEntity;
    private TileEntitySpecialRenderer renderer;

    public ItemRendererPoweredAnvil(TileEntitySpecialRenderer renderer, TileEntity tileEntity)
    {
        this.tileEntity = tileEntity;
        this.renderer = renderer;
    }

    @Override
    public boolean handleRenderType(ItemStack item, ItemRenderType type)
    {
        return true;
    }

    @Override
    public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper)
    {
        return true;
    }

    @Override
    public void renderItem(ItemRenderType type, ItemStack item, Object... data)
    {
        if (type == IItemRenderer.ItemRenderType.ENTITY)
        {
            GL11.glTranslatef(-0.5F, 0.0F, -0.5F);
        }
        this.tileEntity.blockMetadata = 0;
        this.renderer.renderTileEntityAt(this.tileEntity, 0.0D, 0.0D, 0.0D, 0.0F);
    }
}

 

 

 

package com.darichey.PandM.tileEntity.specialRenderer;

import com.darichey.PandM.model.ModelPoweredAnvil;
import com.darichey.PandM.reference.ResourceLocations;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import org.lwjgl.opengl.GL11;

public class RenderPoweredAnvil extends TileEntitySpecialRenderer
{
    private ModelPoweredAnvil modelPoweredAnvil;

    public RenderPoweredAnvil()
    {
        this.modelPoweredAnvil = new ModelPoweredAnvil();
    }

    private void RotateModelBasedOnMeta(World world, int x, int y, int z)
    {
        int meta = world.getBlockMetadata(x, y, z);

        if (meta == 0)
        {
            GL11.glRotatef(-180F, 0.0F, 1.0F, 0.0F);
        }

        if (meta % 2 != 0)
        {
            GL11.glRotatef(meta * (-90F), 0.0F, 1.0F, 0.0F);
        }

        if (meta % 2 == 0)
        {
            GL11.glRotatef(meta * (-180F), 0.0F, 1.0F, 0.0F);
        }
    }

    @Override
    public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float f)
    {
        GL11.glPushMatrix();
        GL11.glTranslatef((float) x + 0.5F, (float) y - 0.5F, (float) z + 0.5F);
        RotateModelBasedOnMeta(tileEntity.getWorldObj(), tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
        this.bindTexture(ResourceLocations.PoweredAnvilModelTexture);
        GL11.glPushMatrix();
        this.modelPoweredAnvil.renderModel(0.0625F);
        GL11.glPopMatrix();
        GL11.glPopMatrix();
    }
}

 

Link to comment
Share on other sites

You are using it wrong.

 

You should override the whole render code in IItemRenderer to render in the inventory, not use the tile entity renderer.

 

Somewheree in your initialization you should have something like this:

ClientRegistry.bindTileEntitySpecialRenderer(MyTileEntity.class, new MyTileEntityRenderer());

 

 

http://www.minecraftforge.net/wiki/Custom_Tile_Entity_Renderer

Link to comment
Share on other sites

Um no, I have both. The TileEntitySpecialRenderer is used to render the block in the world and ItemRender is used to render it in an inventory, right? I've included that second class in my previous reply if you need to look at it.

 

EDIT: What do you mean by overriding the whole render code in IItemRenderer?

Link to comment
Share on other sites

Yeah, my bad, i didn't see the second one.

 

It appears to me that the tileentityrenderer won't work for the inventory you have to do the rendering yerself.

 

You are looking for something along these lines. This is not actual code, you need to adapt it for your personal circumstances.

public void renderItem(IItemRenderer.ItemRenderType type, ItemStack stack, Object... data)
    {
///blahblahblah get the texture get the model etc
case INVENTORY:
                Minecraft.getMinecraft().renderEngine.bindTexture(modelTexture);
            {
                GL11.glPushMatrix();
                GL11.glColor4f(1, 1, 1, 128);

                GL11.glPushMatrix();
                GL11.glTranslatef(-0.5f, 0f, -0.5f);

//This one is important because the model renders upside down because of reasons
                GL11.glPushMatrix();
                GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F);

                GL11.glPushMatrix();
                GL11.glScalef(1.9f, 1.9f, 1.9f);

                model.render(null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.05F, other arguments, whatevers);

                GL11.glPopMatrix();
                GL11.glPopMatrix();
                GL11.glPopMatrix();
                GL11.glPopMatrix();
            }

 

and for entity items

 

  case ENTITY:
                Minecraft.getMinecraft().renderEngine.bindTexture(modelTexture);
            {
                GL11.glPushMatrix();
                GL11.glColor4f(1, 1, 1, 128);

                GL11.glPushMatrix();
                GL11.glTranslatef(0f, 1f, 0f);

                GL11.glPushMatrix();
                GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F);

                GL11.glPushMatrix();
                GL11.glScalef(1.2f, 1.2f, 1.2f);

                model.render(null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.05F, again some extra stuff if you want);

                GL11.glPopMatrix();
                GL11.glPopMatrix();
                GL11.glPopMatrix();
                GL11.glPopMatrix();
            }

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.