@Override /** Updates the blocks bounds based on its current state. Args: world, x, y, z */ public void setBlockBoundsBasedOnState(IBlockAccess blockAccess, int x, int y, int z) { if (!rayTracing) { TEBase TE = getTileEntity(blockAccess, x, y, z); if (TE != null) { int slopeID = TE.getData(); Slope slope = Slope.slopesList[slopeID]; switch (slope.getPrimaryType()) { case PRISM: case PRISM_1P: case PRISM_2P: case PRISM_3P: case PRISM_4P: if (slope.isPositive) { setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); } else { setBlockBounds(0.0F, 0.5F, 0.0F, 1.0F, 1.0F, 1.0F); } break; default: setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); break; } } } }
@Override /** Returns whether sides share faces based on sloping property and face shape. */ protected boolean shareFaces( TEBase TE_adj, TEBase TE_src, ForgeDirection side_adj, ForgeDirection side_src) { if (TE_adj.getBlockType() == this) { Slope slope_src = Slope.slopesList[TE_src.getData()]; Slope slope_adj = Slope.slopesList[TE_adj.getData()]; if (!slope_adj.hasSide(side_adj)) { return false; } else if (slope_src.getFaceBias(side_src) == slope_adj.getFaceBias(side_adj)) { return true; } else { return false; } } return super.shareFaces(TE_adj, TE_src, side_adj, side_src); }
@Override /** Alters block type. */ protected boolean onHammerRightClick(TEBase TE, EntityPlayer entityPlayer) { int slopeID = TE.getData(); Slope slope = Slope.slopesList[slopeID]; /* Transform slope to next type. */ slopeID = slope.slopeType.onHammerRightClick(slope, slopeID); TE.setData(slopeID); return true; }
@Override /** Alters block direction. */ protected boolean onHammerLeftClick(TEBase TE, EntityPlayer entityPlayer) { int slopeID = TE.getData(); Slope slope = Slope.slopesList[slopeID]; /* Cycle between slope types based on current slope. */ slopeID = slope.slopeType.onHammerLeftClick(slope, slopeID); TE.setData(slopeID); return true; }
@Override /** Checks if the block is a solid face on the given side, used by placement logic. */ public boolean isSideSolid(IBlockAccess blockAccess, int x, int y, int z, ForgeDirection side) { TEBase TE = getTileEntity(blockAccess, x, y, z); if (TE != null) { if (isBlockSolid(blockAccess, x, y, z)) { return Slope.slopesList[TE.getData()].isFaceFull(side); } } return false; }
@Override /** * Ray traces through the blocks collision from start vector to end vector returning a ray trace * hit. Args: world, x, y, z, startVec, endVec */ public MovingObjectPosition collisionRayTrace( World world, int x, int y, int z, Vec3 startVec, Vec3 endVec) { TEBase TE = getTileEntity(world, x, y, z); MovingObjectPosition finalTrace = null; if (TE != null) { Slope slope = Slope.slopesList[TE.getData()]; SlopeUtil slopeUtil = new SlopeUtil(); int numPasses = slopeUtil.getNumPasses(slope); int precision = slopeUtil.getNumBoxesPerPass(slope); rayTracing = true; /* Determine if ray trace is a hit on slope. */ for (int pass = 0; pass < numPasses; ++pass) { for (int slice = 0; slice < precision && finalTrace == null; ++slice) { float[] box = slopeUtil.genBounds(slope, slice, precision, pass); if (box != null) { setBlockBounds(box[0], box[1], box[2], box[3], box[4], box[5]); finalTrace = super.collisionRayTrace(world, x, y, z, startVec, endVec); } } if (slope.type.equals(Type.OBLIQUE_EXT)) { --precision; } } rayTracing = false; /* Determine true face hit since sloped faces are two or more shared faces. */ if (finalTrace != null) { setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); finalTrace = super.collisionRayTrace(world, x, y, z, startVec, endVec); } } return finalTrace; }
@Override /** * Adds all intersecting collision boxes to a list. (Be sure to only add boxes to the list if they * intersect the mask.) Parameters: World, X, Y, Z, mask, list, colliding entity */ public void addCollisionBoxesToList( World world, int x, int y, int z, AxisAlignedBB axisAlignedBB, List list, Entity entity) { TEBase TE = getTileEntity(world, x, y, z); if (TE != null) { AxisAlignedBB box = null; Slope slope = Slope.slopesList[TE.getData()]; SlopeUtil slopeUtil = new SlopeUtil(); int precision = slopeUtil.getNumBoxesPerPass(slope); int numPasses = slopeUtil.getNumPasses(slope); for (int pass = 0; pass < numPasses; ++pass) { for (int slice = 0; slice < precision; ++slice) { float[] dim = slopeUtil.genBounds(slope, slice, precision, pass); if (dim != null) { box = AxisAlignedBB.getBoundingBox( x + dim[0], y + dim[1], z + dim[2], x + dim[3], y + dim[4], z + dim[5]); } if (box != null && axisAlignedBB.intersectsWith(box)) { list.add(box); } } if (slope.type.equals(Type.OBLIQUE_EXT)) { --precision; } } } }
@Override public boolean rotateBlock(World world, int x, int y, int z, ForgeDirection axis) { // to correctly support archimedes' ships mod: // if Axis is DOWN, block rotates to the left, north -> west -> south -> east // if Axis is UP, block rotates to the right: north -> east -> south -> west TileEntity tile = world.getTileEntity(x, y, z); if (tile != null && tile instanceof TEBase) { TEBase cbTile = (TEBase) tile; int data = cbTile.getData(); int dataAngle = data % 4; switch (axis) { case UP: { switch (dataAngle) { case 0: { cbTile.setData(data + 3); break; } case 1: { cbTile.setData(data + 1); break; } case 2: { cbTile.setData(data - 2); break; } case 3: { cbTile.setData(data - 2); break; } } break; } case DOWN: { switch (dataAngle) { case 0: { cbTile.setData(data + 2); break; } case 1: { cbTile.setData(data + 2); break; } case 2: { cbTile.setData(data - 1); break; } case 3: { cbTile.setData(data - 3); break; } } break; } default: return false; } return true; } return false; }