Improved Dim Door Collision Detection

Improved our code for checking whether an entity in contact with a door
should be teleported. Now the check works better, works for Minecarts,
and is more readable. It also ignores particle effect entities.
This commit is contained in:
SenseiKiwi 2013-09-08 15:22:03 -04:00
parent 44b39be7b7
commit 672c19b032
2 changed files with 80 additions and 26 deletions

View file

@ -6,8 +6,10 @@ import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor; import net.minecraft.block.BlockDoor;
import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon; import net.minecraft.util.Icon;
@ -361,19 +363,38 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
@Override @Override
public void enterDimDoor(World world, int x, int y, int z, Entity entity) public void enterDimDoor(World world, int x, int y, int z, Entity entity)
{ {
int var12 = (int) (MathHelper.floor_double((double) ((entity.rotationYaw + 90) * 4.0F / 360.0F) + 0.5D) & 3); // We need to ignore particle entities
if (world.isRemote || entity instanceof EntityFX)
int orientation = world.getBlockMetadata(x, y - 1, z);
if (!world.isRemote && (orientation >= 4 && orientation <= 7) && (orientation - 4) == var12 &&
world.getBlockId(x, y - 1, z) == this.blockID)
{ {
this.onPoweredBlockChange(world, x, y, z, false); return;
}
// Check that this is the top block of the door
if (world.getBlockId(x, y - 1, z) == this.blockID)
{
int metadata = world.getBlockMetadata(x, y - 1, z);
boolean canUse = isDoorOpen(metadata);
if (canUse && entity instanceof EntityLiving)
{
// Don't check for non-living entities since it might not work right
canUse = isEntityFacingDoor(metadata, (EntityLiving) entity);
}
if (canUse)
{
// Teleport the entity through the link, if it exists
DimLink link = PocketManager.getLink(x, y, z, world.provider.dimensionId); DimLink link = PocketManager.getLink(x, y, z, world.provider.dimensionId);
if (link != null) if (link != null)
{ {
DDTeleporter.traverseDimDoor(world, link, entity); DDTeleporter.traverseDimDoor(world, link, entity);
} }
// Close the door only after the entity goes through
// so players don't have it slam in their faces.
this.onPoweredBlockChange(world, x, y, z, false);
}
}
else if (world.getBlockId(x, y + 1, z) == this.blockID)
{
enterDimDoor(world, x, y + 1, z, entity);
} }
} }
@ -382,4 +403,18 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
{ {
return this.blockID; return this.blockID;
} }
protected static boolean isDoorOpen(int metadata)
{
return (metadata & 4) != 0;
}
protected static boolean isEntityFacingDoor(int metadata, EntityLiving entity)
{
// Although any entity has the proper fields for this check,
// we should only apply it to living entities since things
// like Minecarts might come in backwards.
int direction = (int) (MathHelper.floor_double((double) ((entity.rotationYaw + 90) * 4.0F / 360.0F) + 0.5D) & 3);
return ((metadata & 3) == direction);
}
} }

View file

@ -1,9 +1,10 @@
package StevenDimDoors.mod_pocketDim.blocks; package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDProperties; import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter; import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
@ -22,23 +23,41 @@ public class TransientDoor extends BaseDimDoor
@Override @Override
public void enterDimDoor(World world, int x, int y, int z, Entity entity) public void enterDimDoor(World world, int x, int y, int z, Entity entity)
{ {
//TODO: Would it kill us to use REASONABLE variable names? <_< ~SenseiKiwi // We need to ignore particle entities
int var12 = (int) (MathHelper.floor_double((double) ((entity.rotationYaw + 90) * 4.0F / 360.0F) + 0.5D) & 3); if (world.isRemote || entity instanceof EntityFX)
int orientation = world.getBlockMetadata(x, y - 1, z);
if (!world.isRemote && orientation == var12 && world.getBlockId(x, y - 1, z) == this.blockID)
{ {
return;
}
// Check that this is the top block of the door
if (world.getBlockId(x, y - 1, z) == this.blockID)
{
boolean canUse = true;
int metadata = world.getBlockMetadata(x, y - 1, z);
if (canUse && entity instanceof EntityLiving)
{
// Don't check for non-living entities since it might not work right
canUse = BaseDimDoor.isEntityFacingDoor(metadata, (EntityLiving) entity);
}
if (canUse)
{
// Teleport the entity through the link, if it exists
DimLink link = PocketManager.getLink(x, y, z, world.provider.dimensionId); DimLink link = PocketManager.getLink(x, y, z, world.provider.dimensionId);
if (link != null) if (link != null)
{ {
DDTeleporter.traverseDimDoor(world, link, entity); DDTeleporter.traverseDimDoor(world, link, entity);
//Turn the transient door into a rift AFTER teleporting the entity. // Turn the door into a rift AFTER teleporting the player.
//The door's orientation may be needed for generating a room at the link's destination. // The door's orientation may be necessary for the teleport.
world.setBlock(x, y, z, properties.RiftBlockID); world.setBlock(x, y, z, properties.RiftBlockID);
world.setBlockToAir(x, y - 1, z); world.setBlockToAir(x, y - 1, z);
} }
} }
} }
else if (world.getBlockId(x, y + 1, z) == this.blockID)
{
enterDimDoor(world, x, y + 1, z, entity);
}
}
@Override @Override
public void placeDimDoor(World world, int x, int y, int z) public void placeDimDoor(World world, int x, int y, int z)