Jump to content

Recommended Posts

Posted

Hello to all you fine folks out there.

Having recently discovered the wondrous thing that is Minecraft Forge, I have started to create my own mod.

 

This mod has started out incredibly simply:

I have added the item Salt, which will, in future, be used in the processing of raw and cooked meat.

I have also added the block Rock Salt, which you can mine to get Salt.

I then successfully integrated the ore into the world gen, however; it has always been my intention to make Rock Salt spawn ONLY in Desert Biomes and only to be generated between y-Coords 55 and 65, just beneath the sand.

I have spent two days searching the internet for any references to these processes with little success. With what fragments I did find I attempted to create my own method, however, this has failed rather dismally. Both attempted methods resulted in no coding errors, as shown by Eclypse, and a fatal crash on world generation.

 

Can someone please help me with this one?

Thanks,

Dan.

Posted

[*]Eclipse does not check your code's logic, only the grammar/syntax. It has no way of knowing what you intended to do, only that what you are trying to do seems like legal Java code.

[*]It's good that you describe your intentions, but we also need to know what did happen instead?

[*]Without access to your code, we can't possible tell you what you did wrong, can we?

[*]And without the error log, how can we know what kind of error caused the runtime crash?

 

Head over to www.pastebin.com and while telling pastebin to use Syntax Highlightning: Java, post your code there and give us the link. This makes for a nice reader friendly piece of code for us to debugg.

 

Then do the same for your error log(without any highlighting), and you are on your way to perfection inn the way you ask for help, which makes getting a fast and useful reply much more likely ;)

If you guys dont get it.. then well ya.. try harder...

Posted

So, for a clarification to my post I present the following:

 

The mod I am creating is running under the name MagiCraft. The primary mod file is thus named MagiCraft.java:

package MagiCraft;

import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.block.material.Material;
import net.minecraftforge.common.ForgeHooks;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeDecorator;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.biome.BiomeGenDesert;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraftforge.common.MinecraftForge;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.Init;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.PostInit;
import cpw.mods.fml.common.Mod.PreInit;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;


@Mod(modid="Generic", name="Generic", version="0.0.0")
@NetworkMod(clientSideRequired=true, serverSideRequired=false)
public class MagiCraft 
{
//Items
public static final Item SaltItem = new ItemSalt(500);

//Blocks

//Ores
public static final Block rocksaltBlock = (new BlockRockSalt(161, 0));
   	
//Crafting

//Smelting

//Graphics
public void updateIcons(IconRegister iconRegister)
{
	iconIndex = iconRegister.registerIcon("MagiCraft:Salt");
	iconIndex = iconRegister.registerIcon("MagiCraft:RockSalt");
}


        // The instance of your mod that Forge uses.
        @Instance("MagiCraft")
        public static MagiCraft instance;
        
        // Says where the client and server 'proxy' code is loaded.
        @SidedProxy(clientSide="MagiCraft.client.ClientProxy", serverSide="MagiCraft.CommonProxy")
        public static CommonProxy proxy;

	private static BiomeGenBase BiomeGenDesert;

        
        @PreInit
        public void preInit(FMLPreInitializationEvent event) {
                // Stub Method
        }
        
        @Init
        public void load(FMLInitializationEvent event) 
        {
            LanguageRegistry.addName(SaltItem, "Salt");
            LanguageRegistry.addName(rocksaltBlock, "Rock Salt");
            MinecraftForge.setBlockHarvestLevel(rocksaltBlock, "pickaxe", 1);
            GameRegistry.registerBlock(rocksaltBlock, "BlockRockSalt");
                proxy.registerRenderers();
            GameRegistry.registerWorldGenerator(new MagiCraftGenerator());
            //Replacing Desert for Further Additions
        }
        
            
                
            	     
        
        @PostInit
        public void postInit(FMLPostInitializationEvent event) {
                // Stub Method
        }
        
}

 

As you can see this uses the world gen file MagiCraftGenerator.java.

While generating the ore randomly within game it looked as such:

package MagiCraft;

import java.util.Random;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.feature.WorldGenMinable;
import cpw.mods.fml.common.IWorldGenerator;

public class MagiCraftGenerator implements IWorldGenerator
{

@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
        switch(world.provider.dimensionId){
        case -1:
            generateNether(world, random, chunkX * 16, chunkZ * 16);
            break;
        case 0:
            generateSurface(world, random, chunkX * 16, chunkZ * 16);
            break;
        case 1:
            generateEnd(world, random, chunkX * 16, chunkZ * 16);
            break;
        }
}

