Jump to content

TileEntities that are not in World - Can I do this better?


Draco18s

Recommended Posts

So a block I had in 1.7 worked really quite well with utilizing the ISidedInventory interface.

 

The basic premise was that the block would store phantom items, specifically blocks with inventories (when trying to insert to a particular set of slots, I'd check to see if the Item was a block, and if that block implemented IInventory).  Then when any other item was attempted to be put into the primary inventory slots, it was checked to see if it was possible to insert that item into the stored block from a given side (top, bottom, side).  If the item was allowed to be inserted, then my block would allow the insertion to its own inventory.

 

Because of the way the ISidedIventory interface allowed access to inventory slots, it was exceedingly rare for a block to throw a Null Pointer Exception trying to test-insert items (I never once saw it happen, but I wrapped the sole method of failure in a try...catch anyway, just in case).

 

However, now that Capabilities are a thing, that's grown a little more...tenuous.

hasCapability

doesn't pass a blockstate and it would not be unreasonable for a block to differentiate slot validity based on blockstate (for example, my own millstone, which allows insertion on the edge blocks of a 3x3 square, and extraction from the center).  Depending on how any given author decides to implement their has/getCapability methods, they may not handle their TE having a null worldObj.

 

So this code (that I have now) is not fail proof (and one of three or four possible failure points, instead the original one):

 

ItemBlock ib = (ItemBlock)stack.getItem();
IBlockState state = ib.block.getStateFromMeta(ib.getMetadata(stack));
if(ib.block.hasTileEntity(state)) {
TileEntity te = ib.block.createTileEntity(null, state);
return te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
}

 

Is there anything I can do to reduce the chance of error? Or do I need to just accept it, and wrap all three/four spots in a try...catch?

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

There are various ways you can pass a

World

object. For example, you can use

setWorldObj

on the

TileEntity

to set the world.

 

You can get a

World

object from

Minecraft#theWorld

(GUI), or your own

TileEntity

's worldObj. You can also pass in the

World

reference to

Block#createTileEntity

and

TileEntity#hasCapability

to reduce the chance on NPEs.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Link to comment
Share on other sites

There are various ways you can pass a

World

object. For example, you can use

setWorldObj

on the

TileEntity

to set the world.

 

You can get a

World

object from

Minecraft#theWorld

(GUI), or your own

TileEntity

's worldObj. You can also pass in the

World

reference to

Block#createTileEntity

and

TileEntity#hasCapability

to reduce the chance on NPEs.

 

That doesn't actually solve the problem, because if the TE uses that world, it's BlockPos is still 0,0,0 and it itself doesn't exist there, so it will fail to retrieve its own blockstate.

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

There are various ways you can pass a

World

object. For example, you can use

setWorldObj

on the

TileEntity

to set the world.

 

You can get a

World

object from

Minecraft#theWorld

(GUI), or your own

TileEntity

's worldObj. You can also pass in the

World

reference to

Block#createTileEntity

and

TileEntity#hasCapability

to reduce the chance on NPEs.

You could call get placed blockstate or getStateFromMeta. If I understood it correctly you have an ItemStack of a Block you shouold be able to get the block from the Item in the stack, then get the blockstate from those methods.

 

That doesn't actually solve the problem, because if the TE uses that world, it's BlockPos is still 0,0,0 and it itself doesn't exist there, so it will fail to retrieve its own blockstate.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

You could call get placed blockstate or getStateFromMeta. If I understood it correctly you have an ItemStack of a Block you shouold be able to get the block from the Item in the stack, then get the blockstate from those methods.

 

Oh *I* can get the blockstate from an item stack. That's not the problem.

The problem is I want to instantiate the tile entity associated with that state and invoke getCapbability.

 

I have no control over what someone else's getCapbability does...such as doing

worldObj.getBlockState(this.getPos())

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

You could call get placed blockstate or getStateFromMeta. If I understood it correctly you have an ItemStack of a Block you shouold be able to get the block from the Item in the stack, then get the blockstate from those methods.

 

Oh *I* can get the blockstate from an item stack. That's not the problem.

The problem is I want to instantiate the tile entity associated with that state and invoke getCapbability.

 

I have no control over what someone else's getCapbability does...such as doing

worldObj.getBlockState(this.getPos())

Instantiate the TileEntity with Block#createTileEntity(IBlockState) using the method I said above. Which will give you the TileEntity for that specfic BlockState. Correct?

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

Yes.  Which I am.

 

That is also not the problem.  The problem is not the TE creation but invoking getCapability as I've said three times now.

 

getCapability DOES NOT PASS A STATE

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 have an idea, but first I'd like to check that I understand what you're trying to do.

 

You have a block with an inventory. If blocks that have TEs are inserted into that inventory, their TEs are instantiated. If any other item/block is inserted, the inventories of the contained TEs are tested to see if they will accept the item/block, and it is inserted into one of the inventories that will take it.

In 1.9+ there are problems with this approach. Some TEs behave differently depending on the attached blockstate. To get their blockstate they need the World it is in. Since your block never actually places them they have a null World, causing a crash when the TEs try to check their blockstates, as most authors don't expect a null World.

 

Is the above correct?

Link to comment
Share on other sites

Is the above correct?

 

Yes, that is correct.

(player's guide to using it: http://reasonable-realism.wikia.com/wiki/Filtering_Hopper )

 

I could pass a non-null world, but it wouldn't make a difference as the TE's author would (reasonably) assume that the block-at-the-TE's-position was its own block.  I know my own code says "hold on, this isn't me" and allows full access to all slots, same as if a null side was passed (to handle cases like blocks being set to air before the block has a chance to drop all the TE's contents--because that was a problem at one point) but that may not be universally true (as I think aforementioned issue was fixed).

 

The other reason my millstone block does that is that it needs to do that before requesting properties from the blockstate, as to not cause an InvalidPropertyException (or whatever it actually throws when you try to get/set a property that doesn't exist).

 

I suppose that I could use two different TEs for my millstone block (one for the edges that accepts items and one for the center that processes and allows extraction) but I originally coded it to just be the same TE and use the Sided interface nature of things to make the distinction.

 

But again, the point is, "if I managed to do this in this way, someone else might do it too."  And it wasn't until I was coding my filter block that I realized that my getCapability method was insufficiently built to handle possible problems (took me three attempts to properly make sure that what I was doing would work).

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 think the best option is to actually place the Blocks and their TEs in a World. This way the TEs should have everything they could expect to have. The easiest way to do this is to create an inaccessible void world dimension that all filtering hoppers place their phantom blocks in. For performance and resource reasons, each filtering hopper should load and unload the chunk it uses in the dimension as it is loaded and unloaded. You could probably get away with a World that only has a single Chunk if you wanted to, a single Chunk could serve 10,000+ filtering hoppers in the manner I have described.

Link to comment
Share on other sites

That...sounds excessive.

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • There are a few Forge specific mods that I would dearly love to use on my new server, but my friend whom I'm setting up the new server with has expressed concerns that Forge may break or change some core mechanics that might make some farms/contraptions/Redstone devices that work in Vanilla or Fabric not work in Forge. They have sent me a few links to some Twitch minecrafters that have commented that "Forge changes Redstone behavior" or "Certain farms are broken on Forge but not Vanilla", however, I've never experienced this myself, and haven't found or seen any actual examples of this being the case.  I've scoured Youtube and can't find anyone saying "This contraption doesn't work on Forge Ole777".  I spoke to a mod developer who mentioned that there may have been small bugs where this might have been the case in extremely complicated builds, but he is not of aware of this still being an issue or concern. And he mentioned that any instance where something might break would definitely be considered a bug and should be reported and it would/could be fixed, as Forge explicitly doesn't intend to change any vanilla behavior. It just seems much more rumor than fact that Forge might break things, and just wanted to see if anyone had any input. Thank you!
    • This is a costume block whit the shape of a zombie is not a full block its flamable when ignited  the flames just burn on top or by a aside  that dint seems right  // ########## ########## ########## ########## @Override public int getFlammability(BlockState state, BlockGetter level, BlockPos pos, Direction direction) {     return 300;//((FireBlock)Blocks.FIRE).getBurnOdds(state); //300 } it just seems like check to know if a fire block could despawn mi block    ########### i want mi block to look more like this      what could i use  i was thinking on something like onNeigbourgChange() check for nearby fire or lava blocks   then using the falling block entity spawn a fire block in the same position than mi dead body block  thanks for your readings             
    • LINK DAFTAR AKUN GACOR VVIP BAMBUHOKI88 LINK LOGIN RESMI BAMBUHOKI88 LINK KLAIM BONUS 100% BAMBUHOKI88 Bambuhoki88 Merupakan kumpulan pilihan link situs rekomendasi slot bank bri di tahun 2024 di rekomendasi oleh para slotter deposit bank bri di indonesia dengan tingkat peluang kemenangan tinggi untuk setiap bet mudah menang maxwin.
    • LINK DAFTAR AKUN GACOR VVIP BAMBUHOKI88 LINK LOGIN RESMI BAMBUHOKI88   LINK KLAIM BONUS 100% BAMBUHOKI88 BAMBUHOKI88 Merupakan Pilihan Terbaik Situs Slot Bank Bca Yang Gampang Menang Maxwin Dan Jackpot Besar Dengan Deposit Bank Bca Yang Online 24Jam Auto Dapat Wd Gede.  
    • So I've been trying to make an mob that can have multiple textures, and the mob has the Witch model, and I can put a texture on it but I don't know how to make it spawn with a random texture. I tried searching through mobs that have multiple textures like the fox, rabbit, and stuff but I wasn't able to find out how to do it and I kept getting errors when i tried compiling: error: method createKey in class net.minecraft.network.datasync.EntityDataManager cannot be applied to given types; private static final DataParameter<Integer> ALCHEMIST_TYPE = EntityDataManager.createKey(AlchemistEntity.class, DataSerializers.VARINT); ^ required: java.lang.Class<? extends net.minecraft.entity.Entity>,net.minecraft.network.datasync.IDataSerializer<T> found: java.lang.Class<net.newblocks.entity.AlchemistEntity>,net.minecraft.network.datasync.IDataSerializer<java.lang.Integer> reason: cannot infer type-variable(s) T (argument mismatch; java.lang.Class<net.newblocks.entity.AlchemistEntity> cannot be converted to java.lang.Class<? extends net.minecraft.entity.Entity>) 1 error   And sorry there isn't much info, this was the only error that appears when I tried to copy the same thing from one of those mobs with multiple textures (plus imports). I already tried searching on the site and didn't find much. I can provide more info if needed
  • Topics

×
×
  • Create New...

Important Information

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