Jump to content

Problems with Crops


HenryRichard

Recommended Posts

I'm trying to make a crop, but I'm having trouble with the order I instantiate things in. When I register the seeds before the block, I get a NullPointerException when I use the seeds (I understand why, so you don't need to explain it). But if I register the seeds after the block, the block doesn't drop any seeds! The block drops seeds just fine if I tell it to drop Items.wheat_seeds, and it drops EWOTItems.beetroot too, just none of the seeds that will actually grow the plant.

 

Here's my code:

 

package com.henrich.epicwasteoftime.init;

import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraftforge.fml.common.registry.GameRegistry;

import com.henrich.epicwasteoftime.blocks.CropsBlock;
import com.henrich.epicwasteoftime.items.SeedItem;

public class EWOTPlants {

public static Item beetrootSeeds;
public static Block beetrootCrop;

public static void createPlants () {
	beetrootCrop  = new CropsBlock("crop_beetroot", beetrootSeeds, EWOTItems.beetroot);
	beetrootSeeds = new SeedItem("beetroot_seeds", beetrootCrop, Blocks.farmland);
	GameRegistry.registerBlock(beetrootCrop, "crop_beetroot");
	GameRegistry.registerItem(beetrootSeeds, "beetroot_seeds");
}
}

 

package com.henrich.epicwasteoftime.items;

import com.henrich.epicwasteoftime.EWOTCreativeTabs;

import net.minecraft.block.Block;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemSeeds;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumPlantType;

public class SeedItem extends ItemSeeds
{

private final Block crops;

    public SeedItem(String unlocalizedName, Block crops, Block soil)
    {
        super(crops, soil);
        
        this.crops = crops;
        this.setUnlocalizedName(unlocalizedName);
        this.setCreativeTab(EWOTCreativeTabs.ewotItems);
    }

    @Override
    public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos)
    {
        return EnumPlantType.Crop;
    }
}

 

package com.henrich.epicwasteoftime.blocks;

import java.util.List;
import java.util.Random;

import com.henrich.epicwasteoftime.EWOTCreativeTabs;

import net.minecraft.block.Block;
import net.minecraft.block.BlockBush;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.IGrowable;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;

public class CropsBlock extends BlockCrops {

public final Item seed;
public final Item crop;
public final int minCrop;
public final int maxCrop;

public CropsBlock(String unlocalizedName, Item seed, Item crop, int minCrop, int maxCrop) {
	super();
	this.setUnlocalizedName(unlocalizedName);
	this.seed = seed;
	this.crop = crop;
	this.minCrop = minCrop;
	this.maxCrop = maxCrop;
	this.setDefaultState(getDefaultState().withProperty(AGE, 0));
}

public CropsBlock(String unlocalizedName, Item seed, Item crop) {
	this(unlocalizedName, seed, crop, 1, 1);
}
    
@Override
protected Item getSeed()
    {
        return seed;
    }

@Override
    protected Item getCrop()
    {
        return crop;
    }

@Override
    public net.minecraftforge.common.EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos)
    {
        return net.minecraftforge.common.EnumPlantType.Crop;
    }
}

 

(EWOTPlants.createPlants() is called in the preInit of my CommonProxy)

I'll put something here when I have something of value I need to put at the end of every post. For now it's this mostly pointless text.

Link to comment
Share on other sites

Reference the seed through your main class, not as an object passed to the constructor.

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

It seems kinda dumb that I have to do that; but I didn't make the language, I just (try to learn how to) use it. Thanks, it's working fine now.

 

For anyone who's interested, here's the code I used in CropsBlock:

package com.henrich.epicwasteoftime.blocks;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.henrich.epicwasteoftime.EWOTCreativeTabs;
import com.henrich.epicwasteoftime.init.EWOTItems;
import com.henrich.epicwasteoftime.init.EWOTPlants;

import net.minecraft.block.Block;
import net.minecraft.block.BlockBush;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.IGrowable;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockState;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumPlantType;

public class CropsBlock extends BlockCrops {

public final int minCrop;
public final int maxCrop;

public CropsBlock(String unlocalizedName, int minCrop, int maxCrop) {
	super();
	this.setUnlocalizedName(unlocalizedName);
	this.minCrop = minCrop;
	this.maxCrop = maxCrop;
	this.setDefaultState(getDefaultState().withProperty(AGE, 0));
}
    
@Override
protected Item getSeed()
    {
        return null;
    }

@Override
    protected Item getCrop()
    {
        return null;
    }

@Override
    public EnumPlantType getPlantType(net.minecraft.world.IBlockAccess world, BlockPos pos)
    {
        return EnumPlantType.Crop;
    }

public static class Beetroot extends CropsBlock {

	public Beetroot(String unlocalizedName) {
		super(unlocalizedName, 1, 3);
	}

	@Override
	protected Item getSeed()
    {
        return EWOTPlants.beetrootSeeds;
    }

	@Override
    protected Item getCrop()
    {
        return EWOTItems.beetroot;
    }

	@Override
    public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    {
		List<ItemStack> ret = new ArrayList<ItemStack>();

        Random rand = world instanceof World ? ((World)world).rand : RANDOM;
        
        int age = ((Integer)state.getValue(AGE)).intValue();

        if (age >= 7)
        {
            int k = 3 + fortune;

            for (int i = 0; i < 3 + fortune; ++i)
            {
                if (rand.nextInt(15) <= age)
                {
                    ret.add(new ItemStack(this.getSeed(), 1, 0));
                }
            }
            
            int j = age == 7 ? (this.minCrop >= this.maxCrop ? this.minCrop : this.minCrop + rand.nextInt(this.maxCrop - this.minCrop + 1)) : 0; 
        
            for (int i = 0; i < j; ++i)
            	ret.add(new ItemStack(this.getCrop(), 1, 0));
        }
        return ret;
    }
}
}

 

...And I used this to register it (before I registered the seeds)

beetrootCrop  = new CropsBlock.Beetroot("crop_beetroot");
GameRegistry.registerBlock(beetrootCrop, "crop_beetroot");

I'll put something here when I have something of value I need to put at the end of every post. For now it's this mostly pointless text.

Link to comment
Share on other sites

It seems kinda dumb that I have to do that

It does seem dumb, but there is in fact a very good reason for it:

 

The block constructor is called before the item is initialized, so the 'reference' you pass to your constructor is 'null', which doesn't point to anything. Then later, when your item gets initialized to an actual object, the block has no way to know because the reference that you stored there is still 'null', whereas if you don't store the reference at all but use the actual item reference from your main class, that reference will always be correct when it is needed.

 

Kind of unintuitive, but from the computer's perspective, it is very logical.

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.