Jump to content

Recommended Posts

Posted

I have a custom block and when I place it down the neighboring blocks became transparent.

 

That's why I put

 

    @Override
    public boolean doesSideBlockRendering(final IBlockState state, final IBlockAccess world, final BlockPos pos, final EnumFacing face)
    {
        return false;
    }

 

 

Into my block code, but now the surface of the neighboring blocks renders black.

 

What did I do wrong?

Posted

Show all of your block's code.

 

Likely (because you didn't explicitly state whether or not it is), your block's volume is less than 1³, because you can "see" the sides of the block facing this block.

If so, your block is not a full block, and you should thus override

isFullBlock(IBlockState)

.

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Posted

Yeah, true, my block is not a full block.

 

The code of my block:

 

The abstract:

 

package com.minecolonies.blocks;

import com.minecolonies.colony.Colony;
import com.minecolonies.colony.ColonyManager;
import com.minecolonies.colony.buildings.AbstractBuilding;
import com.minecolonies.creativetab.ModCreativeTabs;
import com.minecolonies.lib.Constants;
import com.minecolonies.tileentities.TileEntityColonyBuilding;
import net.minecraft.block.Block;
import net.minecraft.block.BlockHorizontal;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Abstract class for all minecolonies blocks.
* <p>
* The method {@link AbstractBlockHut#getName()} is abstract
* <p>
* All AbstractBlockHut[something] should extend this class
*/
public abstract class AbstractBlockHut extends Block implements ITileEntityProvider
{
    public static final  PropertyDirection FACING     = BlockHorizontal.FACING;
    private static final float             HARDNESS   = 10F;
    private static final float             RESISTANCE = Float.POSITIVE_INFINITY;
    protected int workingRange;

    /**
     * Constructor for a block using the minecolonies mod.
     * <p>
     * Registers the block, sets the creative tab, as well as the resistance and the hardness.
     */
    public AbstractBlockHut()
    {
        super(Material.WOOD);
        initBlock();
    }

    private void initBlock()
    {
        setRegistryName(getName());
        setUnlocalizedName(Constants.MOD_ID.toLowerCase() + "." + getName());
        setCreativeTab(ModCreativeTabs.MINECOLONIES);
        //Blast resistance for creepers etc. makes them explosion proof
        setResistance(RESISTANCE);
        //Hardness of 10 takes a long time to mine to not loose progress
        setHardness(HARDNESS);
        this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH));
        GameRegistry.register(this);
        GameRegistry.register((new ItemBlock(this)).setRegistryName(this.getRegistryName()));
    }

    /**
     * Method to return the name of the block.
     *
     * @return Name of the block.
     */
    public abstract String getName();

    @NotNull
    @Override
    public TileEntity createNewTileEntity(World world, int meta)
    {
        //Creates a tile entity for our building
        return new TileEntityColonyBuilding();
    }

    @Override
    public int getMetaFromState(@NotNull IBlockState state)
    {
        return state.getValue(FACING).getIndex();
    }


    // =======================================================================
    // ======================= Rendering & IBlockState =======================
    // =======================================================================

    // render as a solid block, we don't want transparency here
    @NotNull
    @Override
    @SideOnly(Side.CLIENT)
    public BlockRenderLayer getBlockLayer()
    {
        return BlockRenderLayer.SOLID;
    }

    @Override
    public boolean onBlockActivated(
                                     World worldIn,
                                     BlockPos pos,
                                     IBlockState state,
                                     EntityPlayer playerIn,
                                     EnumHand hand,
                                     @Nullable ItemStack heldItem,
                                     EnumFacing side,
                                     float hitX,
                                     float hitY,
                                     float hitZ)
    {
        /*
        If the world is client, open the gui of the building
         */
        if (worldIn.isRemote)
        {
            @Nullable final AbstractBuilding.View building = ColonyManager.getBuildingView(pos);

            if (building != null)
            {
                building.openGui();
            }
        }
        return true;
    }

    @Override
    public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, @Nullable EntityLivingBase placer)
    {
        @NotNull final EnumFacing enumFacing = (placer == null) ? EnumFacing.NORTH : EnumFacing.fromAngle(placer.rotationYaw);
        return this.getDefaultState().withProperty(FACING, enumFacing);
    }

    //We unfortunately have to implement these two, to rotate our blocks in the structures.
    @Override
    public IBlockState withRotation(final IBlockState state, final Rotation rot)
    {
        return state.withProperty(FACING, rot.rotate(state.getValue(FACING)));
    }

    @Override
    public IBlockState withMirror(final IBlockState state, final Mirror mirrorIn)
    {
        return state.withRotation(mirrorIn.toRotation((EnumFacing)state.getValue(FACING)));
    }

    /**
     * Event-Handler for placement of this block.
     * <p>
     * Override for custom logic.
     *
     * @param worldIn the word we are in
     * @param pos     the position where the block was placed
     * @param state   the state the placed block is in
     * @param placer  the player placing the block
     * @param stack   the itemstack from where the block was placed
     * @see Block#onBlockPlacedBy(World, BlockPos, IBlockState, EntityLivingBase, ItemStack)
     */
    @Override
    public void onBlockPlacedBy(@NotNull World worldIn, @NotNull BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
    {
        super.onBlockPlacedBy(worldIn, pos, state, placer, stack);

        /*
        Only work on server side
        */
        if (worldIn.isRemote)
        {
            return;
        }

        final TileEntity tileEntity = worldIn.getTileEntity(pos);
        if (placer instanceof EntityPlayer && tileEntity instanceof TileEntityColonyBuilding)
        {
            @NotNull final TileEntityColonyBuilding hut = (TileEntityColonyBuilding) tileEntity;
            @Nullable final Colony colony = ColonyManager.getColony(worldIn, hut.getPosition());

            if (colony != null)
            {
                colony.addNewBuilding(hut);
            }
        }
    }

    @NotNull
    @Override
    protected BlockStateContainer createBlockState()
    {
        return new BlockStateContainer(this, FACING);
    }

    // =======================================================================
    // ===================== END of Rendering & Meta-Data ====================
    // =======================================================================
}

 

 