private void generateEnd(World world, Random random, int i, int j) 
{

}

private void generateSurface(World world, Random random, int i, int j) 
{
	Random randomGenerator = random;

	for (i = 0; i < 15; i++)
	{
	int randPosX = i + randomGenerator.nextInt(16);
	int randPosY = random.nextInt(65);
	int randPosZ = j + randomGenerator.nextInt(16);
	(new WorldGenMinable(MagiCraft.rocksaltBlock.blockID, 10)).generate(world, random, randPosX, randPosY, randPosZ);
	}
}

private void generateNether(World world, Random random, int i, int j) 
{

}
}

 

Then ofcourse you have the block and item codes:

BLOCK

package MagiCraft;

import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockOre;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.world.World;
import net.minecraft.block.material.Material;
public class BlockRockSalt extends BlockOre
{

        public BlockRockSalt(int id, int texture) 
        {
            super(id);
            
            setHardness(0.8F); // Same as Sandstone
            setResistance(5.0F);
            setStepSound(Block.soundStoneFootstep);
            setUnlocalizedName("Rock Salt");
            setCreativeTab(CreativeTabs.tabBlock);
            }
    
    public String getTextureFile()
    {
            return CommonProxy.BLOCK_PNG;
    }
    
    public int idDropped(int par1, Random random, int par2)
    {
            return MagiCraft.SaltItem.itemID;
    }
    
    public int quantityDropped(Random par1Random)
    {
        return 4 + par1Random.nextInt(2);
    }
    
    public int quantityDroppedWithBonus(int par1, Random par2Random)
    {
        return this.quantityDropped(par2Random) + par2Random.nextInt(par1 + 1);
    }
    
}

Item

package MagiCraft;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;

public class ItemSalt extends Item 
{

        public ItemSalt(int id) 
        {
                super(id);
                // TODO Auto-generated constructor stub
                
                // Constructor Configuration
                setMaxStackSize(64);
                setCreativeTab(CreativeTabs.tabMisc);
                setUnlocalizedName("Salt");
        }
        public String getTextureFile() 
        {
        	return CommonProxy.ITEMS_PNG;
        }

}

 

To the Attempted Desert Biome Generation

After much research I decided that it was probably easiest to override the BiomeGenDesert.java by creating my own and redirecting with the following code:

   private static final BiomeGenBase BiomGenDesert = null;

public void load(FMLInitializationEvent event) 
        {
            LanguageRegistry.addName(SaltItem, "Salt");
            LanguageRegistry.addName(rocksaltBlock, "Rock Salt");
            MinecraftForge.setBlockHarvestLevel(rocksaltBlock, "pickaxe", 1);
            GameRegistry.registerBlock(rocksaltBlock, "BlockRockSalt");
                proxy.registerRenderers();
            GameRegistry.registerWorldGenerator(new MagiCraftGenerator());
            //Replacing Desert for Further Additions
            GameRegistry.removeBiome(BiomeGenBase.desert);
            GameRegistry.addBiome(MagiCraft.BiomGenDesert);
        }

 

BiomeGenDesert.java looks like:

package MagiCraft;

import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenDesertWells;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraft.world.biome.BiomeGenBase;
import MagiCraft.MagiCraftGenerator;

public class BiomeGenDesert extends BiomeGenBase
{
    public BiomeGenDesert(int par1)
    {
        super(par1);
        this.spawnableCreatureList.clear();
        this.topBlock = (byte)Block.sand.blockID;
        this.fillerBlock = (byte)Block.sand.blockID;
        this.theBiomeDecorator.treesPerChunk = -999;
        this.theBiomeDecorator.deadBushPerChunk = 2;
        this.theBiomeDecorator.reedsPerChunk = 50;
        this.theBiomeDecorator.cactiPerChunk = 10;
    }
    
    public void decorate(World par1World, Random par2Random, int par3, int par4)
    {
        super.decorate(par1World, par2Random, par3, par4);
        int o = 0 + par2Random.nextInt(6);
        int p;
        int q1;
        int r1;
        
        if (par2Random.nextInt(1000) == 0)
        {
            int k = par3 + par2Random.nextInt(16) + 8;
            int l = par4 + par2Random.nextInt(16) + 8;
            WorldGenDesertWells worldgendesertwells = new WorldGenDesertWells();
            worldgendesertwells.generate(par1World, par2Random, k, par1World.getHeightValue(k, l) + 1, l);
        }
        
         for (p = 0; p < o; ++p)
         {
        	r1 = par3 + par2Random.nextInt(16);
            q1 = par2Random.nextInt(28) + 4;
            int o1 = par4 + par2Random.nextInt(16);
            int p1 = par1World.getBlockId(q1, r1, o1);

            if (p1 == Block.sandStone.blockID)
            {
                par1World.setBlock(o1, r1, 01, MagiCraft.rocksaltBlock.blockID, 0, 2);
            }
         }
    }
}

