Jump to content

[1.3.2 UNSOLVED] Create a flat block that can go between two blocks


Recommended Posts

Posted

Hi, I'm writing a very big mod, and there's just one thing that's eluding me...

I need to be able to place a block flat against another block (similar to how signs work, in vanilla 1.3.2), however, I need the player to be able to place a block up against the first block with the plate sandwiched in between.  I have already created a block that acts like a flat plate and uses metadata to remember which side of the block it was on and it works great!, but.... if I try and place a block up against the plate, it actually puts a full block of space between the two.  Here is a picture of how it currently works:

 

 

 

 

As you can see the dirt block is floating 1 block above the plate block.

But what I want it to do, is lay the dirt directly on top of the plate, almost like it's just sitting on the sand (but the plate is sandwiched in between)

 

Here is the code for just the plate block, because I believe it is all that applies:

 

  Reveal hidden contents

 

 

Now my best idea is to somehow get the game to allow two blocks to overlap, because in order for the plate to get sandwiched in between the blocks, one of the blocks are going to have to share space with the plate, at least, that's how I understand it? :-\

 

If anybody has any ideas about how this could be accomplished that would be great!  I do know this CAN be done because I've seen it done in a mod, however, that mod is A: Closed source, and B: is made by a dev that is NOT open to helping me in the slightest, and so I'm on my own on how to accomplish this magic trick, which is why I'm asking for your help! :-) Thanks dev community, you guys are awesome! :-D

Posted

Pretty sure you're referring to RedPower2 there, with it's nice miniblocks. And, yes, you'd have to get the game to allow two blocks to overlap. I'm not entirely sure if this is possible, as All the RedPower blocks that overlap use the same Block ID, and I'm assuming the way they're able to be placed in the same block space is written into the code of the miniblocks. Unless you want to edit the main Blocks class, I'm not sure it's possible to have your block sit in the same space as vanilla or other mod blocks.

Posted

For normal blocks you'll have to write you TE to detect the right click of the blockItem.If you don't have a TE(tileEntity) you'll need one to store extra info. When you TE detect the item as a block you'll need to save the block's class,or ID. From this you need too pull the block's render,texture,bound info. Then turn your block into a mirror of the block's looks with one side of it having your block's texture.

Posted
  On 9/12/2012 at 4:31 PM, DarkGuardsman said:

For normal blocks you'll have to write you TE to detect the right click of the blockItem.If you don't have a TE(tileEntity) you'll need one to store extra info. When you TE detect the item as a block you'll need to save the block's class,or ID. From this you need too pull the block's render,texture,bound info. Then turn your block into a mirror of the block's looks with one side of it having your block's texture.

 

So if I understand you correctly, what I would wind up doing is, modding the dirt class to have metadata to know if it has a plate on each side of it, and then display that block appropriately showing the plate on that side.  I had thought of that idea, and that would work, however, that leaves one problem.  When the user tries to break the plate, I want them to be able to 1-shot the plate, but leave the dirt.  How would I be able to accomplish that?  Because I want it to show the plate being destroyed and have it drop on the ground, but I want it to leave the dirt.  Also, I'm assuming I would have to mod every single type of block, which is FAR from ideal.  Especially because this would now make it impossible for my mod to play nice with other mods because I can't mod blocks that don't exist right? :-\

 

So I believe that leaves me with 2 problems:

1. I'd have to mod EVERY block in minecraft

2. I don't believe it would look like the plate was being destroyed

 

Please, tell me I'm wrong so that I can get this to work :-P Thanks! :-)

 

Ok, sorry, I didn't read your post close enough the first time, so the way I'm understanding you now that I've read it more closely...

I'd basically be making a block that when you place it, it actually replaces the block you're putting it on, but then looks exactly like it but with one side having my plate on it.

That would almost work but the problem with that would be... if i put my plate on the side of, say, a redstone light, a jukebox, a noteblock etc.... these blocks would lose everything except how they look, and they would be disabled, until my plate "came off".  Not to mention, the same would be true for any modded blocks from any other mod.  That block would fail to work, it would just look like it did, until my plate came off.  Isn't there some way to modify the base block class?  I think that would work, then I could just add metadata to that to make it know if it has a plate on it, but I'm not sure that that can be done in forge because that would require me to mod the block.java class. :-(

Posted
  On 9/12/2012 at 6:44 AM, vroominator said:

Pretty sure you're referring to RedPower2 there, with it's nice miniblocks. And, yes, you'd have to get the game to allow two blocks to overlap. I'm not entirely sure if this is possible, as All the RedPower blocks that overlap use the same Block ID, and I'm assuming the way they're able to be placed in the same block space is written into the code of the miniblocks. Unless you want to edit the main Blocks class, I'm not sure it's possible to have your block sit in the same space as vanilla or other mod blocks.

 

Actually no, although now I might have to take a look at that mod and see how they do things :-)