the block itself:

 

package com.minecolonies.blocks;

import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import org.jetbrains.annotations.NotNull;

/**
* Hut for the fisherman.
* No different from {@link AbstractBlockHut}
*/
public class BlockHutFisherman extends AbstractBlockHut
{
    protected BlockHutFisherman()
    {
        //No different from Abstract parent
        super();
    }

    @NotNull
    @Override
    public String getName()
    {
        return "blockHutFisherman";
    }

    @Override
    public boolean isFullBlock(final IBlockState state)
    {
        return false;
    }

    @Override
    public boolean doesSideBlockRendering(final IBlockState state, final IBlockAccess world, final BlockPos pos, final EnumFacing face)
    {
        return false;
    }
}

 

 

Even with "isFullBlock" -> false

 

I have the problems with the black rendered surfaces.

Posted

You need to also override isOpaqueCube(IBlockState state). Also, do not implement ITileEntityProvider, Block itself has methods for that (hasTileEntity() and createTileEntity()).

Posted

Using:

 

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

    @Override
    public boolean isFullBlock(final IBlockState state)
    {
        return false;
    }

    @Override
    public boolean doesSideBlockRendering(final IBlockState state, final IBlockAccess world, final BlockPos pos, final EnumFacing face)
    {
        return false;
    }

 

Seems to have resolved it.

 

I unfortunately, cannot change the tileEntityProvider thing because we would lose the stored tileEntities and that means that all our users would have to start over.

Posted

They won't lose there TileEntities because the blocks own method call the ones from ITileEntityProvider if the block implements that interface and hasTileEntity() automatically returns true in that case.

Posted

That doesn't make any sense because the NBT data is stored in a map with the classname or the registration name of the tile entity as key.

Posted

Hi XFactHD

 

Also, do not implement ITileEntityProvider, Block itself has methods for that (hasTileEntity() and createTileEntity()).

Why do  you say that?  I think you're probably right that it's not necessary to implement ITileEntityProvider, but if Ray already has implemented it, why should (s)he change it?

 

-TGG

 

Posted

Oh. I know why him removing ITileEntityProvider "erases his data."

He doesn't have @Override marked and/or isn't dealing with the IDE error involved when he removes the interface.  So he's not overriding the correct method, so when the game runs it treats the block as not having a TE.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Why do  you say that?  I think you're probably right that it's not necessary to implement ITileEntityProvider, but if Ray already has implemented it, why should (s)he change it?
Because
ITileEntityProvider

is an outdated API. It will not give you the

IBlockState

, instead it will give you the raw metadata value, which is not very useful.

So  in other words, at some point in the future if Raycomms needs to know the IBlockState when creating his TileEntity, or if the ITileEntityProvider is removed, he will need to change it.  To me that is a good reason to change it later, not now.  Enough vanilla and forge stuff breaks at every upgrade that personally I don't think trying to get ahead of the curve is the best use of a developer's time.

 

Having said that, I also agree that switching from ITileEntityProvider and overriding the two necessary methods in Block shouldn't break existing saves.  @Draco I think you're probably right and @Override would show the problem

@Override
    public TileEntity createTileEntity(World world, IBlockState state)

@Override
    public boolean hasTileEntity(IBlockState state)

 

-TGG

 

 

Posted

Oh. I know why him removing ITileEntityProvider "erases his data."

He doesn't have @Override marked and/or isn't dealing with the IDE error involved when he removes the interface.  So he's not overriding the correct method, so when the game runs it treats the block as not having a TE.

I just got bitten by this while getting rid of ITileEntityProvider too, and I suspect I know what happened to Raycoms.

 

I implemented hasTileEntity() and getTileEntity(), using @Override of course, and restarted my dev world, only to find my item routers no longer had tile entities at all.  A bit of debugging showed that hasTileEntity() wasn't even being called.

 

A little more investigation with my IDE shows that there are two hasTileEntity() methods:

hasTileEntity()

, and

hasTileEntity(IBlockState state)

.  Of course, I'd overridden the no-args one, which is wrong.  You need to override

 hasTileEntity(IBlockState state)

.  Getting it wrong is a subtle error, since your IDE won't flag this as an error at all.  The code is syntactically fine, just incorrect.

 

Once I fixed that, my item routers had tile entities again, but since the world had been restarted using the wrong code, the game - as you rightly noted - treated the blocks as having no tile entity, and removed any saved data for those from the world.  After fixing the code, loading up another dev world that I previously made worked fine - all TE data was intact.

 

Moral of this story: override

hasTileEntity(IBlockState state)

, not

hasTileEntity()

.  That no-args version appears to be only called by TileEntityHopper, and just calls

hasTileEntity(getDefaultState())

.  Yucky.

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.