Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

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.

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.

  • Author

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.

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.

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...

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.