Jump to content

Blockstates Property for a Block


Siqhter

Recommended Posts

If you're following my example, the COLOR property is stored in the metadata and as such is already set when Block#getActualState is called. The FACING property is stored in the TileEntity and is the only property that needs to be set in your override of Block#getActualState.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

  • Replies 64
  • Created
  • Last Reply

Top Posters In This Topic

40 minutes ago, Siqhter said:

That's exactly what I thought. I'm assuming my problem is elsewhere then? I wasn't sure if maybe it's in onBlockPlaced or something.

 

What exactly is your current issue? Please post your latest code (or a link to your repository). If it's a model issue, please post your blockstates/model files and your debug.log.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

(Note that you can do it the other way too: store the facing in the metadata and the color in the 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.

Link to comment
Share on other sites

On 12/22/2018 at 11:55 PM, Choonster said:

 

What exactly is your current issue?

On placing the block, it should be 1 of 16 different dye colors. Also the items in the creative menu should each be their own dye color.

 

It's not a model issue, because they render when placed, just not with the correct color (they only render in white, which is the first color in the blockstates colors variants). Also the blocks work fine when applied with dyes (the blocks change to their respective color), so it's probably something in a method that I'm not adding. Below are my Block and TileEntity classes, as well as the blockstate file.

Spoiler

public class BlockCounter extends BlockColored {

    public static final IProperty<EnumFacing> FACING = PropertyDirection.create("facing");

    public static final AxisAlignedBB RED_COUNTER_AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);

    public BlockCounter(final Material material) {
        super(Material.CLAY);
        setCreativeTab(CreativeTabs.DECORATIONS);
        this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH));
    }

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

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

    @Override
    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
        return RED_COUNTER_AABB;
    }

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

    @Override
    public boolean hasTileEntity(final IBlockState state) {
        return true;
    }

    @Nullable
    @Override
    public TileEntity createTileEntity(World world, IBlockState state) {
        return new TileEntityCounter();
    }

    @Nullable
    public TileEntityCounter getTileEntity(final IBlockAccess world, final BlockPos pos) {
        return (TileEntityCounter) world.getTileEntity(pos);
    }

    public EnumFacing getFacing(final IBlockAccess world, final BlockPos pos) {
        final TileEntityCounter tileEntity = getTileEntity(world, pos);
        return tileEntity != null ? tileEntity.getFacing() : EnumFacing.NORTH;
    }

    public void setFacing(final IBlockAccess world, final BlockPos pos, final EnumFacing facing) {
        final TileEntityCounter tileEntity = getTileEntity(world, pos);
        if (tileEntity != null) {
            tileEntity.setFacing(facing);
        }
    }

    @Override
    public void onBlockPlacedBy(final World worldIn, final BlockPos pos, final IBlockState state, final EntityLivingBase placer, final ItemStack stack) {
        setFacing(worldIn, pos, EnumFacing.getDirectionFromEntityLiving(pos, placer).getOpposite());
    }

    @Override
    public IBlockState getActualState(final IBlockState state, final IBlockAccess worldIn, final BlockPos pos) {
        return state.withProperty(FACING, getFacing(worldIn, pos));
    }

    @Override
    public void getSubBlocks(CreativeTabs item, NonNullList<ItemStack> items) {
        for (int i = 0; i < EnumDyeColor.values().length; i++) {
            items.add(new ItemStack(this, 1, i));
        }
    }

    @Override
    public boolean onBlockActivated(final World worldIn, final BlockPos pos, final IBlockState state, final EntityPlayer playerIn, final EnumHand hand, final EnumFacing side, final float hitX, final float hitY, final float hitZ)
    {
        final ItemStack heldItem = playerIn.getHeldItem(hand);

        if (!heldItem.isEmpty()) {
            final Optional<EnumDyeColor> dyeColour = DyeUtils.colorFromStack(heldItem);
            if (dyeColour.isPresent()) {
                final boolean success = recolorBlock(worldIn, pos, side, dyeColour.get());
                if (success && !playerIn.isCreative()) {
                    heldItem.shrink(1);
                }
                return true;
            }
        }
        return false;
       }
    }
Spoiler

public class TileEntityCounter extends TileEntity {

    private EnumFacing facing = EnumFacing.NORTH;

    public EnumFacing getFacing() {
        return facing;
    }

    public void setFacing(final EnumFacing facing) {
        this.facing = facing;
        markDirty();
    }

    @Override
    public void readFromNBT(final NBTTagCompound compound) {
        super.readFromNBT(compound);
        facing = EnumFacing.getFront(compound.getInteger("facing"));
    }

    @Override
    public NBTTagCompound writeToNBT(final NBTTagCompound compound) {
        super.writeToNBT(compound);
        compound.setInteger("facing", facing.getIndex());
        return compound;
    }

