Add better Pipe selection checking, open the gate GUI only if it has been clicked
This commit is contained in:
parent
e5c1af707f
commit
bf22970fba
1 changed files with 202 additions and 19 deletions
|
@ -21,6 +21,7 @@ import net.minecraft.block.material.Material;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
@ -42,6 +43,20 @@ import buildcraft.transport.render.PipeWorldRenderer;
|
|||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
|
||||
public class BlockGenericPipe extends BlockContainer {
|
||||
static enum Part {
|
||||
Pipe,
|
||||
Gate
|
||||
}
|
||||
|
||||
static class RaytraceResult {
|
||||
RaytraceResult(Part hitPart, MovingObjectPosition movingObjectPosition) {
|
||||
this.hitPart = hitPart;
|
||||
this.movingObjectPosition = movingObjectPosition;
|
||||
}
|
||||
|
||||
public Part hitPart;
|
||||
public MovingObjectPosition movingObjectPosition;
|
||||
}
|
||||
|
||||
/* Defined subprograms ************************************************* */
|
||||
|
||||
|
@ -213,42 +228,200 @@ public class BlockGenericPipe extends BlockContainer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public MovingObjectPosition collisionRayTrace(World world, int i, int j, int k, Vec3 vec3d, Vec3 vec3d1) {
|
||||
public MovingObjectPosition collisionRayTrace(World world, int x, int y, int z, Vec3 origin, Vec3 direction) {
|
||||
RaytraceResult raytraceResult = doRayTrace(world, x, y, z, origin, direction);
|
||||
|
||||
if (raytraceResult == null) {
|
||||
return null;
|
||||
} else {
|
||||
return raytraceResult.movingObjectPosition;
|
||||
}
|
||||
}
|
||||
|
||||
public RaytraceResult doRayTrace(World world, int x, int y, int z, EntityPlayer entityPlayer) {
|
||||
double pitch = Math.toRadians(entityPlayer.rotationPitch);
|
||||
double yaw = Math.toRadians(entityPlayer.rotationYaw);
|
||||
|
||||
double dirX = -Math.sin(yaw) * Math.cos(pitch);
|
||||
double dirY = -Math.sin(pitch);
|
||||
double dirZ = Math.cos(yaw) * Math.cos(pitch);
|
||||
|
||||
double reachDistance = 5;
|
||||
|
||||
if (entityPlayer instanceof EntityPlayerMP) {
|
||||
reachDistance = ((EntityPlayerMP) entityPlayer).theItemInWorldManager.getBlockReachDistance();
|
||||
}
|
||||
|
||||
Vec3 origin = Vec3.vec3dPool.getVecFromPool(entityPlayer.posX, entityPlayer.posY + 1.62 - entityPlayer.yOffset, entityPlayer.posZ);
|
||||
Vec3 direction = origin.addVector(dirX * reachDistance, dirY * reachDistance, dirZ * reachDistance);
|
||||
|
||||
return doRayTrace(world, x, y, z, origin, direction);
|
||||
}
|
||||
|
||||
public RaytraceResult doRayTrace(World world, int x, int y, int z, Vec3 origin, Vec3 direction) {
|
||||
float xMin = Utils.pipeMinPos, xMax = Utils.pipeMaxPos, yMin = Utils.pipeMinPos, yMax = Utils.pipeMaxPos, zMin = Utils.pipeMinPos, zMax = Utils.pipeMaxPos;
|
||||
|
||||
TileEntity tile1 = world.getBlockTileEntity(i, j, k);
|
||||
|
||||
if (Utils.checkPipesConnections(world, tile1, i - 1, j, k)) {
|
||||
TileEntity pipeTileEntity = world.getBlockTileEntity(x, y, z);
|
||||
Pipe pipe = getPipe(world, x, y, z);
|
||||
|
||||
if (pipeTileEntity == null || !isValid(pipe)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* pipe hits along x, y, and z axis, gate (all 6 sides) [and wires+facades]
|
||||
*/
|
||||
MovingObjectPosition[] hits = new MovingObjectPosition[] { null, null, null, null, null, null, null, null, null };
|
||||
|
||||
boolean needAxisCheck = false;
|
||||
boolean needCenterCheck = true;
|
||||
|
||||
// check along the x axis
|
||||
|
||||
if (Utils.checkPipesConnections(world, pipeTileEntity, x - 1, y, z)) {
|
||||
xMin = 0.0F;
|
||||
needAxisCheck = true;
|
||||
}
|
||||
|
||||
if (Utils.checkPipesConnections(world, tile1, i + 1, j, k)) {
|
||||
if (Utils.checkPipesConnections(world, pipeTileEntity, x + 1, y, z)) {
|
||||
xMax = 1.0F;
|
||||
needAxisCheck = true;
|
||||
}
|
||||
|
||||
if (needAxisCheck) {
|
||||
setBlockBounds(xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
|
||||
if (Utils.checkPipesConnections(world, tile1, i, j - 1, k)) {
|
||||
hits[0] = super.collisionRayTrace(world, x, y, z, origin, direction);
|
||||
xMin = Utils.pipeMinPos;
|
||||
xMax = Utils.pipeMaxPos;
|
||||
needAxisCheck = false;
|
||||
needCenterCheck = false; // center already checked through this axis
|
||||
}
|
||||
|
||||
// check along the y axis
|
||||
|
||||
if (Utils.checkPipesConnections(world, pipeTileEntity, x, y - 1, z)) {
|
||||
yMin = 0.0F;
|
||||
needAxisCheck = true;
|
||||
}
|
||||
|
||||
if (Utils.checkPipesConnections(world, tile1, i, j + 1, k)) {
|
||||
if (Utils.checkPipesConnections(world, pipeTileEntity, x, y + 1, z)) {
|
||||
yMax = 1.0F;
|
||||
needAxisCheck = true;
|
||||
}
|
||||
|
||||
if (needAxisCheck) {
|
||||
setBlockBounds(xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
|
||||
if (Utils.checkPipesConnections(world, tile1, i, j, k - 1)) {
|
||||
hits[1] = super.collisionRayTrace(world, x, y, z, origin, direction);
|
||||
yMin = Utils.pipeMinPos;
|
||||
yMax = Utils.pipeMaxPos;
|
||||
needAxisCheck = false;
|
||||
needCenterCheck = false; // center already checked through this axis
|
||||
}
|
||||
|
||||
// check along the z axis
|
||||
|
||||
if (Utils.checkPipesConnections(world, pipeTileEntity, x, y, z - 1)) {
|
||||
zMin = 0.0F;
|
||||
needAxisCheck = true;
|
||||
}
|
||||
|
||||
if (Utils.checkPipesConnections(world, tile1, i, j, k + 1)) {
|
||||
if (Utils.checkPipesConnections(world, pipeTileEntity, x, y, z + 1)) {
|
||||
zMax = 1.0F;
|
||||
needAxisCheck = true;
|
||||
}
|
||||
|
||||
if (needAxisCheck) {
|
||||
setBlockBounds(xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
|
||||
setBlockBounds(xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
hits[2] = super.collisionRayTrace(world, x, y, z, origin, direction);
|
||||
zMin = Utils.pipeMinPos;
|
||||
zMax = Utils.pipeMaxPos;
|
||||
needAxisCheck = false;
|
||||
needCenterCheck = false; // center already checked through this axis
|
||||
}
|
||||
|
||||
// check center (only if no axis were checked/the pipe has no connections)
|
||||
|
||||
MovingObjectPosition r = super.collisionRayTrace(world, i, j, k, vec3d, vec3d1);
|
||||
if (needCenterCheck) {
|
||||
setBlockBounds(xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
|
||||
hits[0] = super.collisionRayTrace(world, x, y, z, origin, direction);
|
||||
}
|
||||
|
||||
// gates
|
||||
|
||||
if (pipe.hasGate()) {
|
||||
for (int side = 0; side < 6; side++) {
|
||||
setBlockBoundsToGate(ForgeDirection.VALID_DIRECTIONS[side]);
|
||||
|
||||
hits[3 + side] = super.collisionRayTrace(world, x, y, z, origin, direction);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check wires, facades
|
||||
|
||||
// get closest hit
|
||||
|
||||
double minLengthSquared = Double.POSITIVE_INFINITY;
|
||||
int minIndex = -1;
|
||||
|
||||
for (int i = 0; i < hits.length; i++) {
|
||||
MovingObjectPosition hit = hits[i];
|
||||
if (hit == null) continue;
|
||||
|
||||
double lengthSquared = hit.hitVec.squareDistanceTo(origin);
|
||||
|
||||
if (lengthSquared < minLengthSquared) {
|
||||
minLengthSquared = lengthSquared;
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
// reset bounds
|
||||
|
||||
setBlockBounds(0, 0, 0, 1, 1, 1);
|
||||
|
||||
return r;
|
||||
|
||||
if (minIndex == -1) {
|
||||
return null;
|
||||
} else {
|
||||
Part hitPart;
|
||||
|
||||
if (minIndex < 3) {
|
||||
hitPart = Part.Pipe;
|
||||
} else {
|
||||
hitPart = Part.Gate;
|
||||
}
|
||||
|
||||
return new RaytraceResult(hitPart, hits[minIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
private void setBlockBoundsToGate(ForgeDirection dir) {
|
||||
float min = Utils.pipeMinPos + 0.05F;
|
||||
float max = Utils.pipeMaxPos - 0.05F;
|
||||
|
||||
switch (dir) {
|
||||
case DOWN:
|
||||
setBlockBounds(min, Utils.pipeMinPos - 0.10F, min, max, Utils.pipeMinPos, max);
|
||||
break;
|
||||
case UP:
|
||||
setBlockBounds(min, Utils.pipeMaxPos, min, max, Utils.pipeMaxPos + 0.10F, max);
|
||||
break;
|
||||
case NORTH:
|
||||
setBlockBounds(min, min, Utils.pipeMinPos - 0.10F, max, max, Utils.pipeMinPos);
|
||||
break;
|
||||
case SOUTH:
|
||||
setBlockBounds(min, min, Utils.pipeMaxPos, max, max, Utils.pipeMaxPos + 0.10F);
|
||||
break;
|
||||
case WEST:
|
||||
setBlockBounds(Utils.pipeMinPos - 0.10F, min, min, Utils.pipeMinPos, max, max);
|
||||
break;
|
||||
case EAST:
|
||||
setBlockBounds(Utils.pipeMaxPos, min, min, Utils.pipeMaxPos + 0.10F, max, max);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void removePipe(Pipe pipe) {
|
||||
|
@ -376,12 +549,12 @@ public class BlockGenericPipe extends BlockContainer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, int i, int j, int k, EntityPlayer entityplayer, int par6, float par7, float par8, float par9) {
|
||||
super.onBlockActivated(world, i, j, k, entityplayer, par6, par7, par8, par9);
|
||||
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityplayer, int par6, float xOffset, float yOffset, float zOffset) {
|
||||
super.onBlockActivated(world, x, y, z, entityplayer, par6, xOffset, yOffset, zOffset);
|
||||
|
||||
world.notifyBlocksOfNeighborChange(i, j, k, BuildCraftTransport.genericPipeBlock.blockID);
|
||||
world.notifyBlocksOfNeighborChange(x, y, z, BuildCraftTransport.genericPipeBlock.blockID);
|
||||
|
||||
Pipe pipe = getPipe(world, i, j, k);
|
||||
Pipe pipe = getPipe(world, x, y, z);
|
||||
|
||||
if (isValid(pipe)) {
|
||||
|
||||
|
@ -404,7 +577,7 @@ public class BlockGenericPipe extends BlockContainer {
|
|||
else if (entityplayer.getCurrentEquippedItem().getItem() instanceof IToolWrench)
|
||||
// Only check the instance at this point. Call the IToolWrench
|
||||
// interface callbacks for the individual pipe/logic calls
|
||||
return pipe.blockActivated(world, i, j, k, entityplayer);
|
||||
return pipe.blockActivated(world, x, y, z, entityplayer);
|
||||
else if (entityplayer.getCurrentEquippedItem().getItem() == BuildCraftTransport.redPipeWire) {
|
||||
if (!pipe.wireSet[IPipe.WireColor.Red.ordinal()]) {
|
||||
pipe.wireSet[IPipe.WireColor.Red.ordinal()] = true;
|
||||
|
@ -456,13 +629,23 @@ public class BlockGenericPipe extends BlockContainer {
|
|||
pipe.container.scheduleRenderUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean openGateGui = false;
|
||||
|
||||
if (pipe.hasGate()) {
|
||||
RaytraceResult rayTraceResult = doRayTrace(world, x, y, z, entityplayer);
|
||||
|
||||
if (rayTraceResult != null && rayTraceResult.hitPart == Part.Gate) {
|
||||
openGateGui = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (openGateGui) {
|
||||
pipe.gate.openGui(entityplayer);
|
||||
|
||||
return true;
|
||||
} else
|
||||
return pipe.blockActivated(world, i, j, k, entityplayer);
|
||||
return pipe.blockActivated(world, x, y, z, entityplayer);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue