Jump to content

Recommended Posts

Posted

Hello everyone. This is my first post here and I must say, I am a bit nervous as I have seen numerous replies to requests for help end with "Learn Java" and all (not necessarily this forum). Anyway, a quick background, I am currently in school for Software Engineering and have taken 2 Java classes, several other computer related classes (such as machine code), and am currently in a C++ class. So I have a decent background in Java. I have started working on a small mod that would add flowers and other garden type structures to the game in between classes, and I have to say I am completely stuck with flowers. I started off following Shadowfacts tutorials and could get everything placed correctly and even got up to Tile Entity's (a vase), but I had my flower class inheriting Block, and so the flowers behaved as blocks when placed. Over the course of several weeks, I have written and re-written the code more times than I can count, trying to figure out what the heck is going on. I have been following examples from TheGreyGhost, CJMinecraft, MrCrayfish, Pahimar, and more. I have scoured the source code for Botania, BoP, and some other smaller mods that don't seem to be in development anymore, but everyone does things differently, and with versions in between 1.10 and 1.11, it is hard to figure out what code works for what version. Botania and BoP use blockstates for their flowers, and while I have been able to get the code to compile and no errors to print, I cannot get the items to render or even be acknowledged in game. I have since spent some time re-writing again, but now I am a little stuck on the getMetaFromState and getStateFromMeta. Botania's flower class inherits from BlockFlower, and BoP inherits from BlockBush. I have tried both ways, but I seem to prefer BlockBush because I can't quite figure out MC's thinking on the BlockFlower class (like why all of the flowers are considered red except for dandelions and so forth), and when I did use it, I would always get missing texture errors for all of the MC flowers.

 

As for the getMeta and getState methods, all of the examples I have seen have usually been for blocks with more than one state, and so therefore some of the code confuses me. For instance, on CJMinecraft's example:

public IBlockState getStateFromMeta(int meta) {
		ChipTypes type = ChipTypes.values()[(int)(meta / EnumFacing.values().length) % ChipTypes.values().length]; //Gets the type from the meta
		EnumFacing facing = EnumFacing.values()[meta % EnumFacing.values().length]; //Gets the EnumFacing from the meta
		return this.getDefaultState().withProperty(TYPE, type).withProperty(FACING, facing); //Returns the correct state
	}

 

it seems there is some math going on, and I read in other posts that meta data cannot exceed 15, which I assume is what that info is all about.

 

And TheGreyGhost uses bit shifting, which again, I would think would be just because of the extra states equaling more than 15?

 

Anyway, I don't know if my post makes any sense. Again, I have re-written this code so much, I don't even know where I got half of it from anymore. Any help at all would be GREATLY appreciated. I found one tutorial for flowers somewhere, but it was for way to many versions ago.

One other small thing, I keep changing where and how I am registering my blocks and models and so forth, so there could be some stuff missing from there.

 

Here is my BlockModFlower class. (Some of it has a little bit of copied code from TheGreyGhost left in it, because that is where I started drawing a blank on how to convert that to the 3 little flowers I have so far)

package net.cieloangel.gardencraft.blocks.plants.flowers;