I've attempted to combine the coding from BiomeGenBase with the Emerald Ore coding from BiomeGenHills.

 

I hope this helps you to see what I was trying to do,

Dan.

Posted

So, for a clarification to my post I present the following:

 

As you can see this uses the world gen file MagiCraftGenerator.java.

While generating the ore randomly within game it looked as such:

private void generateSurface(World world, Random random, int i, int j) 
{
	Random randomGenerator = random;

	for (i = 0; i < 15; i++)
	{
	int randPosX = i + randomGenerator.nextInt(16);
	int randPosY = random.nextInt(65);
	int randPosZ = j + randomGenerator.nextInt(16);
	(new WorldGenMinable(MagiCraft.rocksaltBlock.blockID, 10)).generate(world, random, randPosX, randPosY, randPosZ);
	}
}

 

Two things in this function:

 

1) you haven't asked the world for a biome

2) you're generating a random value from 0 to 64 (inclusive) with your randPosY.

 

In order to generate from 50 to 65, you need to make that randPosY= Random.nextInt(15) + 55;

In order to get the biomeID, you need...

 

BiomeGenBase b = world.getBiomeGenForCoords(chunkX, chunkZ);
if(b.biomeName.equals("Desert") || b.biomeName.equals("DesertHills")) {
   //existing code
}

 

If you want to make sure you only generate under sand, you'd have to check the block ID at the selected X,Y,Z coordinate:

 

world.getBlockId(randX, randY, randZ) == Block.sand)

 

Though you might want to check the block above rather than the exact x,y,z or you could check against sandstone instead.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Having now reconstructed my code using what you gave me, Draco18, I can now say for certain that it works.

I am extremely pleased with having mined my first vein of rock salt from beneath a desert.

Thank you.

 

Now how do I make it provide XP when mined again..?

Dan

Posted

Having now reconstructed my code using what you gave me, Draco18, I can now say for certain that it works.

I am extremely pleased with having mined my first vein of rock salt from beneath a desert.

Thank you.

 

Now how do I make it provide XP when mined again..?

Dan

 

dropXpOnBlockBreak(...)

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Thank you again for the help on the XP, It's now all working...

 

But to get back into interesting bugs that shouldn't exist, I have created the items Salted Pork and Salted Porkchop, however; neither of them are showing their name in-game.

Here's the code:

package MagiCraft;

import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemFood;

public class ItemSaltedPork extends ItemFood
{
int A = 501;
int B = 4;
float C = 0.4F;
boolean D = false;

public ItemSaltedPork(int A, int B, float C, boolean D)
{
	super (A, B, C, D);
	setMaxStackSize(64);
        setCreativeTab(CreativeTabs.tabFood);
        setUnlocalizedName("Salted Pork");
}
}

 

Could someone please shed some light on this as I am using the same code for an entire range of new foods and it's not working on any of them.

Thanks,

Dan.

Posted

Nudge, nudge...

Still no response to the above post so I have paused in the production of food items.

Also I have been having trouble with adding multiple textures to my Rock Salt block. It keeps coming up texture is missing.

package MagiCraft;

import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.block.BlockOre;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
import net.minecraft.block.material.Material;
import net.minecraft.world.IBlockAccess;

public class BlockRockSalt extends BlockOre
{
private Icon sides, bottom, top;
public void registerIcons(IconRegister par1IconRegister)
{
	this.sides = par1IconRegister.registerIcon("MagiCraft:RockSaltSide");
	this.bottom = par1IconRegister.registerIcon("MagiCraft:RockSaltBottom");
	this.top = par1IconRegister.registerIcon("MagiCraft:RockSaltTop");
}
public Icon getBlockTextureFromSideAndMetadata(int i, int j)
{
	if (i == 0)
	{
		return bottom;
	}
	if (i == 1)
	{
		return top;
	}
	else
	{
	return sides;
	}
}//Don't edit this.

