Jump to content

[1.9.4] [SOLVED] Singular item class, change block placed upon registry


swordkorn

Recommended Posts

Hi guys. I'm currently trying to update my mod to the latest version and as a result, I've been trying to optimise how I do things all over the place.

 

What I want to achieve is a singular item "parent" class that holds all the necessary logic for the item, but have the block it places on item use be configurable so I can manually define that.

 

Anybody have any suggestions as to how I could go about this?

 

Thanks!

Link to comment
Share on other sites

The static keyword is almost certainly not what you want.

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

*Facepalm*

 

What if you do this in your preInit:

 

myStoneItem = new ItemClass(Blocks.stone);
myWoodItem = new ItemClass(Blocks.planks);

 

What do you expect to happen?

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

I'm not a total idiot you know... you don't have to talk to me like one... just saying.

 

Yes you're saying that because I'm calling on a block in the preInit yet to be created in the init it will not associate and return null.

 

My point simply at this stage is to find a way to associate a particular block type with my item so I can manually define which block the item will place during the declaration instead of using 50 item classes to define the particular block in question.

Link to comment
Share on other sites

Draco's point is that a static field will be shared between all instances of the class, so all instances would use the

Block

passed to the last instance created. This is basic Java that you should already know before creating a mod.

 

Use an instance field instead.

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

Hopefully I've understood what my IDE told me and you guys...

 

    Block block;

    public MysticalCropSeed(String regName, Block block) {
        super();
        this.regName = regName;
        this.block = block;
        setCreativeTab(MysticalCrops.cropsTab);
    }

Link to comment
Share on other sites

