Jump to content

Rotating Stairs


_gjkf_

Recommended Posts

Hey everybody!!! I'm making a mod that will allow the player to place stairs horizontally. I have created the custom stair but I can't find a way to make my stair rotate. I'd love to use vanilla stairs and then just rotate them, but I can't figure out a way to do it.

 

I'd also love to know a way to understand what the methods and parameters name are. E.g. what is "field_150152_N"?

 

Any help would be really appreciated. Thanks in advance.

 

 

 

The stair class

 

 

 

 

package com.gjkf.blocks;

 

import cpw.mods.fml.relauncher.Side;

import cpw.mods.fml.relauncher.SideOnly;

import net.minecraft.block.Block;

import net.minecraft.block.BlockStairs;

import net.minecraft.block.material.Material;

import net.minecraft.client.renderer.texture.IIconRegister;

import net.minecraft.entity.EntityLivingBase;

import net.minecraft.entity.player.EntityPlayer;

import net.minecraft.item.ItemStack;

import net.minecraft.util.IIcon;

import net.minecraft.util.MathHelper;

import net.minecraft.world.IBlockAccess;

import net.minecraft.world.World;

 

public class HorizontalStair extends BlockStairs{

private final Block block;

private final int meta;

private boolean field_150152_N;

private int field_150153_O;

 

public HorizontalStair(Block blockSource, int metadata) {

super(blockSource, 0);

this.block = blockSource;

this.meta = metadata;

this.useNeighborBrightness = true;

}

 

@Override

public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z){

if (this.field_150152_N){

this.setBlockBounds(

0.5F * (float)(this.field_150153_O % 2),

0.5F * (float)(this.field_150153_O / 2 % 2),

0.5F * (float)(this.field_150153_O / 4 % 2),

0.5F + 0.5F * (float)(this.field_150153_O % 2),

0.5F + 0.5F * (float)(this.field_150153_O / 2 % 2),

0.5F + 0.5F * (float)(this.field_150153_O / 4 % 2));

}else{

this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);

}

}

 

@Override

public int getRenderType(){

return 10;

}

 

@Override

@SideOnly(Side.CLIENT)

public IIcon getIcon(int side, int meta){

return this.block.getIcon(side, this.meta);

}

 

@Override

@SideOnly(Side.CLIENT)

public void registerBlockIcons(IIconRegister p_149651_1_) {

 

}

 

@Override

public boolean isOpaqueCube(){

return false;

}

 

@Override

public int onBlockPlaced(World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ, int meta){

return side != 0 && (side == 1 || (double)hitY <= 0.5D) ? meta : meta | 4;

}

 

@Override