        public BlockRockSalt(int id, int texture) 
        {
            super(id);
            
            setHardness(0.8F); // Same as Sandstone
            setResistance(5.0F);
            setStepSound(Block.soundStoneFootstep);
            setUnlocalizedName("Rock Salt");
            setCreativeTab(CreativeTabs.tabBlock);
            }
        
    public int idDropped(int par1, Random random, int par2)
    {
            return MagiCraft.SaltItem.itemID;
    }
    
    public int dropXpOnBlockBreak(Random par3Random)
    {
    	return 5 + par3Random.nextInt(2);
    }
    
    
    public int quantityDropped(Random par1Random)
    {
        return 4 + par1Random.nextInt(2);
    }
    public String getTextureFile() 
    {
    	return CommonProxy.BLOCK_PNG;
    }
}

 

Any help with either problem would be much appreciated.

Dan.

Posted

For generating you could do

 

public void generateSurface(World world, Random rand, int i, int j)

{

BiomeGenBase b = world.getBiomeGenForCoords(chunkX, chunkZ);

if (b instanceof BiomeGenBase.desert)

{

  for (i = 0; i < 15; i++)

  {

  int randPosX = i + randomGenerator.nextInt(16);

  int randPosY = random.nextInt(65) + 50;

  int randPosZ = j + randomGenerator.nextInt(16);

  (new WorldGenMinable(MagiCraft.rocksaltBlock.blockID, 10)).generate(world, random, randPosX, randPosY, randPosZ);

 

}

}

}

Posted

Do you ever actually register your item in the GameRegistry?

 

        @Init
        public void load(FMLInitializationEvent event) 
        {
            LanguageRegistry.addName(SaltItem, "Salt");
            LanguageRegistry.addName(rocksaltBlock, "Rock Salt");
            MinecraftForge.setBlockHarvestLevel(rocksaltBlock, "pickaxe", 1);
            GameRegistry.registerBlock(rocksaltBlock, "BlockRockSalt");
                proxy.registerRenderers();
            GameRegistry.registerWorldGenerator(new MagiCraftGenerator());
            //Replacing Desert for Further Additions
        }

 

Not seeing a:

 GameRegistry.registerItem(SaltItem, "Salt");

Posted

Nudge, nudge...

Still no response to the above post so I have paused in the production of food items.

Also I have been having trouble with adding multiple textures to my Rock Salt block. It keeps coming up texture is missing.

 

package MagiCraft;

import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.block.BlockOre;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
import net.minecraft.block.material.Material;
import net.minecraft.world.IBlockAccess;

public class BlockRockSalt extends BlockOre
{
private Icon sides, bottom, top;
public void registerIcons(IconRegister par1IconRegister)
{
	this.sides = par1IconRegister.registerIcon("MagiCraft:RockSaltSide");
	this.bottom = par1IconRegister.registerIcon("MagiCraft:RockSaltBottom");
	this.top = par1IconRegister.registerIcon("MagiCraft:RockSaltTop");
}
public Icon getBlockTextureFromSideAndMetadata(int i, int j)
{
	if (i == 0)
	{
		return bottom;
	}
	if (i == 1)
	{
		return top;
	}
	else
	{
	return sides;
	}
}//Don't edit this.

        public BlockRockSalt(int id, int texture) 
        {
            super(id);
            
            setHardness(0.8F); // Same as Sandstone
            setResistance(5.0F);
            setStepSound(Block.soundStoneFootstep);
            setUnlocalizedName("Rock Salt");
            setCreativeTab(CreativeTabs.tabBlock);
            }
        
    public int idDropped(int par1, Random random, int par2)
    {
            return MagiCraft.SaltItem.itemID;
    }
    
    public int dropXpOnBlockBreak(Random par3Random)
    {
    	return 5 + par3Random.nextInt(2);
    }
    
    
    public int quantityDropped(Random par1Random)
    {
        return 4 + par1Random.nextInt(2);
    }
    public String getTextureFile() 
    {
    	return CommonProxy.BLOCK_PNG;
    }
}

 

 

Any help with either problem would be much appreciated.

Dan.

 

First, make sure that your texture files are named correctly and are in the correct folders.  Since you didn't have this problem a few days ago, I doubt it's this, but it doesn't hurt to be thorough.

 

Second, which is probably the issue, make sure that if you are going to override a method, like you are here, use the @Override tag before the method declaration so it is explicitly using your method when getting the textures for your block.  It's also a good way to make sure that you overrode the method correctly, since Eclipse will flip if you try to override a method incorrectly.

 

 

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.