Jump to content

Need to know where a minecart was heading before it stopped


ILuvYouCompanionCube

Recommended Posts

Entities are very complex. Is there a way for me to know to which side a minecart was heading before it stopped? I have some kind of Powered Rail (all 4 bits of my metadata are taken, 3 for directions, set by the superclass BlockRailBase and 1 for telling when it's powered).

 

This powered rail block makes the cart stop, and then go again after some time. But I'm having a hard time figuring how to make it go to the same direction it was going before. Both posXYZ and prevPosXYZ are set to the same values on every entity update.

 

I can see only 2 possible solutions, and I don't like any of them so much:

1. Adding a tile entity to my powered rail

2. using ASM to add a field to minecart.

 

Can anyone come up with a better idea, please? =/

Link to comment
Share on other sites

This is even better than what I was hoping for. I wasn't gonna care for NBT at all... Whenever the game started, if there was a minecart in one of my rail blocks I'd make it go in a random direction. And I'd even go as far as to call it a "feature" xD

 

Anyway, how do I subscribe to an event? I know I should know this one but...

Link to comment
Share on other sites

Sure. sorry the question got pushed bellow the stack xD

 

Just noticed it had a reply.

 

I'll post the entire class. I think the problem is related to onMinecartPass, because I don't know how to make it stop from being invoked by the minecart when it's stopped (off course I'd have to change some things in the implementation of my block and maybe in my implementation of ExtendedProperties if disabling onMinecartPass was possible).

 

Or maybe something related to telling the minecart stop updating entirely (don't know how to do that either. [digression]Entity is way too complex. The way minecraft codes Entity and all its inheritance hierarchy, is just awful in my opinion. Whenever I see code that needs lots of

aInstance instanceof aClass

instead of just using polymorphism, I instantly assume the author of the code isn't so smart. Minecraft force us to code this way because we're stuck with its own code).[/digression]

 

Enough rambling, here's my code (Stuff is the name of my mod, because I'm that creative):

 

package stuff.blocks;

import java.util.List;
import java.util.Random;

import pedrinholib.minecraft.DirectionXProp;
import net.minecraft.block.BlockRailBase;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.command.IEntitySelector;
import net.minecraft.entity.item.EntityMinecart;
import net.minecraft.entity.item.EntityMinecartContainer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.Icon;
import net.minecraft.world.World;
import stuff.Stuff;

public class MetaDetectorRailBlock extends BlockRailBase
{
Icon theIcon;
String assetsCommonName = Stuff.ModPrefix() + MetaDetectorRailBlock.class.getSimpleName();

public MetaDetectorRailBlock(int id)
{
	super(id, true);//true here says the rail is power related
	setUnlocalizedName(assetsCommonName);
}

