Jump to content

Recommended Posts

Posted

Forgive me if this isn't the right place to post this, but..

 

Can anyone teach me or point me towards a good tutorial for making

TileEntities

?

All of my Googling has proven fruitless and I want to play around with making said

TileEntites

.

GameSlayar

Forgive my noobiness!

Posted

1. Create a class that extends TileEntity

2. Implement ITileEntityProvider in your Block class and return an instance of the TileEntity class you just created from #createNewTileEntity

3. Register your TileEntity:

GameRegistry.registerTileEntity(YourTileEntityClass.class, ModInfo.ID + ":tileEntityUniqueName");

 

That's pretty much it. I like to use the mod_id in the registration to help prevent potential conflicts with other mods.

 

So now you have a TileEntity... but what do you want it for?

Posted

In short, I want to create a campfire block that can be lit and extinguished by right clicking. I wasn't sure how to use

#onBlockActivated

since I couldn't actually right click the block in-game.

So I assumed that to be right-clicked, a block must be/have a

TileEntity

.

 

I hope I'm right in that regard. If not, please correct me.

GameSlayar

Forgive my noobiness!

Posted

Well, here's my code for my block. It seems (as usual) that I forgot to put

@Override

before the method. But now it seems to work.

Almost.

 

Now the problem is that whenever I try to right click the block, it triggers

#onBlockActivated

twice.

I end up with something like this in the console:

//Me trying to right-click the block
true
false

//Trying to click again
true
false

 

Anyways, here's the actual block code:

 

package gameslayar.practice.common.blocks;

import java.util.Random;

import gameslayar.practice.common.PracticeCreativeTab;
import gameslayar.practice.common.PracticeMain;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class CampfireCoaled extends Block {

private final String name = "campfireCoaled";
private boolean active = false;
private final float[] bounds = { //(In pixels)
		2F,     //Min X
		0F,     //Min Y
		2F,     //Min Z
		16F,    //Max X
		9.5F,   //Max Y
		16F     //Max Z
};

//Basic Properties
public CampfireCoaled() {
	super(Material.wood);
	setUnlocalizedName(PracticeMain.MODID + "_" + name);
	setCreativeTab(PracticeCreativeTab.campingTab);
	setHarvestLevel("axe", 0);
	setHardness(2);
	setLightLevel(5);
	setBlockBounds(
			(1F/16F * bounds[0]),
			(1F/16F * bounds[1]),
			(1F/16F * bounds[2]),
			(1F/16F * bounds[3]),
			(1F/16F * bounds[4]),
			(1F/16F * bounds[5])
			);
	GameRegistry.registerBlock(this, name);

}

//***

//Makes sure that all the blocks around are rendered as well because 
//this isn't a full 1x1x1 block
@Override
public boolean isOpaqueCube() {
	return false;
}
//Corrects lighting around the block
@Override
public boolean isFullCube() {
	return false;
}

@Override
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ) {
	if(active) {
		active = false;
		System.out.println(active);
		return false;
	} else {
		active = true;
		System.out.println(active);
		return true;
	}
}

//Particle effects. Fancy fire & smoke.
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World world, BlockPos pos, IBlockState state, Random random) {
	if(active) {
		float f1 = (float)(pos.getX()+0.5F);
		float f2 = (float)(pos.getY()+0.7F);
		float f3 = (float)(pos.getZ()+0.5F);
		float f4 = random.nextFloat() * 0.1F;
		float f5 = random.nextFloat() * -0.1F;

		world.spawnParticle(
				EnumParticleTypes.FLAME,
				(float)(f1+f4),
				(float)(f2),
				(float)(f3+f5),
				0.0D,
				0.0D,
				0.0D,
				new int[0]
				);

		f4 = (float)random.nextFloat() * 0.3F - 0.1F;
		f5 = (float)random.nextFloat() * -0.3F + 0.1F;

		world.spawnParticle(
				EnumParticleTypes.SMOKE_LARGE,
				(float)(f1+f4),
				(float)(f2+0.3F),
				(float)(f3+f5),
				0.0D,
				0.0D,
				0.0D,
				new int[0]
				);
	}
}


//***

public String getName() {
	return name;
}
}

 

GameSlayar

Forgive my noobiness!

Posted

Block#onBlockActivated

is called on both the client and server (like most methods).

 

You can't store mutable data in fields of your

Block

or

Item

classes, these are singletons so only one instance of the class exists per block/item type. Any changes you make will be shared between all occurrences of the block/item.

 