import net.cieloangel.gardencraft.blocks.item.IMetaBlockName;
import net.cieloangel.gardencraft.handlers.EnumHandler.EnumFlowerTypes;
import net.minecraft.block.BlockBush;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class BlockModFlower extends BlockBush implements IPlantable, IMetaBlockName {
	
	private static final PropertyEnum TYPE = PropertyEnum.create("type", EnumFlowerTypes.class);
	private static final AxisAlignedBB FLOWER_AABB = new AxisAlignedBB(0.3, 0, 0.3, 0.8, 1, 0.8);
		
		
	public BlockModFlower(String name) {
		
		this.setUnlocalizedName(name);
		this.setDefaultState(blockState.getBaseState().withProperty(TYPE, EnumFlowerTypes.HYDRANGEA));
		//setRegistryName(new ResourceLocation(Reference.MOD_ID, name));
		//GameRegistry.register(this);		
	}
	
	// necessary to define which properties your blocks use
	// will also affect the variants listed in the blockstates model file
	@Override
	protected BlockStateContainer createBlockState()
	{
	  return new BlockStateContainer(this, new IProperty[] {TYPE});
	}
	
	@Override
	  public int damageDropped(IBlockState state)
	  {
	    EnumFlowerTypes flowerTypes = (EnumFlowerTypes)state.getValue(TYPE);
	    return flowerTypes.getMetadata();
	  }
	
	// create a list of the subBlocks available for this block, i.e. one for each colour
	// ignores facings, because the facing is calculated when we place the item.
	//  - used to populate items for the creative inventory
	// - the "metadata" value of the block is set to the colours metadata
	@Override
	@SideOnly(Side.CLIENT)
	public void getSubBlocks(Item itemIn, CreativeTabs tab, NonNullList<ItemStack> list)
	{
	  EnumFlowerTypes[] allFlowers = EnumFlowerTypes.values();
	  for (EnumFlowerTypes flowerTypes : allFlowers) {
	    list.add(new ItemStack(itemIn, 1, flowerTypes.getMetadata()));
	  }
	}
	
	// getStateFromMeta, getMetaFromState are used to interconvert between the block's property values and
	  //   the stored metadata (which must be an integer in the range 0 - 15 inclusive)
	  // The property is encoded as:
	  // - lower two bits = facing direction (i.e. 0, 1, 2, 3)
	  // - upper two bits = colour (i.e. 0, 4, 8, 12)
	  @Override
	  public IBlockState getStateFromMeta(int meta)
	  {
	    //int fMeta = (meta & 0x0c) >> 2; // 0x0c is hexadecimal, in binary 1100 - the upper two bits, corresponding to the colour
	    EnumFlowerTypes fTypes = EnumFlowerTypes.byMetadata(fMeta);
		// EnumFlowerTypes type = EnumFlowerTypes.values()[(int)(meta / EnumFacing.values().length) % EnumFlowerTypes.values().length]; //Gets the type from the meta
	    return this.getDefaultState().withProperty(TYPE, colour);
	  }

	  @Override
	  public int getMetaFromState(IBlockState state)
	  {
	    EnumFlowerTypes flowerTypes = (EnumFlowerTypes)state.getValue(TYPE);

	    int meta = flowerTypes.getMetadata();
	    return state.getValue(EnumFlowerTypes.TYPE);
	  }
	  
	  @Override
	  public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing blockFaceClickedOn, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
	  {
	    EnumFlowerTypes flowerTypes = EnumFlowerTypes.byMetadata(meta);
	    // find the quadrant the player is facing
	    EnumFacing enumfacing = (placer == null) ? EnumFacing.NORTH : EnumFacing.fromAngle(placer.rotationYaw);

	    return this.getDefaultState().withProperty(TYPE, colour);
	  }
}

 

 

And here is my EnumFlowerTypes class (which started off following CJMinecraft mostly, but then I changed it up a bit to match TheGreyGhost)

package net.cieloangel.gardencraft.handlers;

import net.minecraft.util.IStringSerializable;

public class EnumHandler {
	
	public static enum EnumFlowerTypes implements IStringSerializable {
		HYDRANGEA("hydrangea", 0),
		IRIS("iris", 1),
		ROSE("rose", 2);
		
		private String name;
		private final int meta;
		private static final EnumFlowerTypes[] META_LOOKUP = new EnumFlowerTypes[values().length];
		
		// Constructor
		private EnumFlowerTypes(String pName, int pMeta) {
			this.meta = pMeta;
			this.name= pName;
		}
		
		public static EnumFlowerTypes byMetadata(int pMeta) {
			if (pMeta < 0 || pMeta >= META_LOOKUP.length)
			{
				pMeta = 0;
			}
			
			return META_LOOKUP[pMeta];
		}
		
		@Override
		public String getName() {
			return this.name;
		}
		
		@Override
		public String toString() {
			return getName();
		}

		public int getMetadata() {
			return this.meta;
		}
		
		static
	    {
	      for (EnumFlowerTypes flowerTypes : values()) {
	        META_LOOKUP[flowerTypes.getMetadata()] = flowerTypes;
	      }
	    }
	}
	


}

 

 

And quickly, my ModBlocks class:

package net.cieloangel.gardencraft.init;

import net.cieloangel.gardencraft.GardenCraft;
import net.cieloangel.gardencraft.blocks.item.ItemBlockModFlower;
import net.cieloangel.gardencraft.blocks.plants.flowers.BlockHydrangea;
import net.cieloangel.gardencraft.blocks.plants.flowers.BlockModFlower;
import net.cieloangel.gardencraft.handlers.EnumHandler;
import net.cieloangel.gardencraft.util.Reference;
import net.cieloangel.gardencraft.util.Utils;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.common.registry.GameRegistry;

public class ModBlocks {
	
	public static BlockModFlower flower;
	public static BlockHydrangea hydrangea;
	