That will work, but you should make the field private (so it can't be accessed outside of the class) and final (so it can't be modified after it's set in the constructor).

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

I actually found an easier way to achieve what I was trying to do, so I thought I'd post it here in case people were interested:

 

My item registry class:

public class CropItems {
    public static Item[] MCSeeds;
    public static Item[] MCDrops;
    public static HashMap<MysticalCropBlock, Item> seedsMap = new HashMap<MysticalCropBlock, Item>();
    public static HashMap<MysticalCropBlock, Item> harvestedItemMap = new HashMap<MysticalCropBlock, Item>();

    public static Item redstoneSeedItem = new MysticalCropSeed(CropBlocks.redstoneCrop, Blocks.FARMLAND, "redstoneCropSeed");

    public static Item regItem(Item item, String regName) {
        item.setRegistryName(regName);
        item.setUnlocalizedName(regName);

        return GameRegistry.register(item);
    }

    public static void loadItemRegistry() {
        regItem(redstoneSeedItem, "redstoneCropSeed");

        MCSeeds = new Item[] {redstoneSeedItem};
        MCDrops = new Item[] {Items.REDSTONE};
    }
}

 

My crop block class that binds the seeds and eventually any drops to the block in question:

    protected Item getSeeds() {
        final Item seeds = CropItems.seedsMap.get(this);

        if(seeds == null) {
            FMLLog.bigWarning("No seeds detected!");
            return new Item();
        }
        return seeds;
    }

    @Override
    public ItemStack getItem(World world, BlockPos pos, IBlockState state) {
        return new ItemStack(getSeeds());
    }

    @Override
    public boolean canGrow(World worl, BlockPos pos, IBlockState state, boolean isClient) {
        return !isHarvestReady(state);
    }

    protected Item getHarvestedItem() {
        final Item harvestedItem = CropItems.harvestedItemMap.get(this);
        if(harvestedItem == null) {
            FMLLog.bigWarning("No drop registered!");
            return new Item();
        }
        return harvestedItem;
    }

 

There's more to it of course, but I wanted to share this in case people were struggling like I was.

 

Thanks everyone!

Link to comment
Share on other sites

...What are you doing there?  No really, I'm confused.  Why are you doing that?

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

So I confused even the great Draco18s! I'll add that as an Achievement Unlocked! lol!!!

 

OK so I admit the code may seem a bit broken up and in all honesty, I had missed a few steps but I've since gone back and tweaked a few things.

 

My item class now simply looks like this:

public class MysticalCropSeed extends ItemSeeds{

    public MysticalCropSeed(Block crops, Block soil, String regName) {
        super(crops, soil);
        setUnlocalizedName(regName);
        setCreativeTab(MysticalCrops.cropsTab);
    }
}

So everything seed related is handled by the underlying seed logic. A hint I got from reading your example mod on that winter wheat or something...

 

Block side, it now associates with the seed by checking the seedsMap as defined in CropItems:

public class CropItems {
    public static HashMap<MysticalCropBlock, Item> seedsMap = new HashMap<MysticalCropBlock, Item>();
    public static HashMap<MysticalCropBlock, Item> harvestedItemMap = new HashMap<MysticalCropBlock, Item>();

    public static Item redstoneCropSeed;

    public static Item regItem(Item item, String regName) {
        item.setRegistryName(regName);
        item.setUnlocalizedName(regName);

        return GameRegistry.register(item);
    }

    public static Item regSeeds(String regName, Block crop) {
        Item item = new MysticalCropSeed(crop, Blocks.FARMLAND, regName);

        seedsMap.put((MysticalCropBlock) crop, item);

        return regItem(item, regName);
    }

    public static Item regDrops(Item item, Block crop) {
        return harvestedItemMap.put((MysticalCropBlock) crop, item);
    }

    public static void loadItemRegistry() {
        regSeeds("redstoneCropSeed", CropBlocks.redstoneCrop);
        regDrops(Items.REDSTONE, CropBlocks.redstoneCrop);

        MCSeeds = new Item[] {redstoneCropSeed};
        MCDrops = new Item[] {Items.REDSTONE};
    }

The methods regSeeds and regDrops add the relevant drop item to the relevant HashMap. By doing this, the seed required to plant the block and the required drops upon breaking can be defined in the block class instead as a general constructor.

 

I implement it like this:

public class MysticalCropBlock extends BlockCrops implements IGrowable, IPlantable {

    protected Item getSeeds() {
        final Item seeds = CropItems.seedsMap.get(this);

        if(seeds == null) {
            FMLLog.bigWarning("No seeds detected!");
            return new Item();
        }
        return seeds;
    }

    @Override
    public ItemStack getItem(World world, BlockPos pos, IBlockState state) {
        return new ItemStack(getSeeds());
    }

    protected Item getHarvestedItem() {
        final Item harvestedItem = CropItems.harvestedItemMap.get(this);
        if(harvestedItem == null) {
            FMLLog.bigWarning("No drop registered!");
            return new Item();
        }
        return harvestedItem;
    }

    @Override
    public Item getItemDropped(IBlockState state, Random rnd, int fortune) {
        if(!isHarvestReady(state)) {
            return getSeeds();
        }else{
            return getHarvestedItem();
        }
    }

    @Override
    public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand,
                                    ItemStack stack, EnumFacing side, float hitX, float hitY, float hitZ) {
        if(isHarvestReady(state)) {
            if(world.isRemote) {
                return true;
            }

            final ItemStack savedStack = new ItemStack(getHarvestedItem());

            world.setBlockState(pos, state.withProperty(AGE, 0), 7);
            final EntityItem entItem = new EntityItem(world, player.posX, player.posY - 1D, player.posZ, savedStack);
            world.spawnEntityInWorld(entItem);
            entItem.onCollideWithPlayer(player);
            return true;
        }
        return false;
    }

So in effect, the item doesn't define the block, the block defines the item. By linking it through the getSeeds and getHarvestedItem methods, they can be bound in the item registry.

 

Hope that makes a bit more sense.

 

And yes; I purposely only included the methods relevant. That's why the block class may seem empty but trust me, it's all there and works great.

Link to comment
Share on other sites

No, the question I'm asking is:

 

Why do you have a HashMap at all?

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 works and I have no complaints about it.

 

How else did you expect me to map the seeds and drops to the relevant block using only one class for each?

 

Anyway, this is all fixed now and works just as I had intended. With the added benefit that I achieved my goal of halving the file size of the mod since 1.8.9 and now.

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.