First time posting anything, however I thought I could post some tutorials of mods I have been working on using the mod creator pack.
*Note It's mostly just code I am no good at the whole artistic stuff so I just reuse textures*
Let's Start with potions (they have endless possibilities and are extremely awesome)!
first let's create a base class to use, we will call it "EntityPotion.java". This will be an abstract class, more of a way to design future potions.
Inside this class we have:
package net.minecraft.src;
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode
import java.util.Random;
public abstract class EntityPotion extends Entity
{
public World world;
public EntityPlayer entityplayer;
public long timeOfEffect = 0L;
public EntityPotion(World world, EntityPlayer entityplayer){
super(world);
this.world = world;
this.entityplayer = entityplayer;
}
public EntityPotion(World world){
super(world);
this.world = world;
}
public abstract boolean applyEffects();
public abstract boolean removeEffects();
public abstract void func_370_e_();
public void readEntityFromNBT(NBTTagCompound nbttagcompound){
}
public void writeEntityToNBT(NBTTagCompound nbttagcompound){
}
}
We make this an entity (extends entity) because this will be the effect the potion has and not the actual item itself.
Global Variables:
World world: the world variable, this will allow us access to the world class and many functions
EntityPlayer: This is the player, this will allow us to access variables and methods relating to the player
timeOfEffect: This will be how long the effect should last
Methods:
We have to constructors, which should be fairly straightforward.
public entity(World world)
should be used when we don't care about the player itself.
We have 3 abstract methods (These have to be implemented in any potion that extends this class)
applyEffect(): This is where the effect of the potion will be applied
removeEffect(): This is where any effects from the potions should be removed when the duration of the potion has been exceeded
func_370_e_(): A little arbitrary in terms of what it does, however this is where any updates are taken place. Every tick of the game this method will be called (we are overloading from the entity class), if you were to look at other entities you would notice that stuff to deal with motion would belong in this method. Thus we will use this to time the effect of the potion as well update anything in special cases.
The last two methods in this class are overloaded from the entity class as they are abstract, however I am not entirely sure as to how they work (all I know is it's for saving and I don't know how to deal with it if anyone knows let me know!)
Next Thread Will be how to create the invincibility potion
* I should have noted I'd love to see any tutorials from anyone else on coding so please post or make threads. *
Invincibility ah how nice would it be to not take any damage from those dang creepers, well let me tell you It's nice!
We start off by making a new item class let's call it "ItemInvincibilityPotion.java"
package net.minecraft.src;
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode
public class ItemInvincibilityPotion extends Item
{
public ItemInvincibilityPotion(int i)
{
super(i);
maxStackSize = 64;
}
So here we have the constructor for our ItemInvincibilityPotion which extends item, this takes 1 variable (in this case it's the ID of the item don't get this mistaken with the ID for the texture!)
We will also set the maximum stack size for this item to be 64 (meaning you can have 64 potions per pile).
public ItemStack func_193_a(ItemStack itemstack, World world, EntityPlayer entityplayer)
Here we have func_193_a, this is the function the game calls when the user right clicks an item (not to be confused with onItemUse which will use an item if the player uses the item on a BLOCK)
Here we check to see if we are on first playing on single player (don't want to deal with multiplayer atm) and second if the effects of the invincibilityPotion are currently active. This variable is static to the Entity class for this potion (I probably should have added this as a variable in the base class for all potions instead).
If the potion isn't active and we are on single player then we can create the entity for the invincibility potion and add it to our current world. Next we decrease the itemstack by 1 (so if we had 64 potions we will now have 63). Then we return the current itemstack.
And that's it for the item! Now to add the item so we can use it we look at the item class
Around line 197 we will add the following line:
public static Item invincibilityPotion = (new ItemInvincibilityPotion(423)).func_4022_a(77);
This tells the game that there is an item called invincibilityPotion with the item ID of 423. func_4022_a(int i) is where we define the texture location, in this case I just used the bucket of milk texture which is 77. (call me lazy but w/e it's easy)
Now we need a way to craft it so go into CraftManager.java and around line 148 we will add the following lines:
addRecipe(new ItemStack(Item.invincibilityPotion, 1), new Object[] {
"#", Character.valueOf('#'), Block.obsidian
});
This adds a recipe into the game, which will create a new itemStack of our invincibilityPotion (it will make 1 of them)
The next line is the look of the recipes so in total in can be ("xxx", "xxx", "xxx") which is the slots in the crafting workbench where 'x' is the item. In this case I am only using 1 item (for simplicity sake just to test) which is denoted as "#". Now for every character of '#" should be an Obsidian block in the recipe. Thus 1 block of obsidian = 1 invincibility potion.
However if I were to do something like " X ", " # ", " X " where 'X' is obsidian and the '#' is a glass block then in order to get 1 invincibilitypotion you would need to have 1 obsidian block at the top middle slot of the workbench, a glass block in the middle slot of the middle row, and another obsidian block at the bottom middle slot.
Now on to the most important part of all of this the entity class which will be named "EntityInvincibilityPotion.java"
package net.minecraft.src;
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode
import java.util.Random;
import java.io.PrintStream;
public class EntityInvincibilityPotion extends EntityPotion
{
public static boolean isActive = false;
private int currentHealth = 0;
public EntityInvincibilityPotion(World world, EntityPlayer entityplayer){
super(world, entityplayer);
applyEffects();
}
Note the this class extends the EntityPotion class we created earlier.
Right in the constructor we call the constructor in EntityPotion to define the world and entityplayer values for our class. As well right off the bat we apply any effects this potion should have. We also create 2 variables the static variable to see if this entity is currently in use (isActive) and we create a currentHealth variable for use only with this class.
The applyEffects method sets the timeOfEffect to 80 long (I'm exactly sure how much time it is, it might be 80 ticks however it's about 15 seconds or so). it also sets the isActive variable to true (as the potion is currently active) and we keep track of the players current health as of the player ingesting the potion.
So here we print to the console "you feel mortal..." this is for testing purposes and you will see it in the console when you run "test_game.bat". As well we set the isActive variable to false and we call a function called func_395_F(). What does this odd function do exactly? Well it essentially destroys the entity from the world thus doing a bit of garbage clean up.
This is our update function, which is used by all entities. For every time this is called we decrement timeOfEffect, and if it's less than or equal to zero we call the removeEffects function as described above.
If the time isn't up yet we check two things:
First if the players health is less than the health we measured before if it is then we set the players health back to what we had before. So if we had 18 health and we fell down a giant cave and got hurt for 3 damage we would technically be at 15 health. However our currentHealth variable is set to 18 thus when we fall we will have 18 health again.
However if the player decides to eat some food, we want to gain the health the food gives us. So all we do is set the currentHealth variable to the players new health. So for example we have 18 health eat a golden apple and the players health some how goes to 20 (even though gold is poisonous but w/e I'm no scientist). The next time we get hurt within the effect of the potion the players health will stay at 20.
And That's it! Run the game and be invincible, next up SonicSpeedPotion!!!!! (well just SpeedPotion)
Okay The Speed Potion. From here on I will assume you know how to create the item in the item class, the recipe in the craftingmanager class and the Item[name]Potion class (as it's basically the same as above except you replace the entity class name with the new entity. Thus I'm only going to talk about the entity[name]Potion classes because that's where the guts of the potions lie.
create the class "EntitySpeedPotion.java"
package net.minecraft.src;
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode
import java.util.Random;
import java.io.PrintStream;
public class EntitySpeedPotion extends EntityPotion
{
public EntitySpeedPotion(World world, EntityPlayer entityplayer){
super(world, entityplayer);
applyEffects();
}
public boolean applyEffects(){
timeOfEffect = 256L;
isActive = true;
return true;
}
So same as the invincibility potion, we call the super class constructor to define the entity of the player and the world variables. We then call applyEffects() which sets the duration of the potion and the isActive variable. For this potion the duration is 256L which is quite a bit longer than the invincibility potion lasting somewhere between 30 seconds to a minute. (it might make sense that it would last 25.6 seconds actually now that I think about it, perhaps I'll test this later).
Back to our update function, so again we decrement the timeOfEffect variable, if it's less than or equal to 0 we call removeEffects.
If the potion is still active however we check to see if the player is on the ground (this potion will only work on the ground, and will not work in the air at all. So you will find that you run stupid fast but when you jump you slow right down until you hit the ground. The reason for this is because the motionX and motionZ variables act differently in the air as in it's accumulative where as on the ground the motionX and motionZ variables seem to get reset on every tick. Not saying there isn't a way to make you run off a cliff super fast and keep that momentum, but I didn't feel like doing that) Okay anyway if the player does happen to be on the ground we multiply the players momentum (motionX and motionZ) by 1.5F which to me seems to be more than double the players actual speed. Now to make them stay the same in the air, I suggest something like take the current motionX and motionZ and keep them constant while the player is in the air so you could add perhaps:
This would keep the motionX and motionZ constant when in the air. Now this also gives me a chance to discuss the functions fun_397_g_() and func_359_G. These functions return true if the player is in water (func_397_g_) or in lava (func_359_G). So if you wanted to make a faster swimming potion, you would check to see if func_397_g_ is true and multiple motionX and motionZ by let's say 1.5, this would let the player swim faster. (However again I believe this accumulative so the player will just keep getting faster and faster, you could check to see if the motion is starting to go negative or positive and just set the motion to something like 1.5 or 2.) Anyway that's all for this class, the next one I'm going to post is my favorite the low gravity potion
Last one of these for a bit until I come up with some new ideas. I hope you guys like these, and I know I exclusively use MCP. However hopefully soon they will add support to patch the original minecraft game so I have high hopes that this tool kit will be used by a lot of people. Thus some source code to help people along the way is always good :smile.gif:
Okay so create the class "EntityLowGravityPotion.java"
package net.minecraft.src;
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode
import java.util.Random;
import java.io.PrintStream;
public class EntityLowGravityPotion extends EntityPotion
{
public static boolean isActive = false;
public EntityLowGravityPotion(World world, EntityPlayer entityplayer){
super(world, entityplayer);
applyEffects();
}
public boolean applyEffects(){
timeOfEffect = 300L;
isActive = true;
return true;
}
public boolean removeEffects(){
System.out.println("You Feel Heavier Now...");
isActive = false;
func_395_F();
return false;
}
So we notice that the first three methods are almost exactly the same as the speed potions first three methods.
This little piece of code basically says that if the duration of the potion is up and we are either on the ground, in the water or in the lava (as with this you can't really swim instead you just bounce around the water) then we can terminate the effect and return gravity back to normal for the player.
entityplayer.motionY += 0.075;
This is the line that gives us that low gravity feeling. If we continuously add 0.075 to the motionY the player will be fighting against gravity so to speak. This value is not enough to make the player go floating away, but just enough to make you jump very high and fall very slowly!
entityplayer.fallDistance = 0.0F;
}
Now every update while we are in the air we want to first set the fallDistance to 0.0. This is important because when we hit the ground it will ensure that we are not going to take fall damage.
And that's it for the low gravity potion. nothing too exciting but my god is it fun!
<.<; I believe this is a [Tutorial] thread, sir. Much like the other's I've seen here...
They're ALL great stuff, though, including this one! There's always a lot of information here for people who like to use MCP. I've never gotten around to playing with MCP, myself... But if I ever do, I know where to look first :3
Keep up the good work, and great first post (or, set of posts, rather), Quatham!
*** Minecraft Coder Pack Version 2.11 ***
MCP 2.11 running in C:\MCP
Compiling Minecraft
sources\minecraft\net\minecraft\src\Iteminvinsibilitypotion.java:21: reached end of file while parsing
}
Compiling Minecraft Server
=== MCP 2.11 recompile script finished ===
press any key to continue . . .
Hello - this is a very good tutorial. However, when I tried to recompile, I got an error. It said:
***Minecraft Coder Pack Version***
MCP 2.12 Running in C:\mcp212
Compiling Minecraft
sources\minecraft\net\src\ItemInvincibilityPotion.java:23: reached end
of file while parsing
}
^
1 error
***Minecraft_Server.jar not found, skipping
===MCP 2.12 recompile script finished ===
Press any key to continue...
Other than that, everything worked. Thanks heaps!
~ SC
EDIT: I got the same error as the post above...
it usually means that you forgot to close a bracket (idk right now, not home to test out the code, If thats not it, ill try the code when I get home and see if I can fix it)
@OP, looks like an excellent tutorial, I even copied it to word in case minecraft forums goes down again, that way Ill still be able to see it
Hmm. I seem to be having problems now. The first time I tried the tutorial it worked fine, after I updated the functions, but now none of the new entities I create will notice the onUpdate / onEntityUpdate functions! I don't recall editing any of those functions at all, and no matter what, even decompiling again and rewriting the files from scratch don't work. If anyone has got it working please help me
I'm haveing the same problem! I've been trying all day and nothing seems make the entity update function work.
*Note It's mostly just code I am no good at the whole artistic stuff so I just reuse textures*
Let's Start with potions (they have endless possibilities and are extremely awesome)!
first let's create a base class to use, we will call it "EntityPotion.java". This will be an abstract class, more of a way to design future potions.
Inside this class we have:
We make this an entity (extends entity) because this will be the effect the potion has and not the actual item itself.
Global Variables:
World world: the world variable, this will allow us access to the world class and many functions
EntityPlayer: This is the player, this will allow us to access variables and methods relating to the player
timeOfEffect: This will be how long the effect should last
Methods:
We have to constructors, which should be fairly straightforward. should be used when we don't care about the player itself.
We have 3 abstract methods (These have to be implemented in any potion that extends this class)
applyEffect(): This is where the effect of the potion will be applied
removeEffect(): This is where any effects from the potions should be removed when the duration of the potion has been exceeded
func_370_e_(): A little arbitrary in terms of what it does, however this is where any updates are taken place. Every tick of the game this method will be called (we are overloading from the entity class), if you were to look at other entities you would notice that stuff to deal with motion would belong in this method. Thus we will use this to time the effect of the potion as well update anything in special cases.
The last two methods in this class are overloaded from the entity class as they are abstract, however I am not entirely sure as to how they work (all I know is it's for saving and I don't know how to deal with it if anyone knows let me know!)
Next Thread Will be how to create the invincibility potion
Invincibility ah how nice would it be to not take any damage from those dang creepers, well let me tell you It's nice!
We start off by making a new item class let's call it "ItemInvincibilityPotion.java"
So here we have the constructor for our ItemInvincibilityPotion which extends item, this takes 1 variable (in this case it's the ID of the item don't get this mistaken with the ID for the texture!)
We will also set the maximum stack size for this item to be 64 (meaning you can have 64 potions per pile).
Here we have func_193_a, this is the function the game calls when the user right clicks an item (not to be confused with onItemUse which will use an item if the player uses the item on a BLOCK)
Now let's get to the innards of this function
Here we check to see if we are on first playing on single player (don't want to deal with multiplayer atm) and second if the effects of the invincibilityPotion are currently active. This variable is static to the Entity class for this potion (I probably should have added this as a variable in the base class for all potions instead).
If the potion isn't active and we are on single player then we can create the entity for the invincibility potion and add it to our current world. Next we decrease the itemstack by 1 (so if we had 64 potions we will now have 63). Then we return the current itemstack.
And that's it for the item! Now to add the item so we can use it we look at the item class
Around line 197 we will add the following line:
This tells the game that there is an item called invincibilityPotion with the item ID of 423. func_4022_a(int i) is where we define the texture location, in this case I just used the bucket of milk texture which is 77. (call me lazy but w/e it's easy)
Now we need a way to craft it so go into CraftManager.java and around line 148 we will add the following lines:
This adds a recipe into the game, which will create a new itemStack of our invincibilityPotion (it will make 1 of them)
The next line is the look of the recipes so in total in can be ("xxx", "xxx", "xxx") which is the slots in the crafting workbench where 'x' is the item. In this case I am only using 1 item (for simplicity sake just to test) which is denoted as "#". Now for every character of '#" should be an Obsidian block in the recipe. Thus 1 block of obsidian = 1 invincibility potion.
However if I were to do something like " X ", " # ", " X " where 'X' is obsidian and the '#' is a glass block then in order to get 1 invincibilitypotion you would need to have 1 obsidian block at the top middle slot of the workbench, a glass block in the middle slot of the middle row, and another obsidian block at the bottom middle slot.
Now on to the most important part of all of this the entity class which will be named "EntityInvincibilityPotion.java"
Note the this class extends the EntityPotion class we created earlier.
Right in the constructor we call the constructor in EntityPotion to define the world and entityplayer values for our class. As well right off the bat we apply any effects this potion should have. We also create 2 variables the static variable to see if this entity is currently in use (isActive) and we create a currentHealth variable for use only with this class.
The applyEffects method sets the timeOfEffect to 80 long (I'm exactly sure how much time it is, it might be 80 ticks however it's about 15 seconds or so). it also sets the isActive variable to true (as the potion is currently active) and we keep track of the players current health as of the player ingesting the potion.
So here we print to the console "you feel mortal..." this is for testing purposes and you will see it in the console when you run "test_game.bat". As well we set the isActive variable to false and we call a function called func_395_F(). What does this odd function do exactly? Well it essentially destroys the entity from the world thus doing a bit of garbage clean up.
Now for the guts of the class:
This is our update function, which is used by all entities. For every time this is called we decrement timeOfEffect, and if it's less than or equal to zero we call the removeEffects function as described above.
If the time isn't up yet we check two things:
First if the players health is less than the health we measured before if it is then we set the players health back to what we had before. So if we had 18 health and we fell down a giant cave and got hurt for 3 damage we would technically be at 15 health. However our currentHealth variable is set to 18 thus when we fall we will have 18 health again.
However if the player decides to eat some food, we want to gain the health the food gives us. So all we do is set the currentHealth variable to the players new health. So for example we have 18 health eat a golden apple and the players health some how goes to 20 (even though gold is poisonous but w/e I'm no scientist). The next time we get hurt within the effect of the potion the players health will stay at 20.
And That's it! Run the game and be invincible, next up SonicSpeedPotion!!!!! (well just SpeedPotion)
create the class "EntitySpeedPotion.java"
So same as the invincibility potion, we call the super class constructor to define the entity of the player and the world variables. We then call applyEffects() which sets the duration of the potion and the isActive variable. For this potion the duration is 256L which is quite a bit longer than the invincibility potion lasting somewhere between 30 seconds to a minute. (it might make sense that it would last 25.6 seconds actually now that I think about it, perhaps I'll test this later).
removeEffects is somewhat the same as the invincibility potion except the output is different as it now says "You feel slower now..."
Back to our update function, so again we decrement the timeOfEffect variable, if it's less than or equal to 0 we call removeEffects.
If the potion is still active however we check to see if the player is on the ground (this potion will only work on the ground, and will not work in the air at all. So you will find that you run stupid fast but when you jump you slow right down until you hit the ground. The reason for this is because the motionX and motionZ variables act differently in the air as in it's accumulative where as on the ground the motionX and motionZ variables seem to get reset on every tick. Not saying there isn't a way to make you run off a cliff super fast and keep that momentum, but I didn't feel like doing that) Okay anyway if the player does happen to be on the ground we multiply the players momentum (motionX and motionZ) by 1.5F which to me seems to be more than double the players actual speed. Now to make them stay the same in the air, I suggest something like take the current motionX and motionZ and keep them constant while the player is in the air so you could add perhaps:
This would keep the motionX and motionZ constant when in the air. Now this also gives me a chance to discuss the functions fun_397_g_() and func_359_G. These functions return true if the player is in water (func_397_g_) or in lava (func_359_G). So if you wanted to make a faster swimming potion, you would check to see if func_397_g_ is true and multiple motionX and motionZ by let's say 1.5, this would let the player swim faster. (However again I believe this accumulative so the player will just keep getting faster and faster, you could check to see if the motion is starting to go negative or positive and just set the motion to something like 1.5 or 2.) Anyway that's all for this class, the next one I'm going to post is my favorite the low gravity potion
Okay so create the class "EntityLowGravityPotion.java"
So we notice that the first three methods are almost exactly the same as the speed potions first three methods.
back to the update function we will jump right into the guts ignoring the remove effects stuff I assume you all know what it does by now!
okay so let's break it down
This little piece of code basically says that if the duration of the potion is up and we are either on the ground, in the water or in the lava (as with this you can't really swim instead you just bounce around the water) then we can terminate the effect and return gravity back to normal for the player.
This is the line that gives us that low gravity feeling. If we continuously add 0.075 to the motionY the player will be fighting against gravity so to speak. This value is not enough to make the player go floating away, but just enough to make you jump very high and fall very slowly!
Now every update while we are in the air we want to first set the fallDistance to 0.0. This is important because when we hit the ground it will ensure that we are not going to take fall damage.
And that's it for the low gravity potion. nothing too exciting but my god is it fun!
Enjoy I hope this helps some of you!
Liquimatter.com
Thats my Website
The YouTube
Thats my Youtube
<.<; I believe this is a [Tutorial] thread, sir. Much like the other's I've seen here...
They're ALL great stuff, though, including this one! There's always a lot of information here for people who like to use MCP. I've never gotten around to playing with MCP, myself... But if I ever do, I know where to look first :3
Keep up the good work, and great first post (or, set of posts, rather), Quatham!
Custom Mob Spawners | Inverted Half Steps
Timberrrrr! | Jolly Old Saint Notch
Bladed Bows
Prefix Skeleton mobs!! Warp Arrows!!
Show me how to do it?
*** Minecraft Coder Pack Version 2.11 ***
MCP 2.11 running in C:\MCP
Compiling Minecraft
sources\minecraft\net\minecraft\src\Iteminvinsibilitypotion.java:21: reached end of file while parsing
}
Compiling Minecraft Server
=== MCP 2.11 recompile script finished ===
press any key to continue . . .
Plz help idk what to do next
Other than that, everything worked. Thanks heaps!
~ SC
EDIT: I got the same error as the post above...
My pet dragon (Egg) needs to hatch! Click on it and let it live!
My pet dragon (Egg) needs to hatch! Click on it and let it live!
[Sheep] Would YOU want to be hurt for you hair? No? Join us...
Join SDU NOW!
it usually means that you forgot to close a bracket (idk right now, not home to test out the code, If thats not it, ill try the code when I get home and see if I can fix it)
@OP, looks like an excellent tutorial, I even copied it to word in case minecraft forums goes down again, that way Ill still be able to see it
Help the little guy hatch?
I'm haveing the same problem! I've been trying all day and nothing seems make the entity update function work.