The mod I'm referring to is actually a VERY awesome mod called UGOcraft, but the dev on that one is not very nice, and the mod is NOT compatible with forge at all :-(

(also, the dev is NOT open to porting it to forge, or providing source, or anything)

 

You know, I'd be ok with editing the main block class, just as long as I can make it act like it should.  for example:

If you hit the plate, the plate will drop off and the block it was attached to will stay and the plate will drop on the ground so the player can pick it back up.  Is this behavior possible? :-\

Any pointers you could give me in that direction would be great! :-D

Posted

You have look in the block halfSlab/doubleSlab?

 

Just changing a little, to check that place block on top, then store the placed block data, remove it and let change your plate to the block.

think must be possible.

Posted
  On 9/12/2012 at 10:40 PM, WiNeTel said:

You have look in the block halfSlab/doubleSlab?

 

Just changing a little, to check that place block on top, then store the placed block data, remove it and let change your plate to the block.

think must be possible.

I have already looked into the halfslabs/doubeslabs and that wont really help me, the way those work is, they store metadata to keep track of if it's single/double, etc... And so with those blocks, it's not really two blocks when you put a second one down, it just reads the metadata, makes the block bigger, and changes the texture.

Sorry, no dice :-(

Posted

Ok, after thinking about this WAY too much, I think there's really only one way to do what it is that I need....

 

I think I need to be able to define a class at runtime, then, if I could do that, here's how I could accomplish what I need....

Step 1: When I place my plate, I don't really place my plate, instead, I get the class of the block it's being put onto

          a: Therefore, I can dynamically generate a new class that extends the class of the block it's being put onto, but it overrides the texture to show a plate on one side and the amount of damage it can take

Step 2: When the block gets hit with a tool/fist, have it only take 1 hit to destroy this modded block, but then when it gets destroyed, I'll have it replaces itself with a non-modded version of itself, and therefore making it seem like the plate was destroyed

 

Does that sound like it would work?

If so... um, could anybody point me to an easy way to implement what I need?

The basic thing I'm currently missing is...

I need to be able to do this:

public class BlockPlatePositive extends UnknownClass{

Where UnknownClass can be any class that I need it to be.

That way, if the plate is put on a piece of dirt, it will extend the dirt and put a plate on it.

Actually I just thought of something, let's assume I could do what I'm saying....

 

I still don't think it would work though, because if I put down one plate that looked like dirt, then I put down another plate on a piece of wool.  The first plate would now be on a piece of wool.... hmmmm.... apparently I'm back to where I started... so does anybody know how I might be able to do what I need? :-\

 

 

 

 

 

Posted

Ok, after again, thinking about how in the world I can get around this, I've decided to settle on making a "mimic" block, that pretends to be other blocks like DarkGuardsman suggested.  I'm not happy about it, but, really it's the best way I can figure to get done what I needed without modding every class of block in minecraft.  :-\

 

I'll mark this one as solved as soon as I manage to get a proof of concept working.  Thanks for all your help! :-D

Posted
  On 9/13/2012 at 12:35 AM, Bandayd said:

  Quote

You have look in the block halfSlab/doubleSlab?

 

Just changing a little, to check that place block on top, then store the placed block data, remove it and let change your plate to the block.

think must be possible.

I have already looked into the halfslabs/doubeslabs and that wont really help me, the way those work is, they store metadata to keep track of if it's single/double, etc... And so with those blocks, it's not really two blocks when you put a second one down, it just reads the metadata, makes the block bigger, and changes the texture.

Sorry, no dice :-(

Sorry my english is not so good, i was thinking in using the idea of the slabs, not the code.

you use BlockContainer, so you place a block over your plate, then store which block is placed over your block in your container, and make that your plate looks like the placedBlock, not replace with it.

When you give signal to your Block change back to plate Block and let flip the stored block up.

Hope you understand my Idea.

you can store so many things in the BlockContainer so must be possible.

only switch the rendering when it´s your placed plate or with placed Block.

 

 

Posted

if you do it right you can get your mimic block to act like every single vanilla block. For example if you right click with a chest you can have your block turn into a chest by having the chest code inside your block&TE. It would be very complex coding but would work. However,i recommend just having blocks without function be able to be mimic-ed. This way you avoid issue and headaches trying to get it too work.

 

Also like WiNeTel said your not replacing as much transforming you block to look like the block being placed. You will use the onBlockActivated method and get the item being clicked with. Then you will remove one item from the player's hand and store the item name,or ID in a variable inside you TileEntity. Also from inside you TileEntity you will reference the item that was placed and steal its render,textures,and effects. This way your block will look like the placed block. 

Also if you do it that way add IF statement to check if the block being placed doesn't have a tileEntity, is a solid block, is a normal MC block, etc to prevent crashes.

Posted

Ok, I think I've gotten a lot further, but I'm still stuck, so here's how far I've gotten...

When I try and place my plate, it first finds the block ID of the block that the plate is going against.  Then it replaces the block with my mimicking/plate block, which also stores the block ID and anything else I could want.  I actually set it up similar to a chest so it's actually holding a single stack of that block.  Then when you hit it, it drops the plate, and places the original plate back (or at least one with the same block ID :-P).

 

The problem I'm having is... in the "getBlockTextureFromSideAndMetadata" for my plate block, I need to be able to read the texture of the block I'm storing/mimicking.  The problem is, the only way I know how to do that is to use "world.getBlockTileEntity(x,y,z)" and it would be smooth sailing from there, however, I can't get the x,y,z of our current block in that function.  Here, I'll just post a few screenshots showing how it currently works.....

 

Before placing the plate block

 

 

 

After placing the plate block

 

 

 

After hitting at the plate block

 

 

 

Here is the code for my TileEntityPlate:

 

  Reveal hidden contents

 

 

Here is my tryPlaceItemIntoWorld from my ItemPlate.java:

 

  Reveal hidden contents

 

 

And lastly, here is the code from my PlateBlock.java that I think I need to use to control my block's texture, so I can make it mimic the blocks I need to:

 

  Reveal hidden contents

 

 

Now I think I'm doing what both of you guys suggested, when the item is placed, it backs up the block it's replacing inside the new block.  When the new block gets destroyed, it just restores it back.  My problem is.... I need to have access to my TileEntity inside my "public int getBlockTextureFromSideAndMetadata(int side, int par2)", that way, if the "side" parameter is the side my plate is on, I'll override that with my plate texture, but on the remaining sides, I'll just use the texture from my stored block, the problem is, I can't access the TiledEntity in getBlockTextureFromSideAndMetadata therefore I can't mimic the block like I need to.  Is there somewhere else I can control my plate block's texture from?  I thought getBlockTextureFromSideAndMetadata was the only place really? :-\ 

 

And remember, my whole problem is really the second picture I showed you (the one labeled "After placing the plate block"), because it's showing the plate texture on ALL sides, rather than displaying dirt on 5 sides, and my plate on 1 side.  (I'm familiar with how to show different textures on different sides, but I need to be able to access the TileEntity information to be able to do that)

 

Thanks in advance for all your help! :-D

Posted

Actually, I've been playing around with metadata and I got it where when you place the block, it backs up the block's metadata, and then when you break the plate, it restores the block's metadata.  What's nice about that is, if you put the plate on a piston, it remembers which way the piston was facing, and if you put a plate on a jack-o-lantern, it remembers what type of pumpkin, and which the jack-o-lantern was facing.

 

So I think I understand the whole metadata thing, which is how your normally determine how to render the block, the problem is, normally metadata is just a single integer.  I need to be able to pass it an int, and 4 textures, and the name of the texture file.  So I think I need a tileentity to do this, but you can't pass a tileentity to the getBlockTextureFromSideAndMetadata function. :-\

 

Any ideas? (sorry if I'm repeating myself a little :-P)

Posted

Nope, I already store it in the tileentity, however, when I try and access the tileentity in the getBlockTextureFromSideAndMetadata function, in order to get the tileentity, I need to use world.getBlockTileEntity(x, y, z);  But.... the function is defined as follows...

public int getBlockTextureFromSideAndMetadata(int side, int metadata)

and there's no way to get the x,y,z of the current block. :-(

 

Unless you know of another way to render the block without using the getBlockTextureFromSideAndMetadata function? That would be GREAT if you could give me a hint? :-D

 

Posted
  On 9/13/2012 at 11:53 AM, DarkGuardsman said:

from inside you TileEntity you will reference the item that was placed and steal its render,textures,and effects. This way your block will look like the placed block. 

Also if you do it that way add IF statement to check if the block being placed doesn't have a tileEntity, is a solid block, is a normal MC block, etc to prevent crashes.

 

I've already re-coded everything to work how I think you suggested (with the block mimicking the block it's replacing).  But I'm having trouble getting the information from the TileEntity, to the actual block texture, is there any way I can set the block texture of my block besides "getBlockTextureFromSideAndMetadata"?  Because I don't think I can access the TileEntity from there? :-\

 

Thanks again for your help with this :)

Posted
  On 9/17/2012 at 3:51 AM, DarkGuardsman said:

You could setup your TileEntity to have its own render class and use packets to send the data from server(or local server) to client. Since the render.class can get TileEntity it can get all the info it needs for rendering the correct sides and such.

 

Any chance you could point me to example code for something like that? :-\

 

Thanks for the quick response! :-D

Posted

here browse my src for steam power i use a render class that contains 3 separate sub models for one block. redpower i believe uses something similar to render all of its diffrent block shapes. Though yours will be more complex so you might want to look at minecraft's block renderer. It has code to bind textures to each side of the block which you need.

Posted
  On 9/17/2012 at 5:24 PM, DarkGuardsman said:

here browse my src for steam power i use a render class that contains 3 separate sub models for one block. redpower i believe uses something similar to render all of its diffrent block shapes. Though yours will be more complex so you might want to look at minecraft's block renderer. It has code to bind textures to each side of the block which you need.

 

Thank you DarkGuardsman, that helped a ton!

 

I did dig around a lot in both WorldRenderer.java and RenderBlocks.java, and the best thing I can come up with would be for forge to add a hook into func_78588_a (on line 3692 of RenderBlocks.java), or wherever it is that I can render a second texture to the same block. :-)

 

