Jump to content

[1.8.9] Slabs dropping their item when doubled


blahblahbal

Recommended Posts

I'm having issues getting my slabs to drop two of the item when they're mined while doubled. I've tried everything I can think of, from overriding getItemDropped in the double slab class, to manually forcing (or at least, trying to force) them to drop two.

 

Here is the Double Slab class:  https://github.com/blahblahbal/Blah-s-Minecraft-Mod/blob/Structure-fix/src/main/java/blahblahbal/blahmod/blocks/ModBlockSlabDouble.java

Here is the Half Slab class:  https://github.com/blahblahbal/Blah-s-Minecraft-Mod/blob/Structure-fix/src/main/java/blahblahbal/blahmod/blocks/ModBlockSlabHalf.java

And here is the Slab class:  https://github.com/blahblahbal/Blah-s-Minecraft-Mod/blob/Structure-fix/src/main/java/blahblahbal/blahmod/blocks/ModBlockSlab.java

 

I followed a tutorial from somewhere, I can't remember where I found it however.

 

Side note: the files linked are older versions of the files I'm using now (as they don't have the evidence of what I've tried), but even back then they didn't drop two slab items when mined while doubled.

Link to comment
Share on other sites

I only glanced at your classes, but in my slab class I have overridden this method that you don't seem to be using:

 

@Override
public int quantityDropped(Random random)
{
	return this.isDouble() ? 2 : 1;
}

 

When you say "manually forcing" them to drop two, how did you try doing that?

Link to comment
Share on other sites

I forgot to mention that with the code I have now, they drop absolutely nothing when doubled.

 

1 hour ago, Daeruin said:

When you say "manually forcing" them to drop two, how did you try doing that?

I'm not even sure anymore. I tried so many things I don't remember.

Link to comment
Share on other sites

You can't use the == operator to check whether these strings match. == only checks for object identity, which will always be false when you're comparing a substring to a test string. To do what you're trying to do, you can use String#startsWith.

 

With that said, your entire approach to finding the block type seems incredibly flawed. Whatever tutorial you used.. it was terrible. There's a whole mess of inefficient and unnecessary things going on.

  • This entire method is completely excessive. It's "Stringly typing" and will be very error prone. All you need to do is directly associate the item with the block somehow, like using a single instance method which returns each block's own item.
  • In that method, you use Block.getIdFromBlock as an instance method, but it's static. Any IDE worth its salt should be able to warn you about doing this.
  • ItemStack i = new ItemStack(GameRegistry.findItem("blahmod", blockId.substring(7)), 2);
    In this line you pointlessly create a new ItemStack only to use getItem on it. The result is identical to simply returning the Item parameter you use in the stack constructor, which ignores stack size (presumably that was an attempt to get it to drop two when doubled).

  • In these two methods you are using raw types when you should be using a type parameter.

Edited by Jay Avery
  • Like 1
Link to comment
Share on other sites

I knew there was something not quite right about the tutorial I followed. I just couldn't pin it down.

 

And I've just discovered a small problem with the code I have currently. It makes all blocks that drop an item not drop anything. Ores will still drop xp orbs, however. Trying to fix this right now.

Link to comment
Share on other sites

I can't for the life of me figure out why the ores aren't dropping their item. Nothing that I've changed in the last few days changes anything when I revert the change. Here is the repo:  https://github.com/blahblahbal/Blah-s-Minecraft-Mod/tree/Broken

 

I've tried reverting the slab change. I even tried reverting the leaf change, thinking maybe the @Override on the getItemDropped there somehow took over the ore code.

 

You can tell I'm grasping at straws.

Link to comment
Share on other sites

Your blocks return the content of drop field when the getItemDropped is called. That field is assigned in a constructor. Your blocks are created in createBlocks method, and items are created in createItems method, respectively. Those methods are called in your... proxy for some reason like this:

ModBlocks.createBlocks();
ModItems.createItems();

So every time your block is constructed it gets a reference of item that has not yet been initialized and thereforeafter is null. So your ores always return null when it comes to their drops(apart from that one that drops vanilla clay). Just determine the drop item right in that method, on the fly. Or assign that field later, when the item is not null.

Blocks/items should not even be constructed by you like that. They should either be constructed straight in the field initializer or provided by forge's registred-objects-to-fields-injection(if that is available for you). 

Edited by V0idWa1k3r
Formatting
  • Like 1
Link to comment
Share on other sites

21 minutes ago, blahblahbal said:

I can't for the life of me figure out why the ores aren't dropping their item.

This is nothing to do with your custom slabs/blocks, it will be a problem with your HarvestDropsEvent. Step through in the debugger to see what's going wrong.

 

Edit: I was wrong! And beaten to it.

Edited by Jay Avery
  • Like 1
Link to comment
Share on other sites

Okay, looking further into the slab issue:

Spoiler

 

The getQuantityDropped is habdled for you in the BlockSlab you are extening so the only issue I see is the getItemDropped method. Why are you even doing it the way you are? Currently you go through a lot of trouble to mess up with IDs and that results in nothing being dropped(probably because you get a null or Items.AIR from the GameRegistry).

The way you could do this? Well, let's think. The slab can only have 2 'states' - a half-slab(we do not care if it is upper or lower) and a double slab. So we can do something like:


public Item getItemDropped(IBlockState blockState, java.util.Random random, int unused) 
{
    return this.getHalfSlabReference();
}

What is getHalfSlabReference()? That is up to you to implement. I would store the half slab somewhere in a field and retrieve an item of that, but you could do anything. You could do this in you base slab class:


public abstract Item getHalfSlabReference();

And then in your slab child classes you could implement it like:


public class ModBlockSlabHalf extends ModBlockSlab
{
  ...

    @Override
    public Item getHalfSlabReference()
    {
    	return Item.getItemFromBlock(this);
    }

  ...
}

public class ModBlockSlabDouble extends ModBlockSlab
{
    private final Block singleSlab;
            
    public ModBlockSlabDouble(Material m, Block singleSlabReference)
    {
    	super(m);
        this.singleSlab = singleSlabReference;
    }
            
    @Override
    public Item getHalfSlabReference()
    {
        return Item.getItemFromBlock(this.singleSlab);
    }
            
    ...
}

You would then need to simply pass your single-slab instance to the double-slab constructor whereever you are initializing it. It also gets rid of that useless name field and constructor parameter - why did you need that anyway? 

 

These are just examples, the direct implementation is up to you. 

You might also want to consider implementing all your different slab types as variants. That will make your code cleaner, go from using 32 block ids(that is how much you are using right now) to 3 and make blockstates files more organized. Also would make the code above much easier - in fact you would not even need that single slab block reference anymore!

 

Edited by V0idWa1k3r
Link to comment
Share on other sites

2 hours ago, V0idWa1k3r said:

Your blocks return the content of drop field when the getItemDropped is called. That field is assigned in a constructor. Your blocks are created in createBlocks method, and items are created in createItems method, respectively. Those methods are called in your... proxy for some reason like this:


ModBlocks.createBlocks();
ModItems.createItems();

So every time your block is constructed it gets a reference of item that has not yet been initialized and thereforeafter is null.

 

And here's the #1 reason why I don't put my construction-y stuff in two separate classes (main class or GTFO).

 

That way I can control the creation order of any given block or item that needs to reference a different block or item. Seeds -> Crops (or Crops -> Seeds), ores -> ore drops, etc. And that's when I'm using a generic class that handles the same sorts of actions but slightly different, if I'm doing a one-off or two-off I'll just hard code the getItemDropped method to reference the item field in my main class.

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

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.