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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Reach Out To Rapid Digital: What sapp Info: +1 41 4 80 7 14 85 Email INFO: rap iddi gita lrecov ery @ exe cs. com Hello, my name is Jayson, and I’m 35 years old from the United Kingdom. My family and I recently endured an incredibly challenging experience that I wouldn’t wish on anyone. We became victims of a cryptocurrency investment fraud scheme that saw us lose a staggering $807,000 in USDT and Bitcoins. The fraudsters had created a convincing facade, and we were lured into investing, only to discover later that the platform was a complete scam. We were left devastated, not just financially, but emotionally, as we had trusted these people and believed in the legitimacy of the investment. After the initial shock wore off, we desperately searched for ways to recover the lost funds. It seemed like an impossible task, and we felt as though there was no hope. That’s when, by sheer luck, we stumbled across a post about Rapid Digital Recovery, a cryptocurrency and funds recovery organization with a proven track record in cybersecurity and fraud recovery. We decided to reach out to them, and from the first interaction, we were impressed with their professionalism and transparency. They explained the recovery process in detail and reassured us that they had the skills and expertise to track down the perpetrators and recover our funds. This gave us a renewed sense of hope, something we hadn’t felt in months. What truly stood out during our experience with Rapid Digital Recovery was their dedication to the recovery process. The team went above and beyond, using sophisticated tracking tools and cyber forensics to gather critical information. Within a matter of weeks, they had successfully located the funds and traced the scam back to the fraudsters responsible. They worked with the authorities to ensure the criminals were held accountable for their actions. To our relief, the team at Rapid Digital Recovery was able to recover every single penny we had lost. The funds were returned in full, and the sense of closure we felt was invaluable. We couldn’t have imagined such a positive outcome in the early stages of our recovery journey, and we are deeply grateful for the work they did. If you ever find yourself in a similar situation, I highly recommend contacting Rapid Digital Recovery. Their expertise, transparency, and dedication to their clients make them the go-to choice for anyone seeking to recover lost cryptocurrency or funds. They truly gave us back our financial future.  
    • This is my first time modding anything, so maybe just skill issue. I'm using Forge 54.0.12 and Temurin 21.0.5+11-LTS I wanted to create a custom keybind and to check whether it works I'd like to send a chat message. I tried using Minecraft.getInstance().player.sendSystemMessage(Component.literal("test")); but IntelliJ couldnt resolve sendSystemMessage(...). Since I saw people using it in earlier versions, I tried the same thing with 1.20.6(- 50.1.0), where it works fine, now I can't figure out if this is intentional and whether there are other options for sending chat messages. On that note, is there more documentation than https://docs.minecraftforge.net/en/1.21.x/? It seems very incomplete compared to something like the Oracle Java docs
    • Hi, i'm having this error and I wanna fix it. we try: -Reload drivers -Eliminate .minecraft -Eliminate Java -Restart launcher -Verify if minecraft is using gpu -Mods  in .minecraft is empty -Install the latest and recomended version of forge idk what i have to do, help me pls. the lastest log is: https://mclo.gs/WAMao8x  
    • Read the FAQ, Rule #2. (https://forums.minecraftforge.net/topic/125488-rules-and-frequently-asked-questions-faq/)  
    • The link to your log does not work, it says it is forbidden, Error, this is a private paste or is pending moderation.
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.