    private void notifyBlockUpdate() {
        final IBlockState state = getWorld().getBlockState(getPos());
        getWorld().notifyBlockUpdate(getPos(), state, state, 3);
    }

    @Override
    public void markDirty() {
        super.markDirty();
        notifyBlockUpdate();
    }

    @Override
    public NBTTagCompound getUpdateTag() {
        return writeToNBT(new NBTTagCompound());
    }

    @Nullable
    @Override
    public SPacketUpdateTileEntity getUpdatePacket() {
        return new SPacketUpdateTileEntity(getPos(), 0, getUpdateTag());
    }

    @Override
    public void onDataPacket(final NetworkManager net, final SPacketUpdateTileEntity pkt) {
        readFromNBT(pkt.getNbtCompound());
        notifyBlockUpdate();
    }

    @Override
    public boolean shouldRefresh(final World world, final BlockPos pos, final IBlockState oldState, final IBlockState newSate) {
        return oldState.getBlock() != newSate.getBlock();
    }
}
Spoiler

{
  "forge_marker": 1,
  "defaults": {
    "model": "testmod:counter"
  },
  "variants": {
    "facing": {
      "down": {
        "x": 90
      },
      "up": {
        "x": 270
      },
      "north": {
        "y": 270
      },
      "south": {
        "y": 90
      },
      "east": {
        "y": 0
      },
      "west": {
        "y": 180
      }
    },
    "color": {
      "white": {
        "textures": {
          "top": "blocks/hardened_clay_stained_white"
        }
      },
      "orange": {
        "textures": {
          "top": "blocks/hardened_clay_stained_orange"
        }
      },
      "magenta": {
        "textures": {
          "top": "blocks/hardened_clay_stained_magenta"
        }
      },
      "light_blue": {
        "textures": {
          "top": "blocks/hardened_clay_stained_light_blue"
        }
      },
      "yellow": {
        "textures": {
          "top": "blocks/hardened_clay_stained_yellow"
        }
      },
      "lime": {
        "textures": {
          "top": "blocks/hardened_clay_stained_lime"
        }
      },
      "pink": {
        "textures": {
          "top": "blocks/hardened_clay_stained_pink"
        }
      },
      "gray": {
        "textures": {
          "top": "blocks/hardened_clay_stained_gray"
        }
      },
      "silver": {
        "textures": {
          "top": "blocks/hardened_clay_stained_silver"
        }
      },
      "cyan": {
        "textures": {
          "top": "blocks/hardened_clay_stained_cyan"
        }
      },
      "purple": {
        "textures": {
          "top": "blocks/hardened_clay_stained_purple"
        }
      },
      "blue": {
        "textures": {
          "top": "blocks/hardened_clay_stained_blue"
        }
      },
      "brown": {
        "textures": {
          "top": "blocks/hardened_clay_stained_brown"
        }
      },
      "green": {
        "textures": {
          "top": "blocks/hardened_clay_stained_green"
        }
      },
      "red": {
        "textures": {
          "top": "blocks/hardened_clay_stained_red"
        }
      },
      "black": {
        "textures": {
          "top": "blocks/hardened_clay_stained_black"
        }
      }
    }
  }
}

 

Link to comment
Share on other sites

3 minutes ago, Siqhter said:

On placing the block, it should be 1 of 16 different dye colors. Also the items in the creative menu should each be their own dye color.

 

It's not a model issue, because they render when placed, just not with the correct color (they only render in white, which is the first color in the blockstates colors variants). Also the blocks work fine when applied with dyes (the blocks change to their respective color), so it's probably something in a method that I'm not adding. Below are my Block and TileEntity classes, as well as the blockstate file.

 

This sounds like an issue with the ItemBlock and/or the model registration for the ItemBlock. Please post the code where you instantiate and register the ItemBlock and the code where you register the models for the ItemBlock(or create a repository so that we can see all of your code).

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

1 minute ago, Choonster said:

(or create a repository so that we can see all of your code).

Yeah sorry I've been meaning to do that. Something got messed up with an old mod's repository and I've been trying to fix it. Anyway this is how I register the block and itemblock, but I feel like that would only be an issue with it registering the texture in the inventory. And I should add, it does register the counter model block fine (on placed, and in the inventory), just not the subitems I create with the getSubItems method in my BlockCounter.java. So I'm pretty sure they're registered correctly.

 

BlockInit.java

Spoiler

public static final List<Block> BLOCKS = new ArrayList<Block>();


static Block COUNTER;

public static void init()
{
    COUNTER = new BlockCounter(Material.ROCK).setUnlocalizedName("counter").setRegistryName("counter");

    registerBlock(COUNTER);
}