public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase ent, ItemStack p_149689_6_){

int l = MathHelper.floor_double((double)(ent.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;

int i1 = world.getBlockMetadata(x, y, z) & 4;

 

if (l == 0){

world.setBlockMetadataWithNotify(x, y, z, 2 | i1, 2);

}

 

if (l == 1){

world.setBlockMetadataWithNotify(x, y, z, 1 | i1, 2);

}

 

if (l == 2){

world.setBlockMetadataWithNotify(x, y, z, 3 | i1, 2);

}

 

if (l == 3){

world.setBlockMetadataWithNotify(x, y, z, 0 | i1, 2);

}

}

 

@Override

public void onBlockClicked(World world, int x, int y, int z, EntityPlayer ent){

this.block.onBlockClicked(world, x, y, z, ent);

}

 

}

 

 

 

"I an atom in the universe, a universe of atoms"-- Richard P. Feynman

Link to comment
Share on other sites

Hi

 

try these methods under Block::

 

-TGG

 

    /**
     * Rotate the block. For vanilla blocks this rotates around the axis passed in (generally, it should be the "face" that was hit).
     * Note: for mod blocks, this is up to the block and modder to decide. It is not mandated that it be a rotation around the
     * face, but could be a rotation to orient *to* that face, or a visiting of possible rotations.
     * The method should return true if the rotation was successful though.
     *
     * @param worldObj The world
     * @param x X position
     * @param y Y position
     * @param z Z position
     * @param axis The axis to rotate around
     * @return True if the rotation was successful, False if the rotation failed, or is not possible
     */
    public boolean rotateBlock(World worldObj, int x, int y, int z, ForgeDirection axis)
    {
        return RotationHelper.rotateVanillaBlock(this, worldObj, x, y, z, axis);
    }

    /**
     * Get the rotations that can apply to the block at the specified coordinates. Null means no rotations are possible.
     * Note, this is up to the block to decide. It may not be accurate or representative.
     * @param worldObj The world
     * @param x X position
     * @param y Y position
     * @param z Z position
     * @return An array of valid axes to rotate around, or null for none or unknown
     */
    public ForgeDirection[] getValidRotations(World worldObj, int x, int y, int z)
    {
        return RotationHelper.getValidVanillaBlockRotations(this);
    }

Link to comment
Share on other sites

Here you are.

 

Stairs Class

package com.gjkf.blocks;

import com.gjkf.main.Main;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

public class HorizontalStair extends BlockStairs{
private final Block block;
private final int meta;
private boolean field_150152_N;
private int field_150153_O;
public static boolean field_rotated = false;

public HorizontalStair(Block blockSource, int metadata) {
	super(blockSource, metadata);
	this.block = blockSource;
	this.meta = metadata;
	this.useNeighborBrightness = true; 
}

@Override
public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z){
	if (this.field_150152_N){
		this.setBlockBounds(
				0.5F * (float)(this.field_150153_O % 2),
				0.5F * (float)(this.field_150153_O / 2 % 2),
				0.5F * (float)(this.field_150153_O / 4 % 2),
				0.5F + 0.5F * (float)(this.field_150153_O % 2),
				0.5F + 0.5F * (float)(this.field_150153_O / 2 % 2),
				0.5F + 0.5F * (float)(this.field_150153_O / 4 % 2));
	}else{
		this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
	}
}

@Override
public int getRenderType(){
	return 10;
}

@Override
@SideOnly(Side.CLIENT)
public IIcon getIcon(int side, int meta){
	return this.block.getIcon(side, this.meta);
}

@Override
@SideOnly(Side.CLIENT)
public void registerBlockIcons(IIconRegister p_149651_1_) {}

@Override
public boolean isOpaqueCube(){
	return false;
}

@Override
public int onBlockPlaced(World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ, int meta){
	return side != 0 && (side == 1 || (double)hitY <= 0.5D) ? meta : meta | 4;
}

@Override
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase ent, ItemStack p_149689_6_){

	int l = MathHelper.floor_double((double)(ent.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3;
	int i1 = world.getBlockMetadata(x, y, z) & 4;

	if(field_rotated){
		this.rotateBlock(world, x, y, z, ForgeDirection.EAST);
	}

	if (l == 0){
		world.setBlockMetadataWithNotify(x, y, z, 2 | i1, 2);
	}

	if (l == 1){
		world.setBlockMetadataWithNotify(x, y, z, 1 | i1, 2);
	}

	if (l == 2){
		world.setBlockMetadataWithNotify(x, y, z, 3 | i1, 2);
	}

	if (l == 3){
		world.setBlockMetadataWithNotify(x, y, z, 0 | i1, 2);
	}

}

@Override
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer ent){
	this.block.onBlockClicked(world, x, y, z, ent);
}

}

 

KeyBind Class

package com.gjkf.key;

import org.lwjgl.input.Keyboard;

import cpw.mods.fml.client.registry.ClientRegistry;
import net.minecraft.client.settings.KeyBinding;

public class KeyBind {

public static KeyBinding rotate;

public static void init(){
	rotate = new KeyBinding("Rotate", Keyboard.KEY_LMENU, "key.categories.gameplay");

	ClientRegistry.registerKeyBinding(rotate);
}

}

 

KeyInputHandlerClass

package com.gjkf.key;

import net.minecraft.client.settings.KeyBinding;

