Hello everyone I'm Spaces and I will be doing some tutorials on Minecraft modding just request some tutorials and I will try to post a tutorial on it. I can also do tutorials on API's.
Requested Tutorials
If you want a specific tutorial reply to the thread with a request.
package net.minecraft.src;
public class mod_Namehere extends BaseMod
{
public mod_Namehere()
{
}
public String Version()
{
return "1.2.3";
}
}
How to post your errors!READ THIS!
You must use code tags if you don't know what those are you use [ code] and [ /code] in between those to tags you post your error log and in separate code tags post your code. If you don't bother doing this I won't bother to help you out.
So basically all this tutorial really is creating a new throwable entity.
Your mod_ class
package net.minecraft.src;
public class mod_Tutorial extends BaseMod{
public static Item gun = new ItemGun(3000).setMaxStackSize(1).setItemName("Gun");
public static Item bullet = new Item(3001).setItemName("Bullet");
@Override
public String getVersion() {
return "Spaces Tutorials!";
}
@Override
public void load() {
ModLoader.addName(gun , "Gun");
ModLoader.addName(bullet, "bullet");
gun.iconIndex = ModLoader.addOverride("/gui/items.png", "/Mods/Picture.png");
bullet.iconIndex = ModLoader.addOverride("/gui/items.png", "/Mods/Picture.png");
ModLoader.addShapelessRecipe(new ItemStack(bullet, 64), new Object[]{
Block.dirt
});
ModLoader.addShapelessRecipe(new ItemStack(gun, 1), new Object[]{
Block.dirt, Block.dirt
});
}
}
ItemGun class
package net.minecraft.src;
public class BItemBlackRevolver extends Item
{
public BItemBlackRevolver(int par1)
{
super(par1);
this.maxStackSize = 1;
}
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
boolean var5 = par3EntityPlayer.capabilities.depleteBuckets;
if (!par3EntityPlayer.capabilities.depleteBuckets)
{
if (var5 || par3EntityPlayer.inventory.hasItem(mod_Tutorial.bullet.shiftedIndex))
{
if (!var5)
{
par3EntityPlayer.inventory.consumeInventoryItem(mod_Tutorial.bullet.shiftedIndex);
if (!par2World.isRemote)
{
par2World.spawnEntityInWorld(new EntityBullet(par2World, par3EntityPlayer));
}
par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F));
}
}
}
return par1ItemStack;
}
}
EntityBullet
package net.minecraft.src;
public class EntityBullet extends EntityThrowable
{
public EntityBullet(World par1World)
{
super(par1World);
}
public EntityBullet(World par1World, EntityLiving par2EntityLiving)
{
super(par1World, par2EntityLiving);
}
public EntityBullet(World par1World, double par2, double par4, double par6)
{
super(par1World, par2, par4, par6);
}
protected void onImpact(MovingObjectPosition par1MovingObjectPosition)
{
if (par1MovingObjectPosition.entityHit != null)
{
/**The damage is this variable
* \/ **/
byte var2 = 5;
if (par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.thrower), var2))
{
;
}
}
for (int var3 = 0; var3 < 8; ++var3)
{
this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
}
if (!this.worldObj.isRemote)
{
this.setEntityDead();
}
}
}
Explanation
For the mod_Tutorial file:
You should know how to make a basic item with modloader. For the gun item makes a new ItemGun because there are specific things we need to do inside that class for make the gun to work and the bullet item is just a plain old Item because its just not going to do anything all its going to help us with is checking if the player has the item in their inventory.
For the ItemGun file:
So this file is specifically important because if you look at the onRightClick method and inside of it the deplete buckets statement it checks if the specific item is in the Player's inventory and if it is it will take the item on right click and it will spawn an entitybullet into the world.
For the EntityBullet file:
Basically all this is just the EntitySnowball file with renamed methods and if you see where I left a comment saying this is the damage variable just make that how ever much you like and it goes by half hearts so to kill a player on bullet hit it has to be 20.
package net.minecraft.src;
public class mod_Tutorial extends BaseMod{
public static final Block pressureplate = new BlockPressurePlate(250, 0, EnumMobType.mobs, Material.cloth).setHardness(9F).setStepSound(Block.soundClothFootstep).setBlockName("pressureplate");
@Override
public String getVersion() {
return "Spaces Tutorials!";
}
@Override
public void load() {
pressureplate.blockIndexInTexture = ModLoader.addOverride("/terrain.png", "/Mods/Whatever.png");
ModLoader.addName(pressureplate, "Pressure Plate TuT");
ModLoader.registerBlock(pressureplate);
ModLoader.addShapelessRecipe(new ItemStack(pressureplate, 1), new Object[]{
Block.dirt
});
}
}
Explanation
This tutorial was pretty easy all you really have to do is instead of making it a new BlockWhatever and making a new class you make it a new BlockPressurePlate and add the extra parameters. The EnumMobType you can change it to any mob that you want for it to activate the pressure plate and the Material you can change to whatever and you can fix the hardness of it by adding .setHardness(#F)
**Update**
Hey guys one of my friends just showed me that there was a bug in my gun code that you could keep shooting without bullets but I updated the code so that you cant. Sorry for that.
For this tutorial you need Puddlehund's Dimension API which can be found here.
Your mod_ file
package net.minecraft.src;
public class mod_Tutorial extends BaseMod{
public static final Item tutorial = new ItemTutorial(250, 0).setItemName("Derp");
public mod_Tutorial() {
DimensionAPI.registerDimension(new WorldProviderTutorial());
}
public String getVersion() {
return "Spaces Tutorials!";
}
public void load() {
ModLoader.addName(tutorial,"Tutorial Portal");
ModLoader.addRecipe(new ItemStack(tutorial, 1), new Object[] {"#", Character.valueOf('#'), Block.dirt});
}
}
Your WorldProvider file
package net.minecraft.src;
public class WorldProviderTutorial extends WorldProviderBase
{
public int getDimensionID()
{
return 3;
}
public boolean renderClouds()
{
return true;
}
public boolean renderVoidFog()
{
return false;
}
public float setSunSize()
{
return 0.5F;
}
public float setMoonSize()
{
return 0.5F;
}
public boolean renderStars()
{
return true;
}
public boolean darkenSkyDuringRain()
{
return false;
}
public String getRespawnMessage()
{
return "Your a derp.";
}
public void registerWorldChunkManager()
{
worldChunkMgr = new WorldChunkManagerTutorial(worldObj);
}
public IChunkProvider getChunkProvider()
{
return new ChunkProviderTutorial(worldObj, worldObj.getSeed(), hasNoSky);
}
}
Your ChunkManager file
package net.minecraft.src;
import java.util.List;
import java.util.Random;
public class ChunkProviderTutorial implements IChunkProvider
{
private World worldObj;
private Random random;
private final boolean useStructures;
private MapGenVillage villageGen;
public ChunkProviderTutorial(World par1World, long par2, boolean par4)
{
villageGen = new MapGenVillage(1);
worldObj = par1World;
useStructures = par4;
random = new Random(par2);
}
private void generate(byte par1ArrayOfByte[])
{
int i = par1ArrayOfByte.length / 256;
for (int j = 0; j < 16; j++)
{
for (int k = 0; k < 16; k++)
{
for (int l = 0; l < i; l++)
{
int i1 = 0;
if (l == 0)
{
i1 = Block.bedrock.blockID;
}
else if (l <= 2)
{
i1 = Block.dirt.blockID;
}
else if (l == 3)
{
i1 = Block.grass.blockID;
}
par1ArrayOfByte[j << 11 | k << 7 | l] = (byte)i1;
}
}
}
}
/**
* Creates an empty chunk ready to put data from the server in
*/
public Chunk loadChunk(int par1, int par2)
{
return provideChunk(par1, par2);
}
/**
* Will return back a chunk, if it doesn't exist and its not a MP client it will generates all the blocks for the
* specified chunk from the map seed and chunk seed
*/
public Chunk provideChunk(int par1, int par2)
{
byte abyte0[] = new byte[32768];
generate(abyte0);
Chunk chunk = new Chunk(worldObj, abyte0, par1, par2);
if (useStructures)
{
villageGen.generate(this, worldObj, par1, par2, abyte0);
}
chunk.generateSkylightMap();
return chunk;
}
/**
* Checks to see if a chunk exists at x, y
*/
public boolean chunkExists(int par1, int par2)
{
return true;
}
/**
* Populates chunk with ores etc etc
*/
public void populate(IChunkProvider par1IChunkProvider, int par2, int par3)
{
random.setSeed(worldObj.getSeed());
long l = (random.nextLong() / 2L) * 2L + 1L;
long l1 = (random.nextLong() / 2L) * 2L + 1L;
random.setSeed((long)par2 * l + (long)par3 * l1 ^ worldObj.getSeed());
if (useStructures)
{
villageGen.generateStructuresInChunk(worldObj, random, par2, par3);
}
}
/**
* Two modes of operation: if passed true, save all Chunks in one go. If passed false, save up to two chunks.
* Return true if all chunks have been saved.
*/
public boolean saveChunks(boolean par1, IProgressUpdate par2IProgressUpdate)
{
return true;
}
/**
* Unloads the 100 oldest chunks from memory, due to a bug with chunkSet.add() never being called it thinks the list
* is always empty and will not remove any chunks.
*/
public boolean unload100OldestChunks()
{
return false;
}
/**
* Returns if the IChunkProvider supports saving.
*/
public boolean canSave()
{
return true;
}
/**
* Converts the instance data to a readable string.
*/
public String makeString()
{
return "FlatLevelSource";
}
/**
* Returns a list of creatures of the specified type that can spawn at the given location.
*/
public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4)
{
BiomeGenBase biomegenbase = worldObj.func_48454_a(par2, par4);
if (biomegenbase == null)
{
return null;
}
else
{
return biomegenbase.getSpawnableList(par1EnumCreatureType);
}
}
/**
* Returns the location of the closest structure of the specified type. If not found returns null.
*/
public ChunkPosition findClosestStructure(World par1World, String par2Str, int par3, int i, int j)
{
return null;
}
}
Your WorldChunkManager file
package net.minecraft.src;
import java.util.*;
public class WorldChunkManagerTutorial extends WorldChunkManager
{
private GenLayer genBiomes;
/** A GenLayer containing the indices into BiomeGenBase.biomeList[] */
private GenLayer biomeIndexLayer;
/** The BiomeCache object for this world. */
private BiomeCache biomeCache;
/** A list of biomes that the player can spawn in. */
private List biomesToSpawnIn;
protected WorldChunkManagerTutorial()
{
biomeCache = new BiomeCache(this);
biomesToSpawnIn = new ArrayList();
biomesToSpawnIn.add(BiomeGenBase.forest);
biomesToSpawnIn.add(BiomeGenBase.plains);
biomesToSpawnIn.add(BiomeGenBase.taiga);
biomesToSpawnIn.add(BiomeGenBase.taigaHills);
biomesToSpawnIn.add(BiomeGenBase.forestHills);
biomesToSpawnIn.add(BiomeGenBase.field_48416_w);
biomesToSpawnIn.add(BiomeGenBase.field_48417_x);
biomesToSpawnIn.add(BiomeGenBase.virus);
}
public WorldChunkManagerTutorial(long par1, WorldType par3WorldType)
{
this();
GenLayer agenlayer[] = GenLayer.func_48425_a(par1, par3WorldType);
genBiomes = agenlayer[0];
biomeIndexLayer = agenlayer[1];
}
public WorldChunkManagerTutorial(World par1World)
{
this(par1World.getSeed(), par1World.getWorldInfo().getTerrainType());
}
/**
* Gets the list of valid biomes for the player to spawn in.
*/
public List getBiomesToSpawnIn()
{
return biomesToSpawnIn;
}
/**
* Returns the BiomeGenBase related to the x, z position on the world.
*/
public BiomeGenBase getBiomeGenAt(int par1, int par2)
{
return biomeCache.getBiomeGenAt(par1, par2);
}
/**
* Returns a list of rainfall values for the specified blocks. Args: listToReuse, x, z, width, length.
*/
public float[] getRainfall(float par1ArrayOfFloat[], int par2, int par3, int par4, int par5)
{
IntCache.resetIntCache();
if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5)
{
par1ArrayOfFloat = new float[par4 * par5];
}
int ai[] = biomeIndexLayer.getInts(par2, par3, par4, par5);
for (int i = 0; i < par4 * par5; i++)
{
float f = (float)BiomeGenBase.biomeList[ai[i]].getIntRainfall() / 65536F;
if (f > 1.0F)
{
f = 1.0F;
}
par1ArrayOfFloat[i] = f;
}
return par1ArrayOfFloat;
}
/**
* Return an adjusted version of a given temperature based on the y height
*/
public float getTemperatureAtHeight(float par1, int par2)
{
return par1;
}
/**
* Returns a list of temperatures to use for the specified blocks. Args: listToReuse, x, y, width, length
*/
public float[] getTemperatures(float par1ArrayOfFloat[], int par2, int par3, int par4, int par5)
{
IntCache.resetIntCache();
if (par1ArrayOfFloat == null || par1ArrayOfFloat.length < par4 * par5)
{
par1ArrayOfFloat = new float[par4 * par5];
}
int ai[] = biomeIndexLayer.getInts(par2, par3, par4, par5);
for (int i = 0; i < par4 * par5; i++)
{
float f = (float)BiomeGenBase.biomeList[ai[i]].getIntTemperature() / 65536F;
if (f > 1.0F)
{
f = 1.0F;
}
par1ArrayOfFloat[i] = f;
}
return par1ArrayOfFloat;
}
/**
* Returns an array of biomes for the location input.
*/
public BiomeGenBase[] getBiomesForGeneration(BiomeGenBase par1ArrayOfBiomeGenBase[], int par2, int par3, int par4, int par5)
{
IntCache.resetIntCache();
if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5)
{
par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5];
}
int ai[] = genBiomes.getInts(par2, par3, par4, par5);
for (int i = 0; i < par4 * par5; i++)
{
par1ArrayOfBiomeGenBase[i] = BiomeGenBase.biomeList[ai[i]];
}
return par1ArrayOfBiomeGenBase;
}
/**
* Returns biomes to use for the blocks and loads the other data like temperature and humidity onto the
* WorldChunkManager Args: oldBiomeList, x, z, width, depth
*/
public BiomeGenBase[] loadBlockGeneratorData(BiomeGenBase par1ArrayOfBiomeGenBase[], int par2, int par3, int par4, int par5)
{
return getBiomeGenAt(par1ArrayOfBiomeGenBase, par2, par3, par4, par5, true);
}
/**
* Return a list of biomes for the specified blocks. Args: listToReuse, x, y, width, length, cacheFlag (if false,
* don't check biomeCache to avoid infinite loop in BiomeCacheBlock)
*/
public BiomeGenBase[] getBiomeGenAt(BiomeGenBase par1ArrayOfBiomeGenBase[], int par2, int par3, int par4, int par5, boolean par6)
{
IntCache.resetIntCache();
if (par1ArrayOfBiomeGenBase == null || par1ArrayOfBiomeGenBase.length < par4 * par5)
{
par1ArrayOfBiomeGenBase = new BiomeGenBase[par4 * par5];
}
if (par6 && par4 == 16 && par5 == 16 && (par2 & 0xf) == 0 && (par3 & 0xf) == 0)
{
BiomeGenBase abiomegenbase[] = biomeCache.getCachedBiomes(par2, par3);
System.arraycopy(abiomegenbase, 0, par1ArrayOfBiomeGenBase, 0, par4 * par5);
return par1ArrayOfBiomeGenBase;
}
int ai[] = biomeIndexLayer.getInts(par2, par3, par4, par5);
for (int i = 0; i < par4 * par5; i++)
{
par1ArrayOfBiomeGenBase[i] = BiomeGenBase.biomeList[ai[i]];
}
return par1ArrayOfBiomeGenBase;
}
/**
* checks given Chunk's Biomes against List of allowed ones
*/
public boolean areBiomesViable(int par1, int par2, int par3, List par4List)
{
int i = par1 - par3 >> 2;
int j = par2 - par3 >> 2;
int k = par1 + par3 >> 2;
int l = par2 + par3 >> 2;
int i1 = (k - i) + 1;
int j1 = (l - j) + 1;
int ai[] = genBiomes.getInts(i, j, i1, j1);
for (int k1 = 0; k1 < i1 * j1; k1++)
{
BiomeGenBase biomegenbase = BiomeGenBase.biomeList[ai[k1]];
if (!par4List.contains(biomegenbase))
{
return false;
}
}
return true;
}
/**
* Finds a valid position within a range, that is once of the listed biomes.
*/
public ChunkPosition findBiomePosition(int par1, int par2, int par3, List par4List, Random par5Random)
{
int i = par1 - par3 >> 2;
int j = par2 - par3 >> 2;
int k = par1 + par3 >> 2;
int l = par2 + par3 >> 2;
int i1 = (k - i) + 1;
int j1 = (l - j) + 1;
int ai[] = genBiomes.getInts(i, j, i1, j1);
ChunkPosition chunkposition = null;
int k1 = 0;
for (int l1 = 0; l1 < ai.length; l1++)
{
int i2 = i + l1 % i1 << 2;
int j2 = j + l1 / i1 << 2;
BiomeGenBase biomegenbase = BiomeGenBase.biomeList[ai[l1]];
if (par4List.contains(biomegenbase) && (chunkposition == null || par5Random.nextInt(k1 + 1) == 0))
{
chunkposition = new ChunkPosition(i2, 0, j2);
k1++;
}
}
return chunkposition;
}
/**
* Calls the WorldChunkManager's biomeCache.cleanupCache()
*/
public void cleanupCache()
{
biomeCache.cleanupCache();
}
}
Your Teleporter file
package net.minecraft.src;
public class TeleporterTutorial extends Teleporter{}
Your Item file
package net.minecraft.src;
import java.util.ArrayList;
import java.util.List;
public class ItemTutorial extends ItemTeleporterBase
{
public ItemTutorial(int i, int j)
{
super(i);
}
public WorldProviderBase getDimension()
{
return new WorldProviderTutorial();
}
public TeleporterTutorial getTeleporter()
{
return new TeleporterTutorial();
}
public String getEnteringMessage()
{
return "Entering the Tutorial Dimension";
}
public String getLeavingMessage()
{
return "Leaving the Tutorial Dimension";
}
public boolean isPortalImmediate()
{
return true;
}
public boolean displayPortalAnimation()
{
return true;
}
public int returnsPlayerToDimension()
{
return 0;
}
public double getDistanceRatio()
{
return 0.2D;
}
public int getPortalDelay()
{
return 150;
}
}
I edited Puddlehund's ItemTeleporterBase to make this work so here it is
package net.minecraft.src;
import java.util.ArrayList;
import java.util.List;
public abstract class ItemTeleporterBase extends Item
implements ISpecialTeleportation
{
public ItemTeleporterBase(int i)
{
super(i);
}
public ItemStack onItemRightClick(ItemStack itemstack, World world, EntityPlayer entityplayer)
{
if (!world.isRemote)
{
DimensionAPI.setInPortal(getDimension(), ModLoader.getMinecraftInstance(), (EntityPlayerSP)entityplayer, this, null);
}
if (displayPortalOverlay())
{
GuiIngame.currentPortal = this;
entityplayer.setInPortal();
if(entityplayer.timeInPortal >= 0.9F)
{
entityplayer.timeInPortal = 0.0F;
GuiIngame.currentPortal = null;
}
}
return itemstack;
}
public abstract WorldProviderBase getDimension();
public abstract TeleporterTutorial getTeleporter();
public abstract String getEnteringMessage();
public abstract String getLeavingMessage();
public boolean isPortalImmediate()
{
return true;
}
public boolean displayPortalOverlay()
{
return false;
}
public int getOverlayTexture()
{
return Block.portal.blockIndexInTexture;
}
public List canTeleportFromDimension()
{
ArrayList arraylist = new ArrayList();
arraylist.add(Integer.valueOf(0));
return arraylist;
}
public int returnsPlayerToDimension()
{
return 0;
}
public double getDistanceRatio()
{
return 1.0D;
}
public int getPortalDelay()
{
return 0;
}
public Achievement triggerAchievement()
{
return null;
}
}
[size=large]Explanation[/size]
[size=medium]
[/size]
Im not really going to explain anything because this is some advanced stuff and Puddlehund's Dimension API makes it alot more easier.
you should make a tutorial on how to add a new biome
Rollback Post to RevisionRollBack
If Facebook, Myspace, and Twitter were all destroyed, 90% of teens would go insane. If you're one of the 10% that would be laughing at them, copy this into your signature and hope it happens.
Thx for posting all these tutorials! It helps a lot. Also could you maybe look into changing blocks into entity and back again? Because that would be cool if you could pick up blocks and set them down again.
Hi
I'm making my second mod and I was hoping you could help
I have spent about 1 hour trying to figure this out, but i cant
I want to make a mod that if you put a pumpkin on your head you will immediately die.
Also I need it to be able to read a config file so I can save settings of the mod
Thanks.
This is the code i tried:
In SlotArmor.java line 27 - 32:
Thx for posting all these tutorials! It helps a lot. Also could you maybe look into changing blocks into entity and back again? Because that would be cool if you could pick up blocks and set them down again.
Hi
I'm making my second mod and I was hoping you could help
I have spent about 1 hour trying to figure this out, but i cant
I want to make a mod that if you put a pumpkin on your head you will immediately die.
Also I need it to be able to read a config file so I can save settings of the mod
Thanks.
This is the code i tried:
In SlotArmor.java line 27 - 32:
package net.minecraft.src;
public class mod_Tutorial extends BaseMod {
public static final BiomeGenBase tutorial = (new BiomeGenTutorial(24)).setColor(0xf13a01).setBiomeName("Tutorial");
public String getVersion()
{
return "Spaces Tutorials!";
}
public void load()
{
ModLoader.addBiome(tutorial);
}
}
For your mod_ file:
Ok this tutorial was fairly simple since ModLoader added the new addBiome method so you just need to make a new Biome in your mod_ file.
For your BiomeGenTutorial:
If you see the func_48415_j and func_48412_k these are for the grass colors if you see the 0xC2C2C2 that is a hexdecimal color just google hexdecimal colors and replace C2C2C2 with the color code some colors will not work. Now also if you see waterColorMultiplier and another hexdecimal color you can change that to whatever but alot of it doesn't work for the water coloring.
Well thats it for this tutorial I will post a next one soon.
Your mod_ class
ItemGun class
EntityBullet
I will try my best to make those tutorials.
Hey guys one of my friends just showed me that there was a bug in my gun code that you could keep shooting without bullets but I updated the code so that you cant. Sorry for that.
Your mod_ file
Your WorldProvider file
Your ChunkManager file
Your WorldChunkManager file
Your Teleporter file
Your Item file
I edited Puddlehund's ItemTeleporterBase to make this work so here it is
Its the same thing but with different blocks and a portal structure.
Moon dimension mod was released long ago, jesus christ!
I'll put these in the requests.
I'm making my second mod and I was hoping you could help
I have spent about 1 hour trying to figure this out, but i cant
I want to make a mod that if you put a pumpkin on your head you will immediately die.
Also I need it to be able to read a config file so I can save settings of the mod
Thanks.
This is the code i tried:
In SlotArmor.java line 27 - 32:
if (itemstack.getItem().shiftedIndex == Block.pumpkin.blockID)
{
return armorType == 0;
EntityLiving.attackEntityFrom(DamageSource.magic, 10);
}
^ it doesn't work ^
I will see what I can do.
You will have to make your own dimension portal frame and portal block. So it will spawn that portal instead of the nether portal.
What is the error?
No Problem ^-^
Your mod_ file
Your BiomeGenTutorial file