private double calcDiagonalLength() { double length = 0.0; // Count the amount of zig-zagging curved tracks final BlockFace[] toCheck; if (this.instruction == BlockFace.SELF) { toCheck = new BlockFace[] { FaceUtil.rotate(this.railDirection, -2), FaceUtil.rotate(this.railDirection, 2) }; } else { toCheck = new BlockFace[] {this.instruction}; } for (BlockFace direction : toCheck) { double tlength = 0.0; // Find out the starting offset final BlockFace[] dirs = FaceUtil.getFaces(direction); BlockFace[] railDirs = FaceUtil.getFaces(this.railDirection); BlockFace railDirection = this.railDirection; Block b = this.railsBlock; for (int i = 0; i < 20; i++) { // Invert the direction railDirection = railDirection.getOppositeFace(); railDirs[0] = railDirs[0].getOppositeFace(); railDirs[1] = railDirs[1].getOppositeFace(); // Obtain the new offset final BlockFace offset; if (LogicUtil.contains(railDirs[0], dirs)) { offset = railDirs[0]; } else { offset = railDirs[1]; } // Check if the new block is the expected curve direction b = b.getRelative(offset); Rails rr = BlockUtil.getRails(b); if (rr == null || rr.getDirection() != railDirection) { break; } tlength += MathUtil.HALFROOTOFTWO; } // Update the length if (tlength > length) { length = tlength; } } return length; }
private double calcHorizontalLength() { double length = 0.0; // Count the amount of horizontal tracks final BlockFace[] toCheck; if (this.instruction == BlockFace.SELF) { toCheck = FaceUtil.getFaces(this.railDirection); } else { toCheck = new BlockFace[] {this.instruction}; } for (BlockFace face : toCheck) { int tlength = 0; // Get the type of rail required BlockFace checkface = face; if (checkface == BlockFace.NORTH) checkface = BlockFace.SOUTH; if (checkface == BlockFace.EAST) checkface = BlockFace.WEST; Block b = this.railsBlock; for (int i = 0; i < 20; i++) { // Next until invalid b = b.getRelative(face); Rails rr = BlockUtil.getRails(b); if (rr == null || rr.getDirection() != checkface) { break; } tlength++; } // Update the length if (tlength > length) { length = tlength; } } return length; }
@SuppressWarnings("rawtypes") public static MinecartMember getAt(World world, ChunkCoordinates coord, boolean checkmoving) { net.minecraft.server.Chunk chunk = WorldUtil.getChunk(world, coord.x >> 4, coord.z >> 4); if (chunk != null) { MinecartMember mm; MinecartMember result = null; for (List list : chunk.entitySlices) { for (Object e : list) { if (e instanceof MinecartMember) { mm = (MinecartMember) e; if (mm.getBlockX() != coord.x) continue; if (mm.getBlockY() != coord.y) continue; if (mm.getBlockZ() != coord.z) continue; result = mm; if (result.isHeadingTo(coord)) return result; } } } if (result == null && checkmoving) { Block b = world.getWorld().getBlockAt(coord.x, coord.y, coord.z); int id = b.getTypeId(); // get the two connected rails to check if (BlockUtil.isRails(id)) { BlockFace[] possible = FaceUtil.getFaces(BlockUtil.getRails(b).getDirection()); MinecartMember mm1 = getAt(Util.getRailsBlock(b.getRelative(possible[0])), false); MinecartMember mm2 = getAt(Util.getRailsBlock(b.getRelative(possible[1])), false); if (mm1 != null && mm2 != null && mm1.group == mm2.group) { Location loc = b.getLocation(); return mm1.distance(loc) < mm2.distance(loc) ? mm1 : mm2; } else if (isHeadingTo(mm1, coord)) { return mm1; } else if (isHeadingTo(mm2, coord)) { return mm2; } else { return null; } } else if (Util.isPressurePlate(id)) { // check all directions MinecartMember mm1 = getAt(Util.getRailsBlock(b.getRelative(BlockFace.NORTH)), false); MinecartMember mm2 = getAt(Util.getRailsBlock(b.getRelative(BlockFace.SOUTH)), false); MinecartMember mm3 = getAt(Util.getRailsBlock(b.getRelative(BlockFace.EAST)), false); MinecartMember mm4 = getAt(Util.getRailsBlock(b.getRelative(BlockFace.WEST)), false); if (mm1 != null && mm2 != null && mm1.group == mm2.group) { Location loc = b.getLocation(); return mm1.distance(loc) < mm2.distance(loc) ? mm1 : mm2; } else if (mm3 != null && mm4 != null && mm3.group == mm4.group) { Location loc = b.getLocation(); return mm3.distance(loc) < mm4.distance(loc) ? mm3 : mm4; } else if (isHeadingTo(mm1, coord)) { return mm1; } else if (isHeadingTo(mm2, coord)) { return mm2; } else if (isHeadingTo(mm3, coord)) { return mm3; } else if (isHeadingTo(mm4, coord)) { return mm4; } else { return null; } } } return result; } return null; }
public Station(SignActionEvent info) { this.delay = ParseUtil.parseTime(info.getLine(2)); this.nextDirection = Direction.parse(info.getLine(3)); this.centerCart = info.isCartSign() ? info.getMember() : info.getGroup().middle(); this.railsBlock = info.getRails(); // Vertical or horizontal rail logic if (info.isVerticalRails()) { this.railDirection = BlockFace.DOWN; // Up, down or center based on redstone power boolean up = info.isPowered(BlockFace.UP); boolean down = info.isPowered(BlockFace.DOWN); if (up && !down) { this.instruction = BlockFace.UP; } else if (!up && down) { this.instruction = BlockFace.DOWN; } else if (info.isPowered()) { this.instruction = BlockFace.SELF; } else { this.instruction = null; } } else { this.railDirection = info.getRailDirection(); if (FaceUtil.isSubCardinal(this.railDirection) && FaceUtil.isSubCardinal(info.getFacing())) { // Sub-cardinal checks: Both directions have two possible powered sides BlockFace[] faces = FaceUtil.getFaces(this.railDirection); boolean pow1 = info.isPowered(faces[0]) || info.isPowered(faces[1].getOppositeFace()); boolean pow2 = info.isPowered(faces[1]) || info.isPowered(faces[0].getOppositeFace()); if (pow1 && !pow2) { this.instruction = FaceUtil.combine(faces[0], faces[1].getOppositeFace()); } else if (!pow1 && pow2) { this.instruction = FaceUtil.combine(faces[0].getOppositeFace(), faces[1]); } else if (info.isPowered()) { this.instruction = BlockFace.SELF; } else { this.instruction = null; } } else { // Which directions to move, or brake? if (this.railDirection == BlockFace.WEST) { boolean west = info.isPowered(BlockFace.WEST); boolean east = info.isPowered(BlockFace.EAST); if (west && !east) { this.instruction = BlockFace.WEST; } else if (east && !west) { this.instruction = BlockFace.EAST; } else if (info.isPowered()) { this.instruction = BlockFace.SELF; } else { this.instruction = null; } } else if (this.railDirection == BlockFace.SOUTH) { boolean north = info.isPowered(BlockFace.NORTH); boolean south = info.isPowered(BlockFace.SOUTH); if (north && !south) { this.instruction = BlockFace.NORTH; } else if (south && !north) { this.instruction = BlockFace.SOUTH; } else if (info.isPowered()) { this.instruction = BlockFace.SELF; } else { this.instruction = null; } } else { this.length = 0.0; this.instruction = null; this.valid = false; return; } } } // Get initial station length, delay and direction double length = ParseUtil.parseDouble(info.getLine(1).substring(7), 0.0); if (length == 0.0 && this.instruction != null) { // Manually calculate the length // Use the amount of straight blocks if (info.isVerticalRails()) { length = this.calcVerticalLength(); } else if (FaceUtil.isSubCardinal(this.railDirection)) { length = this.calcDiagonalLength(); } else { length = this.calcHorizontalLength(); } if (length == 0.0) { length++; } } this.length = length; this.valid = true; }