Someone asked how to make more than one block on the same ID. It is possible, it uses one class that stores a variable. this variable will work similar to damage for wool and etc.
this tutorial is not made to show you how to make a block or how to install or use MCP.
To start make a new class the extends Block
package net.minecraft.src;
public class Blocktester extends Block{
protected Blocktester(int i, Material material) {
if(Block.blocksList[i]!=null){
Block.blocksList[i]=null;
}
super(i, material);
blockIndexInTexture = -1;//We will not ever use the texture index
}
}
Now that we have a block class we can start adding the content into it.
package net.minecraft.src;
public class BlockTester extends Block{
protected BlockTester(int i, Material material) {
if(Block.blocksList[i]!=null){
Block.blocksList[i]=null;
}
super(i, material);
blockIndexInTexture = -1;//We will not ever use the texture index
blocktype = 1;//set it to 1 by default
}
public BlockTester setBlockType(int i){
blocktype = i;
return this;
}
public int blocktype;
}
What we did, we made a method that sets a variable called blocktype to a number that is input. We will use this number later to choose different actions, consider blocktype to be an alternate block id.
To add our first method to show how to use the blocktype variable we will get a texture based off of the blocktype.
package net.minecraft.src;
public class BlockTester extends Block{
protected BlockTester(int i, Material material) {
if(Block.blocksList[i]!=null){
Block.blocksList[i]=null;
}
super(i, material);
blockIndexInTexture = -1;//We will not ever use the texture index
blocktype = 1;//set it to 1 by default
}
public BlockTester setBlockType(int i){
blocktype = i;
return this;
}
public int getBlockTextureFromSide(int i){
//Based on the blocktype, return a different texture index
//You decide what number is equal to what block
//for example:
//
// 0 = WetStone
// 1 = DeadGrass
// 2 = GraniteOre
//
//We are ignoring the side variable for now, but you can use it
//like you normally would.
if(blocktype==0){
return 110;
}
if(blocktype==1){
return 111;
}
if(blocktype==2){
return 112;
}
return blocktype;
}
public int blocktype;
}
If the blocktype is set to 0, then return a number that is the texture index you want for that block. It is helpful to first decide what number you want each block to be, adding annotations can help you remember.
Now that we have the idea behind it done we can make more content. Almost everything that is different about the blocks has to be overridden in this class and using if statements.
package net.minecraft.src;
public class BlockTester extends Block{
protected BlockTester(int i, Material material) {
if(Block.blocksList[i]!=null){
Block.blocksList[i]=null;
}
super(i, material);
blockIndexInTexture = -1;//We will not ever use the texture index
blocktype = 1;//set it to 1 by default
}
public BlockTester setBlockType(int i){
blocktype = i;
return this;
}
public int getBlockTextureFromSide(int i){
//Based on the blocktype, return a different texture index
//You decide what number is equal to what block
//for example:
//
// 0 = WetStone
// 1 = DeadGrass
// 2 = GraniteOre
//
//We are ignoring the side variable for now, but you can use it
//like you normally would.
if(blocktype==0){
return 110;
}
if(blocktype==1){
return 111;
}
if(blocktype==2){
return 112;
}
return blocktype;
}
public int idDropped(int i, Random r){
if(blocktype==2){
return 375;
}
return blockID;
}
public int blocktype;
}
now using the same method of if statements we returned different Item IDs, Items can be done the same way. the hard part is integrating a method to get the blocktype so when the block drops it drops the right id, there are several ways you can do it, but I will not go over them. Examples are you can find the method that calls "idDropped()" and have it call another method if the block class is instanceof BlockTest. of you could return a negative or non existent number and have a check for that before dropping, then after making the block item set it's blocktype with setBlocktype(int i);
The next feature is how much of the item to drop, for example in this, we want wetstone to only drop one, and same with dead grass, however let's make granite ore drop randomly 1, 2 or 3 pieces.
package net.minecraft.src;
import java.util.Random;
public class BlockTester extends Block{
protected BlockTester(int i, Material material) {
if(Block.blocksList[i]!=null){
Block.blocksList[i]=null;
}
super(i, material);
blockIndexInTexture = -1;//We will not ever use the texture index
}
public BlockTester setBlockType(int i){
blocktype = i;
return this;
}
public int getBlockTextureFromSide(int i){
//Based on the blocktype, return a different texture index
//You decide what number is equal to what block
//for example:
//
// 0 = WetStone
// 1 = DeadGrass
// 2 = GraniteOre
//
//We are ignoring the side variable for now, but you can use it
//like you normally would.
if(blocktype==0){
return 110;
}
if(blocktype==1){
return 111;
}
if(blocktype==2){
return 112;
}
return blocktype;
}
public int idDropped(int i, Random r){
if(blocktype==0){
return 110;
}
if(blocktype==1){
return 111;
}
if(blocktype==2){
return 375;
}
return 1;
}
public int amountDropped(int i, Random r){
if(blocktype==2){
return r.nextInt(3)+1;//drop randomly 1, 2 or 3
}
return 1;
}
public int blocktype;
}
That's better... you can keep adding more methods using the same idea. Just one more idea and then I'll leave creativity up to you.
package net.minecraft.src;
import java.util.Random;
public class BlockTester extends Block{
protected BlockTester(int i, Material material) {
if(Block.blocksList[i]!=null){
Block.blocksList[i]=null;
}
super(i, material);
blockIndexInTexture = -1;//We will not ever use the texture index
}
public BlockTester setBlockType(int i){
blocktype = i;
return this;
}
public int getBlockTextureFromSide(int i){
//Based on the blocktype, return a different texture index
//You decide what number is equal to what block
//for example:
//
// 0 = WetStone
// 1 = DeadGrass
// 2 = GraniteOre
//
//We are ignoring the side variable for now, but you can use it
//like you normally would.
if(blocktype==0){
return 110;
}
if(blocktype==1){
return 111;
}
if(blocktype==2){
return 112;
}
return blocktype;
}
public int idDropped(int i, Random r){
if(blocktype==0){
return 110;
}
if(blocktype==1){
return 111;
}
if(blocktype==2){
return 375;
}
return 1;
}
public int amountDropped(int i, Random r){
if(blocktype==2){
return r.nextInt(3)+1;//drop randomly 1, 2 or 3
}
return 1;
}
public String getBlockName(){
if(blocktype==0){
return "wetstone";
}
if(blocktype==1){
return "deadgrass";
}
if(blocktype==2){
return "graniteore";
}
return "";
}
public int blocktype;
}
there, now all our blocks have different names.
Now you can define them.
public static final BlockTester wetStone = new BlockTester(blah1, blah2).setBlockType(0);
public static final BlockTester deadGrass = new BlockTester(blah3, blah4).setBlockType(1);
public static final BlockTester graniteOre = new BlockTester(blah5, blah6).setBlockType(2);
If you have any problems please tell me.
This method had been tested and does work.
This method DOES work for modloader! Just register do like so:
private BlockTester base = new BlockTester(blah1, blah2);
ModLoader.registerBlock(base);
public static final BlockTester wetStone = base.setBlockType(0);
public static final BlockTester deadGrass = base.setBlockType(1);
public static final BlockTester graniteOre = base.setBlockType(2);
Wow. There goes most item/block conflicts. With this method, each entire mod could just use one single ID for their entire set of blocks or items... With this, there literally is an unlimited number of blockIDs (sorta). Kudos!
Wow. There goes most item/block conflicts. With this method, each entire mod could just use one single ID for their entire set of blocks or items... With this, there literally is an unlimited number of blockIDs (sorta). Kudos!
You can thank the person who requested this tutorial. Dusldin(Lordmau5)
== MCP v4.4 ==
> Recompiling client...
== ERRORS FOUND ==
warning: [options] bootstrap class path not set in conjunction with -source 1.6
src\minecraft\net\minecraft\src\mod_CompressedBlocksIronOre.java:5: error: incom
patible types
private IronOre base = new IronOre(231, 0).setBlockName("IronOreComp").setHardne
ss(3F).setResistance(250F);
^
required: IronOre
found: Block
src\minecraft\net\minecraft\src\mod_CompressedBlocksIronOre.java:7: error: non-s
tatic variable base cannot be referenced from a static context
public static final IronOre oreBox = base.setBlockType(0);
^
src\minecraft\net\minecraft\src\mod_CompressedBlocksIronOre.java:8: error: non-s
tatic variable base cannot be referenced from a static context
public static final IronOre oreCompressed = base.setBlockType(1);
^
src\minecraft\net\minecraft\src\mod_CompressedBlocksIronOre.java:9: error: non-s
tatic variable base cannot be referenced from a static context
public static final IronOre oreCompressed2 = base.setBlockType(2);
^
src\minecraft\net\minecraft\src\mod_CompressedBlocksIronOre.java:10: error: non-
static variable base cannot be referenced from a static context
public static final IronOre oreCompressed3 = base.setBlockType(3);
^
src\minecraft\net\minecraft\src\mod_CompressedBlocksIronOre.java:11: error: non-
static variable base cannot be referenced from a static context
public static final IronOre oreCompressed4 = base.setBlockType(4);
^
src\minecraft\net\minecraft\src\mod_CompressedBlocksIronOre.java:12: error: non-
static variable base cannot be referenced from a static context
public static final IronOre oreCompressed5 = base.setBlockType(5);
^
src\minecraft\net\minecraft\src\mod_CompressedBlocksIronOre.java:21: error: cann
ot find symbol
ModLoader.registerBlock(base);
^
symbol: method registerBlock(IronOre)
location: class ModLoader
8 errors
1 warning
==================
> Done in 12.43 seconds
No there is not. Each block can only have a maximum of 15 damage values, for example 35-15, And there is still the block limit as minecraft runs out of sprites, look at my ColourCraft mod, that causes minecraft to crash because of the limit.
The sprite limit can be overcame actually. A couple of nice mods (InfiniteSprites, Extended Blocks, MC Forge) actually do this in 1.7.3.
No there is not. Each block can only have a maximum of 15 damage values, for example 35-15, And there is still the block limit as minecraft runs out of sprites, look at my ColourCraft mod, that causes minecraft to crash because of the limit.
As seeing this is not damage, you can set the blocktype to anywhere between 0 to the limit if the type Integer, meaning a lot mooe than 15. the sprite images you will probably run out of, that's why you'd use mod loader and addOverride().
How would you provide the textures for the blocks then?
Give me an example? :smile.gif:
Do you read? YOU USE MODLOADER!!!!! YOU ADD AN OVERRIDE!!!!! Almost every modded on here know that mod loader allows you to override an ID to use a specified image. Each image could be its own file. wow...
I didn't test it, but this method won't work imo. The reason is, that you will have to store your blocktype for each block in your map. You will also have to load and store this data somehow. If it would be as easy as that, Notch wouldn't be using damage values.
And this:
private BlockTester base = new BlockTester(blah1, blah2);
ModLoader.registerBlock(base);
public static final BlockTester wetStone = base.setBlockType(0);
public static final BlockTester deadGrass = base.setBlockType(1);
public static final BlockTester graniteOre = base.setBlockType(2);
will create three references to the same object with blocktype=2. The final keyword wont prevent it from changing.
I would like to see your test-implementation.
Actually about your last part, as I am not assigning it to the base but instead calling a method on the base that returns a different object based on the input each object is independent from each other. If you want to you can make it set the block type and then return a new instance of it:
public BlockTester setBlockType(int i){
blocktype = i;
BlockType ret = new BlockTester(blockID, blockMaterial);
ret.blocktype = i;
return ret;
}
And you'd actually get the same results.
It saves the full block class, so when loaded the blocktype variable would still be there when casted to the class. This works almost the same exact way as damage.
I will remake the test run, When I make a tutorial I make a test for it to see if it actually works, usually I discard it afterwards, so I'll remake it and post it when I'm done. Right now I'm working on a large scale project though so I'd be doing it more in my free time, which is not much. But here is what I tested:
Spawning Blocks With The World Generators
Crafting Recipes
Saving/Loading
Breaking Block (What Does It Drop - And How Much)
The Texture
All 5 worked, they did not work the first 2 tests I did, so I fixed the code twice before it worked and then made the tutorial with the working code.
dude... I threw that out there as an example of what to do to fix the "problem" you suggested. If that causes an error come up with a solution, Oh wait, that's easy, MAKE A NEW CONSTRUCTOR that does NOT call the super class, just sets the proper variables. There are ways. My point is I tested this, I am working on it again and you will see, but it does work and you've basically introduced an argument into a thread I posted to help one person.
As seeing BlockTester extends Block it has all the same variables Block has, it's just instead of calling the super class to set them set them in your own blocks constructor leaving out the thing about the blocksArray[]
The String s in the constructor is just so you don't get an error saying it's already defined. the string can be "" for All I care.
Wow... IT DOES WORK, test it if you think it doesn't, you'll not crash, The only purpose of calling the super class is to set the variables in it, if you set those variables in your own class you avoid any need to call the super class while still making a new instance of BlockTester, as seeing you still keep the original constructor as well "the class does not have the needed constructor" will not cause any issues. You say it does not work, one difference, you even said you didn't test it, I did. Make a test before you make a post claiming that it wouldn't work, test it and you'll find out that it does not crash.
This tutorial is not to explain the basics, I gave an EXAMPLE of a class you can make, you can make it much much different. I explain the basics of how to make multiple blocks with one ID, what they use in it's place does not matter, they can replace the method setBlockType to not even return anything, or they can do what you suggested and store different variations of the class in a HashMap or Set<> or List<> or even an array.
Tutorials should not be a "Here I'm going to supply you with the full code so you can just copy and paste into your project" thread, instead it should require the person to read and learn what the tutorial is showing them and use it in their own way. My point is you are flaming this thread, and you even said you haven't even tested it.
I'll have the example up within 1 week, granted I can find more than 10 minutes of free time per day.
One example of how to make it completely ignore the blocksList[] is before calling the super class's constructor you set
Block.blocksList[id]=null;
then it completely overrides it. Like I already explained, there are ways.
Dude, the thing Is I have schol, and two extra classes after. After that I have 6 hours worth of stuff and I get some time to check the forums which I use to make these posts, however I get less that ten minutes a day sometimes that I can actually code. I currently have a project going as well that I'm working on, while it wouldn't be hard to import the src files into Eclipse. to tell you the truth I have not even had enough time to even start on it, that's why it's not done yet. also MCP is being a ***** and is giving me a ton of OpenGL errors, which I can fix but then it gives me errors that deal with classes I haven't even edited.
And people will not be wasting time to read this, if this is the type of thing they want to mod they will find this useful, it is only the basics of it, this alone will not work 100% but it shows how it works so that other people can make their own versions of it. This is a base, other people make the full thing off of it.
When I make the demo you want it using ModLoader? because ModLoader always gives me compilation errors even if I don't do anything.
public static final BlockTester wetStone = new BlockTester(blah1, blah2).setBlockType(0);
public static final BlockTester deadGrass = new BlockTester(blah3, blah4).setBlockType(1);
public static final BlockTester graniteOre = new BlockTester(blah5, blah6).setBlockType(2);
For this to work, would these declarations have to be set in the "BlockTester" class that was created rather than the "Block" class it extends from?
I tried messing around with this a little and kept running into the problem that it still says I can't use the same Block ID:
Exception in thread "main" java.lang.ExceptionInInitializerError
...
Caused by: java.lang.IllegalArgumentException: Slot <###> is already occupied by ...
That would be where "blah1" and "blah3" (since "blah2" and "blah4" would normally be either texture(s) or material(s)) are the Same Block ID Number.
Such as:
public static final BlockTester wetStone = new BlockTester( 111, 50 ).setBlockType( 0 );
public static final BlockTester deadGrass = new BlockTester( 111, 51 ).setBlockType( 1 );
That's because you havn't been reading the thread, it was brought to my attention that small (semi-easy to fix glitch, I'll update the code in a sec, it's only one more line in the constructor.
Someone asked how to make more than one block on the same ID. It is possible, it uses one class that stores a variable. this variable will work similar to damage for wool and etc.
this tutorial is not made to show you how to make a block or how to install or use MCP.
To start make a new class the extends Block
Now that we have a block class we can start adding the content into it.
What we did, we made a method that sets a variable called blocktype to a number that is input. We will use this number later to choose different actions, consider blocktype to be an alternate block id.
To add our first method to show how to use the blocktype variable we will get a texture based off of the blocktype.
take a closer look:
If the blocktype is set to 0, then return a number that is the texture index you want for that block. It is helpful to first decide what number you want each block to be, adding annotations can help you remember.
Now that we have the idea behind it done we can make more content. Almost everything that is different about the blocks has to be overridden in this class and using if statements.
now using the same method of if statements we returned different Item IDs, Items can be done the same way. the hard part is integrating a method to get the blocktype so when the block drops it drops the right id, there are several ways you can do it, but I will not go over them. Examples are you can find the method that calls "idDropped()" and have it call another method if the block class is instanceof BlockTest. of you could return a negative or non existent number and have a check for that before dropping, then after making the block item set it's blocktype with setBlocktype(int i);
The next feature is how much of the item to drop, for example in this, we want wetstone to only drop one, and same with dead grass, however let's make granite ore drop randomly 1, 2 or 3 pieces.
That's better... you can keep adding more methods using the same idea. Just one more idea and then I'll leave creativity up to you.
there, now all our blocks have different names.
Now you can define them.
If you have any problems please tell me.
This method had been tested and does work.
This method DOES work for modloader! Just register do like so:
Check out my Minecraft Modding Tutorials!
Donate to help me buy people Minecraft accounts!
You can thank the person who requested this tutorial. Dusldin(Lordmau5)
5 of 5 Diamonds ;D
one for type of block (ore, ground, instantmineable, etc)
and then one for the blocks
Ores (0) : (0)Emerald - (1)Ruby - (2)Athenium - (3)Dethenium
Ground (1) : (0)Leaf Pile - (1)Wet Sand - (2)Mulch
Instant Mineable (2) : (0)Fancy Tile - (1)Glow Dust
Those are only examples, but imagine what you can do.
Glad you like it. It was a fairly fast tutorial to make surprisingly to me.
What I should put in
In the "blah1" and "blah2" for example? ^^
//EDIT: aaah this is like
^^
Edit, try to cast your block to IronOre or change the return type of setBlockType() to IronOre instead of Block.
The sprite limit can be overcame actually. A couple of nice mods (InfiniteSprites, Extended Blocks, MC Forge) actually do this in 1.7.3.
As seeing this is not damage, you can set the blocktype to anywhere between 0 to the limit if the type Integer, meaning a lot mooe than 15. the sprite images you will probably run out of, that's why you'd use mod loader and addOverride().
Yes, and this doesn't even use damage, it uses something similar to damage, sort of like a custom damage system.
Do you read? YOU USE MODLOADER!!!!! YOU ADD AN OVERRIDE!!!!! Almost every modded on here know that mod loader allows you to override an ID to use a specified image. Each image could be its own file. wow...
Actually about your last part, as I am not assigning it to the base but instead calling a method on the base that returns a different object based on the input each object is independent from each other. If you want to you can make it set the block type and then return a new instance of it:
And you'd actually get the same results.
It saves the full block class, so when loaded the blocktype variable would still be there when casted to the class. This works almost the same exact way as damage.
I will remake the test run, When I make a tutorial I make a test for it to see if it actually works, usually I discard it afterwards, so I'll remake it and post it when I'm done. Right now I'm working on a large scale project though so I'd be doing it more in my free time, which is not much. But here is what I tested:
Spawning Blocks With The World Generators
Crafting Recipes
Saving/Loading
Breaking Block (What Does It Drop - And How Much)
The Texture
All 5 worked, they did not work the first 2 tests I did, so I fixed the code twice before it worked and then made the tutorial with the working code.
As seeing BlockTester extends Block it has all the same variables Block has, it's just instead of calling the super class to set them set them in your own blocks constructor leaving out the thing about the blocksArray[]
The String s in the constructor is just so you don't get an error saying it's already defined. the string can be "" for All I care.
This tutorial is not to explain the basics, I gave an EXAMPLE of a class you can make, you can make it much much different. I explain the basics of how to make multiple blocks with one ID, what they use in it's place does not matter, they can replace the method setBlockType to not even return anything, or they can do what you suggested and store different variations of the class in a HashMap or Set<> or List<> or even an array.
Tutorials should not be a "Here I'm going to supply you with the full code so you can just copy and paste into your project" thread, instead it should require the person to read and learn what the tutorial is showing them and use it in their own way. My point is you are flaming this thread, and you even said you haven't even tested it.
I'll have the example up within 1 week, granted I can find more than 10 minutes of free time per day.
One example of how to make it completely ignore the blocksList[] is before calling the super class's constructor you set
then it completely overrides it. Like I already explained, there are ways.
And people will not be wasting time to read this, if this is the type of thing they want to mod they will find this useful, it is only the basics of it, this alone will not work 100% but it shows how it works so that other people can make their own versions of it. This is a base, other people make the full thing off of it.
When I make the demo you want it using ModLoader? because ModLoader always gives me compilation errors even if I don't do anything.
For this to work, would these declarations have to be set in the "BlockTester" class that was created rather than the "Block" class it extends from?
I tried messing around with this a little and kept running into the problem that it still says I can't use the same Block ID:
That would be where "blah1" and "blah3" (since "blah2" and "blah4" would normally be either texture(s) or material(s)) are the Same Block ID Number.
Such as:
~ iiiHuman ~