Now I'm one step further, I can render a block, and I can even make two separate "models" (rectangles), however, I am only able to apply one texture to both of these rectangles. :-(  I need to be able to specify two separate textures, one for the plate, and one for the "block that I'm mimicking".  I'm starting to wonder if this can be done with forge :-\  I'm going to keep digging though.  I will be sure and update my post if I get anywhere, but at this point, I'm stuck on separating the textures of the two different pieces. 

 

Here is a picture, just showing how I'm able to do two different rectangles.

 

 

 

So the next step would be, I need to be able to apply TWO textures to my "blocks" (I know it's only one block, but it's rendered as two).  One texture will be my plate texture, and the other texture will be the texture of the block I'm mimicking.

 

So I'm off to search for "how to render two textures to one TileEntitySpecialRenderer, OR, how to bindTileEntitySpecialRenderer TWO renderers to ONE class" :-P

 

If anybody has any idea on how to do this, please don't hesitate to pitch in! :-D

I'm starting to think I need forge to add a new hook for binding two textures to one TileEntitySpecialRenderer? :-\

What do you guys think?

 

Also, if it helps any, here is my "TileEntitySpecialRenderer" class that I'm using which give me the awesome picture above... :-P

 

  Reveal hidden contents

 

 

But as you can see, the line "this.bindTextureByName("/myMod/Textures/blockPlate.png");" is only able to apply a single texture to the current TileEntity :-(

Posted

You can use more than one bindTextureByName.

 

Something like this:

 

        this.bindTextureByName("/myMod/Textures/blockPlate.png");
        pM.renderAll();
        this.bindTextureByName("/terrain.png");
        pMM.renderAll();

Posted
  On 9/18/2012 at 10:44 AM, N1xx1 said:

You can use more than one bindTextureByName.

Something like this:

        this.bindTextureByName("/myMod/Textures/blockPlate.png");
        pM.renderAll();
        this.bindTextureByName("/terrain.png");
        pMM.renderAll();

 

I was already using bindTextureByName... buuuut... it didn't occur to me that I could load one texture.... render it, then load another texture! :-P

Thanks N1xx1!  Not only do I think that will work, but now I feel kinda dumb for not thinking of that! :-P lol

 

I'll give that a shot tonight after I get home from work, and I'll report back here how it worked :-)

 

Thanks again!!! :-D

Posted

I´am not sure how work in 1.3.2 but in 1.2.5 was a method i found a try 1 time:

 

in modfile was something with

public boolean renderWorldBlock(RenderBlocks var1, IBlockAccess var2, int var3, int var4, int var5, Block var6, int var7)

    {

. . . .

.getBlockTileEntity

 

. . .

var1.overrideBlockTexture = texture;

 

something like this, sorry not remember verry good, it´s month ago, that was playing around with it

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.