        @Override
public void registerIcons(IconRegister par1IconRegister)
       {
	blockIcon = par1IconRegister.registerIcon(assetsCommonName);
	this.theIcon = par1IconRegister.registerIcon(assetsCommonName + "_powered");
}

@Override
public void updateTick(World world, int x, int y, int z, Random useless)
{
	List list = world.selectEntitiesWithinAABB(EntityMinecartContainer.class, AxisAlignedBB.getAABBPool().getAABB(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D), IEntitySelector.selectAnything);
       
	int metadata = world.getBlockMetadata(x, y, z);
	if(list.size() > 0)//at least one entity
	{
        		int powerFromNeighbours = world.getStrongestIndirectPower(x, y, z);
        		int redstoneSignalFromCart = 0;
        	
        		for(Object cart : list)//hopefully there will be only one
        		{
        			int temp = Container.calcRedstoneFromInventory((IInventory)cart);
        			if(temp > redstoneSignalFromCart)
        				redstoneSignalFromCart = temp;	
        		}
        	
        		//if the cart over the tracks has a stronger signal than the input from neighbour blocks, turn
        		//the track on
        		if(redstoneSignalFromCart > powerFromNeighbours)
        		{
        			turnOn(world, x, y, z, metadata);
        		}
        		else
        		{
        			turnOff(world, x, y, z, metadata);
        		}

        	}
        	else //there are no minecart over this track, turn it off
        	{
    			turnOff(world, x, y, z, metadata);
        	}
        
        	ScheduleUpdate(world, x, y, z);
}

@Override
public void onMinecartPass(World world, EntityMinecart cart, int x, int y, int z)
{
	if(cart instanceof IInventory)
	{
		int currentMetadata = world.getBlockMetadata(x, y, z);
		if(isOn(currentMetadata))
		{
			addVelocity(cart, currentMetadata);
		}
		else
		{
			if(registerDirection(cart))
				stopCart(cart);
		}
	}
}

public void ScheduleUpdate(World world, int x, int y, int z)
{
	world.scheduleBlockUpdate(x, y, z, this.blockID, 100);
}

/**
* Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, side, hitX, hitY, hitZ, block metadata
        */
@Override
public int onBlockPlaced(World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ, int metadata)
{
	ScheduleUpdate(world, x, y, z);
	return metadata;
}
    
/**
 * Register the directions for the cart before it stops. It returns true if the cart wasn't already stopped,
 * and false otherwise. The result can be used to avoid calling stopCart over and over again.
 * @param cart
 * @return
 */
protected boolean registerDirection(EntityMinecart cart)
{
	DirectionXProp directions = (DirectionXProp)cart.getExtendedProperties(DirectionXProp.Identifier);
	if(directions.IsStopped)
	{
		return false;
	}
	else
	{
		directions.IsStopped = true;
		if(cart.prevPosX > cart.posX)
		{
			//System.out.println("This cart is moving towards -X");
			directions.XOrientation = -1;
		}
		else if(cart.prevPosX == cart.posX)
		{
			//System.out.println("this cart is not moving along the X axis");
			directions.XOrientation = 0;
		}
		else
		{
			//System.out.println("this cart is moving towards +X");
			directions.XOrientation = +1;
		}

		if(cart.prevPosZ > cart.posZ)
		{
			//System.out.println("This cart is moving towards -Z");
			directions.ZOrientation = -1;
		}
		else if(cart.prevPosZ == cart.posZ)
		{
			//System.out.println("this cart is not moving along the Z axis");
			directions.ZOrientation = 0;
		}
		else
		{
			//System.out.println("this cart is moving towards +Z");
			directions.ZOrientation = +1;
		}

		return true;
	}
}

protected void turnOn(World world, int x, int y, int z, int metadata)
{
	if((metadata &  == 0)//equivalent to !isOn
	{
		int onStateMetadata = metadata ^ 8;

		world.setBlockMetadataWithNotify(x, y, z, onStateMetadata, 2);
		world.notifyBlocksOfNeighborChange(x, y, z, this.blockID);
	}
}

protected void turnOff(World world, int x, int y, int z, int metadata)
{
	if((metadata &  != 0)//equivalent to isOn
	{
		int offStateMetadata = metadata ^ 8;

		world.setBlockMetadataWithNotify(x, y, z, offStateMetadata, 2);
		world.notifyBlocksOfNeighborChange(x, y, z, this.blockID);
	}
}

protected boolean isOn(int metadata)
{
	return (metadata &  != 0;
}

protected void addVelocity(EntityMinecart cart, int metadata)
{
	//otherwise this will never work, since it's only called when the 8 bit is on
	metadata = metadata & 7;
	double velocityAdjustment;
	DirectionXProp directions = (DirectionXProp)cart.getExtendedProperties(DirectionXProp.Identifier);
	switch(metadata)
	{
		case 0:
		case 4:
		case 5:
			if(directions.ZOrientation > 0)
			{
				//System.out.println("Resuming movement towards +Z");
				velocityAdjustment = 0.4;
			}
			else
			{
				//System.out.println("Resuming movement towards -Z");
				velocityAdjustment = -0.4;
			}
			velocityAdjustment = cart.motionZ == 0 ? velocityAdjustment : cart.motionZ * 0.4;
			directions.IsStopped = false;
			cart.addVelocity(0, 0, velocityAdjustment);
			break;
		case 1:
		case 2:
		case 3:
			if(directions.XOrientation > 0)
			{
				//System.out.println("Resuming movement towards +X");
				velocityAdjustment = 0.4;
			}
			else
			{
				//System.out.println("Resuming movement towards -X");
				velocityAdjustment = -0.4;
			}
			velocityAdjustment = cart.motionX == 0 ? velocityAdjustment : cart.motionX * 0.4;
			directions.IsStopped = false;
			cart.addVelocity(velocityAdjustment, 0, 0);
			break;
	}
}

protected void stopCart(EntityMinecart cart)
{
	cart.setVelocity(0, 0, 0);
}
}

 

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.