You need to use the block's

IBlockState

to store the activated state:

  • Create your properties (using the
    IProperty

    implementations) and store them as

    public static final

    fields

  • Override
    Block#createBlockState

    to return a new instance of

    BlockState

    , using

    this

    and the properties as constructor arguments

  • Override
    Block#getStateFromMeta

    and

    Block#getMetaFromState

    to convert between the

    IBlockState

    and metadata

  • Use
    blockState.getBaseState()

    to get the base state, then chain

    IBlockState#withProperty

    calls to set each property's value before passing the result to

    Block#setDefaultState

    in the constructor to set the default state

 

You can use

IBlockState#getValue

to get the value of a property and

World#setBlockState

to change the state at the specified position.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

Thank you, but while your reply is probably well explained to most people, I can't help but have a little trouble understanding.

 

In short, your last bullet point confuses me. Would you mind explaining it in terms a less skilled modder would understand?

 

PS - In this method I'm confused about what I'm supposed to return exactly.

@Override
public int getMetaFromState(IBlockState state) {
    Boolean type = (Boolean) state.getValue(LIT);
    return type //Not sure how to return the metadata here
}

 

PPS - Sorry to be a pain in the ass

GameSlayar

Forgive my noobiness!

Posted

PS -

EDIT: I think I've got it. Is this how it works?

 

@Override
public int getMetaFromState(IBlockState state) {
    Boolean type = (Boolean) state.getValue(LIT);
    if(type) {
    	return(1);
    } else {
    	return(0);
    }
}

GameSlayar

Forgive my noobiness!

Posted

PS -

EDIT: I think I've got it. Is this how it works?

 

@Override
public int getMetaFromState(IBlockState state) {
    Boolean type = (Boolean) state.getValue(LIT);
    if(type) {
    	return(1);
    } else {
    	return(0);
    }
}

 

That should work, but I have a few minor nitpicks:

  • Name your variables properly.
    type

    isn't a type of any kind, it's the value of the

    LIT

    property so call it something like

    lit

    or

    isLit

    .

    • Use raw primitive types (
      boolean

      ) rather than boxed primitive types (

      Boolean

      ) when possible. Generic type arguments require boxed types, but Java will automatically box and unbox primitives as needed. See this page for more details on boxing.

    • There's no need for the parentheses around the returned values, you can have any amount of whitespace between
      return

      and the expression.

    • You can convert the
      if

      statement to a ternary expression.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

Thanks, my code has been corrected!

 

Ah, and were you able to simplify this for me?

Thank you, but while your reply is probably well explained to most people, I can't help but have a little trouble understanding.

 

In short, your last bullet point confuses me. Would you mind explaining it in terms a less skilled modder would understand?

 

PPS - Sorry to be a pain in the ass

 

 

Use

blockState.getBaseState()

to get the base state, then chain

IBlockState#withProperty

calls to set each property's value before passing the result to

Block#setDefaultState

in the constructor to set the default state

GameSlayar

Forgive my noobiness!

Posted
public YourBlockClass() // Constructor of YourBlockClass
{
super(Material.rock);
setDefaultState(blockState.getBaseState().withProperty(SOME_PROPERTY, someDefaultValue).withProperty(OTHER_PROPERTY, otherDefaultValue));
}

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

Last request. Promise.

I'm now stuck on the

World#setBlockState

bit, simply because I don't know what to put for the

state

argument.

 worldIn.setBlockState(pos, /* I have no idea what goes here */);

 

Should I have named the states in

#getStateFromMeta

?

Could you check through, maybe give me a hint as to what I'm doing wrong?

 

@Override
public IBlockState getStateFromMeta(int meta) {
    return getDefaultState().withProperty(LIT, meta == 0 ? false : true);
}

 

 

EDIT:

Is this okay?

worldIn.setBlockState(pos, getStateFromMeta(0));

 

 

DOUBLE EDIT:

Awesome, everything works - thanks!

GameSlayar

Forgive my noobiness!

Posted

Don't use metadata values yourself (the whole point of the blockstate system is to abstract away metadata), get the default state of a block (

Block#getDefaultState

) and then set each property to the desired value (chain

IBlockState#withProperty

calls).

 

Your

Block#getStateFromMeta

implementation can be simplified: comparison operators like

==

already return

boolean

values, you don't need to use a ternary expression here. Consider using the

!=

(not equal),

>

(greater than) or

!

(not) operators here.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

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