public static void registerBlock(Block block)
{
    registerBlock(block, new ItemBlock(block));
}

public static void registerBlock(Block block, ItemBlock itemBlock)
{
    BLOCKS.add(block);
    itemBlock.setRegistryName(block.getRegistryName());
    ItemInit.ITEMS.add(itemBlock);
}

RegistryHandler.java

Spoiler

@SubscribeEvent
public static void onBlockRegister(RegistryEvent.Register<Block> event) {
    BlockInit.init();
    event.getRegistry().registerAll(BlockInit.BLOCKS.toArray(new Block[0]));
}

 

Link to comment
Share on other sites

ItemBlock itself isn't suitable for blocks with variants, you need to use a subclass that overrides Item#getMetadata(int) to convert the item metadata to block metadata and calls Item#setHasSubtypes to mark the item as having variants/subtypes. ItemCloth does these and also overrides Item#getTranslationKey(ItemStack) to add the stack's colour as a suffix to the translation key (unlocalised name) so that each colour can have its own translation.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

20 minutes ago, Choonster said:

ItemBlock itself isn't suitable for blocks with variants

Ah, I didn't realize that. So I would need a separate class that sets hasSubtypes to true, overrides getMetadata, and a getUnlocalizedName method? Pretty much everything in the ItemCloth class?

Link to comment
Share on other sites

9 minutes ago, Siqhter said:

Ah, I didn't realize that. So I would need a separate class that sets hasSubtypes to true, overrides getMetadata, and a getUnlocalizedName method? Pretty much everything in the ItemCloth class?

 

Yes, or just use ItemCloth.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Got that working. I feel stupid, I had created a class that I planned to use for any block with subtypes, just forgot to register it in the BlockInit class as a new ItemBlock. It was the same type as ItemCloth that you just told me about. The textures in the inventory are still not registering, should I do the same with with a getSubItems subclass? I'm not sure how similar it is toSubBlocks. Thanks.

Link to comment
Share on other sites

What does the code look like right now?

nvm...

Edited by Animus_Surge

Forge 1.8.9 and below are not supported in the forums anymore. Please upgrade to a later version.

 

My experimental mod: new GitHub page to be created... (Add your favorite TCGs in MC! [WIP])

 

When asking for assistance with modding or making mods, paste the log (located in .minecraft/logs folder for mod users or in the console for mod makers).

Link to comment
Share on other sites

You could also have a different block for each colour, the way shulker boxes do

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

Well I have heard a couple people on this post say something about switching facing and color properties so that I can store color in the TE. Right now color is in the metadata, but if I instead put it in the TE, than how exactly would I call it in the block class instead of using getMetaFromState and getStateFromMeta?

Link to comment
Share on other sites

You would use the block pos you would get to get the tile entity at that pos, check if it’s yours & get the data from it.

However, with the ID limit expansion in 1.13 I would just use seperate blocks (not seperate classes) for each colour the way shulker boxes do it (with an enum). Meta is great for facing, but you shouldnt be using a TE for something like this as you can avoid all the overhead of it by just using multiple blocks

Edited by Cadiboo

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

Yes

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

11 hours ago, Cadiboo said:

However, with the ID limit expansion in 1.13 I would just use seperate blocks (not seperate classes) for each colour the way shulker boxes do it (with an enum). Meta is great for facing, but you shouldnt be using a TE for something like this as you can avoid all the overhead of it by just using multiple blocks

Ok, I will look into it. For now I am curious, just because I'm trying to switch color and facing so I store color in the TE. (I will end up changing it to what has been recommended). But in getActualState I'm trying to call the TE and get the data from it, but I'm not quite sure how.

@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
    super.getActualState(state, worldIn, pos);
    TileEntityCounter tileEntity = (TileEntityCounter) worldIn.getTileEntity(pos);
    EnumDyeColor color = tileEntity.getColor();

    return state.withProperty(COLOR, color);
}
Link to comment
Share on other sites

Quick update, sorry but I'm still stuck on this. My tileentity for color is:

Spoiler

private EnumDyeColor color = EnumDyeColor.RED;

@Override
public void readFromNBT(NBTTagCompound compound) {
    super.readFromNBT(compound);
    this.color = EnumDyeColor.byMetadata(compound.getInteger("color"));
}

@Override
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
    super.writeToNBT(compound);
    compound.setInteger("color", this.color.getMetadata());
    return compound;
}

and getActualState:

Spoiler

@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
    super.getActualState(state, worldIn, pos);
    TileEntityCounter tileEntity = (TileEntityCounter) worldIn.getTileEntity(pos);
    EnumDyeColor color = tileEntity.getColor();

    return state.withProperty(COLOR, color);
}

but this only returns RED, obviously, but I don't understand how to get the data from the block.

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.