import org.lwjgl.input.Keyboard;

import com.gjkf.blocks.HorizontalStair;

import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.InputEvent;

public class KeyInputHandler {

@SubscribeEvent
public void onKeyInput(InputEvent.KeyInputEvent event){
	while(KeyBind.rotate.isPressed()){
		System.err.println(HorizontalStair.field_rotated);
		if(HorizontalStair.field_rotated){
			HorizontalStair.field_rotated = false;
		}else if(!HorizontalStair.field_rotated){
			HorizontalStair.field_rotated = true;
		}
	}

}

}

 

 

I wanted so that when you press a key while placing a block it would rotate it. That's why I have the KeyBindings classes.

"I an atom in the universe, a universe of atoms"-- Richard P. Feynman

Link to comment
Share on other sites

Hi

 

Hmm yeah there are a few things wrong in that code :)

 

So what you really want to do is rotate your stair before you place it, not after.

 

Some thoughts-

- the rotation of the stairs is determined by the metadata

- the initial rotation of the stairs when you place them is determined in onBlockPlacedBy - see the setBlockMetadataWithNotify

- your Horizontal stair probably doesn't need to override any of the stair methods except onBlockPlacedBy

- storing the "rotation to be used when I place the block" in a static field_rotated is a bad idea because it won't work on multiplayer - your keypresses are on the client, but the block placement is on the server which has a different copy of HorizontalStair (ie might  be on a different computer).  Unfortunately you will probably need to use packets to overcome this problem - i.e. the client needs to tell the server how many times the rotate has been pressed.

 

This link might help understand metadata, if you don't already

http://greyminecraftcoder.blogspot.com.au/2013/07/blocks.html

 

This link will help with user input and how it is sent to the server.  It's for 1.6.4 but hasn't changed much.

http://greyminecraftcoder.blogspot.com.au/2013/10/user-input.html

 

It's possible there's an easier way than packets for this, but if so I'm not sure what it is.  If you can intercept the "Place a block" packet sent from the client to the server (Packet15Place in 1.6.4) you can change the direction parameter there; if you trace through the vanilla code you should be able to track that down (but it will take a fair bit of effort I think :)  )

 

-TGG

Link to comment
Share on other sites

Thanks for the explanation, I have no clue about packets so I'll read that link. I didn't thought about the server thing, that's right though. So basically I have to get when the key is pressed, send a packet to the server so that he knows if the stair should be rotated and only then rotate the block, right?

 

Now my problem is that I want to rotate a block in a way that vanilla Minecraft hasn't conceived, I want my stair to be horizontal on a wall, Minecraft has  never thought it was even possible. So, do I have to write a custom render engine to rotate the stair and then store its rotation inside the metadata?

 

Sorry if it seems dumb to you, it's my first serious mod that I've ever released (even the other part is awful (vertical slabs that I had to use 2 different blocks, one for East/West the other for North/South because I couldn't get the direction of the player without crashing)).

 

Thanks for your answers, and again sorry for my very small knowledge.

"I an atom in the universe, a universe of atoms"-- Richard P. Feynman

Link to comment
Share on other sites

Hi

 

No worries, we all start knowing nothing about anything, great big parts of vanilla I know nothing about and I've been at this for a year now.

 

Yeah if the vanilla stair doesn't exist you'll have to write your own renderer (try ISimpleBlockRenderingHandler as a keyword) and depending on how many orientations the stair can have, you might need to use multiple blocks in addition to metadata, i.e. if there are more than 16 orientations (6 directions for the "top" * 4 rotations)

 

Sounds like you've got the right idea about the packets.  I haven't used packets in 1.7.2 yet but I'm told it's not that hard and a couple of tutorials are around.

 

-TGG

Link to comment
Share on other sites

Thanks for all the infos, I'll start looking for packet handling tutorials and render tutorials, I'll go look into vanilla code and I hope I'll do something cool. Thanks again.

"I an atom in the universe, a universe of atoms"-- Richard P. Feynman

Link to comment
Share on other sites

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.