	public static void init() {
		flower = new BlockModFlower("block_flower");
		hydrangea = new BlockHydrangea("block_hydrangea");
	}
	
	public static void register() {
		registerBlock(flower, new ItemBlockModFlower(flower));
		registerBlock(hydrangea);
	}
	
	public static void registerRenders() {
		for(int i = 0; i < EnumHandler.EnumFlowerTypes.values().length; i++) {
			registerRender(flower, i, "block_flower_" + EnumHandler.EnumFlowerTypes.values()[i].getName());
		}
		registerRender(hydrangea);
	} 
	
	public static void registerBlock(Block block) {
		block.setCreativeTab(GardenCraft.CREATIVE_TAB);
		GameRegistry.register(block);
		GameRegistry.register(new ItemBlock(block).setRegistryName(block.getRegistryName()));
		Utils.getLogger().info("Registered Block: " + block.getUnlocalizedName().substring(5));
	}
	
	public static void registerBlock(Block block, ItemBlock itemBlock) {
		block.setCreativeTab(GardenCraft.CREATIVE_TAB);
		GameRegistry.register(block);
		GameRegistry.register(itemBlock.setRegistryName(block.getRegistryName()));
		Utils.getLogger().info("Registered Block: " + block.getUnlocalizedName().substring(5));
	}
	
	public static void registerRender(Block block) {
		ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(new ResourceLocation(Reference.MOD_ID , block.getUnlocalizedName().substring(5)), "inventory"));
		Utils.getLogger().info("Registered render for block: " + block.getUnlocalizedName().substring(5));
	}

	public static void registerRender (Block block, int meta, String name) {
		ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), meta, new ModelResourceLocation(new ResourceLocation(Reference.MOD_ID , name), "inventory"));
		Utils.getLogger().info("Registered render for block with meta data: " + block.getUnlocalizedName().substring(5));
	}
}

 

 

Thank you so much for any help you can give me. My son has been creating my flower models, and has gone on ahead to create numerous pots and more, but if I can't get a simple flower in the game, then all of his work is for naught.

Posted (edited)

You have four* flower types and eight* facings:

 

That's 32 variants.

 

*Your flower type has 0, 1, and 2 values, which encompasses 2 bits with of address space, which is four variations (one of which is invalid).

Facing has 6 variations which takes 3 bits of address space, or eight variations (two of which are invalid).

Edited by Draco18s

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

Where do you use facing? I see it calculated but not used.

 

 

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted

I am not using facing. That is from the example code I was following. In my original post, I stated I got to that point of replacing things, but then didn't know how to take out the facing part. The only state I want my flowers to have is their type (I suppose if I do it by inheriting BlockBush). Not sure if I should go more along the lines of using colors and/or dyes for types though, like Botania does (and vanilla MC?). If I go that route though, I am even more confused. I also wonder if I should even do block states? Or is it okay to do each flower as its own separate block? I haven't seen any example code going that route though.

Posted

I'm sorry if I didn't make that more clear. That code above has not even been tested yet. It is just what I was about to try. I have been through so many iterations.

 

Just in case it is helpful at all, I have some very early code on my Github (I haven't updated it in a while though as I have not made any real progress). It does not use BlockStates at all though.

 

GardenCraft

Posted
10 hours ago, CieloAngel said:

I am not using facing. That is from the example code I was following. In my original post, I stated I got to that point of replacing things, but then didn't know how to take out the facing part. The only state I want my flowers to have is their type (I suppose if I do it by inheriting BlockBush). Not sure if I should go more along the lines of using colors and/or dyes for types though, like Botania does (and vanilla MC?). If I go that route though, I am even more confused. I also wonder if I should even do block states? Or is it okay to do each flower as its own separate block? I haven't seen any example code going that route though.

You take out the facing by....taking out the facing. There's all of like four references to it, you need to remove all of them.

Take a look at my flowers:

https://github.com/Draco18s/ReasonableRealism/blob/master/src/main/java/com/draco18s/flowers/block/BlockOreFlower1.java#L50

Three properties, one of which is whether or not the block is 2-tall (STALK) and another is for how to display the item (a generic property that can be used by more than one block to display as 2D, not handled by the blockstate JSON file but rather the model registration).

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
14 hours ago, CieloAngel said:

I also wonder if I should even do block states? Or is it okay to do each flower as its own separate block?

Learn properties and blockstates for things like variable textures/colors of of functionally identical blocks. Do not burn up block IDs simply because a basic Forge or Minecraft programming feature needs to be learned.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

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.