public Map<EnumFacing, TileEntitySignalBase> getSignals(){ if(signals == null) { EnumRailDirection railDir = rail.getDirection(world, this, state); if(isStraightTrack(railDir) && getNeighbors().size() <= 2) { for(EnumFacing d : getDirections(railDir)) { d = d.rotateY(); //Check for signals perpendicular to the rail direction TileEntity te = world.getTileEntity(offset(d)); if(te instanceof TileEntitySignalBase) { TileEntitySignalBase signal = (TileEntitySignalBase)te; if(signal.getNeighborPos().equals(this)) { if(signals == null) signals = new HashMap<>(1); //Be conservative with instantiating, as not many rails usually have a signal. signals.put(d, signal); } } } } if(signals == null) signals = Collections.emptyMap(); } return signals; }
private Map<EnumFacing, Map<RailWrapper, EnumFacing>> calculateExitsForEntries(EnumSet<EnumRailDirection> validRailDirs){ Map<EnumFacing, Map<RailWrapper, EnumFacing>> exitsForEntries = new HashMap<>(); //Evaluate every neighbor dir for(EnumFacing entry : allNeighbors.values()) { Map<RailWrapper, EnumFacing> exitsForEntry = new HashMap<>(6); exitsForEntries.put(entry.getOpposite(), exitsForEntry); //Check if that neighbor dir is part of a EnumRailDir, if so it's a valid entry/exit path for(EnumRailDirection railDir : validRailDirs) { EnumSet<EnumFacing> railDirDirs = getDirections(railDir); if(railDirDirs.contains(entry)) { //If found, put all the rail dir entries in the result set for(Map.Entry<RailWrapper, EnumFacing> neighbor : allNeighbors.entrySet()) { if(neighbor.getValue() == EnumFacing.DOWN || railDirDirs.contains(neighbor.getValue())) { exitsForEntry.put(neighbor.getKey(), neighbor.getValue()); } } } } } return exitsForEntries; }
private static EnumSet<EnumFacing> getDirections(EnumRailDirection railDir){ switch(railDir){ case NORTH_SOUTH: case ASCENDING_NORTH: case ASCENDING_SOUTH: return EnumSet.of(EnumFacing.NORTH, EnumFacing.SOUTH); case EAST_WEST: case ASCENDING_EAST: case ASCENDING_WEST: return EnumSet.of(EnumFacing.EAST, EnumFacing.WEST); case SOUTH_EAST: return EnumSet.of(EnumFacing.SOUTH, EnumFacing.EAST); case SOUTH_WEST: return EnumSet.of(EnumFacing.SOUTH, EnumFacing.WEST); case NORTH_WEST: return EnumSet.of(EnumFacing.NORTH, EnumFacing.WEST); case NORTH_EAST: return EnumSet.of(EnumFacing.NORTH, EnumFacing.EAST); default: return EnumSet.noneOf(EnumFacing.class); } }
/** * All the neighbors of this rail, used in determining which rails are part of a block. * For junction rails this would include all north, south east and west. * @return */ public Map<RailWrapper, EnumFacing> getNeighbors(){ if(allNeighbors == null) { EnumSet<EnumRailDirection> validRailDirs = rail.getValidDirections(world, this, state); this.allNeighbors = calculateAllNeighbors(validRailDirs); this.exitsForEntries = calculateExitsForEntries(validRailDirs); } return allNeighbors; }
private static int getHeightOffset(EnumRailDirection railDir, EnumFacing dir){ switch(railDir){ case ASCENDING_EAST: return dir == EnumFacing.EAST ? 1 : 0; case ASCENDING_WEST: return dir == EnumFacing.WEST ? 1 : 0; case ASCENDING_NORTH: return dir == EnumFacing.NORTH ? 1 : 0; case ASCENDING_SOUTH: return dir == EnumFacing.SOUTH ? 1 : 0; default: return 0; } }
private static boolean isStraightTrack(EnumRailDirection railDir){ switch(railDir){ case NORTH_SOUTH: case ASCENDING_NORTH: case ASCENDING_SOUTH: case EAST_WEST: case ASCENDING_EAST: case ASCENDING_WEST: return true; default: return false; } }
/** * Makes it so when a player right clicks a rail block with a different rail item, it will be replaced, without having to remove and place a rail. * @param e */ @SubscribeEvent public void onBlockInteraction(RightClickBlock e){ if(!e.getWorld().isRemote && e.getFace() == EnumFacing.UP) { ItemStack stack = e.getEntityPlayer().getHeldItemMainhand(); BlockRailBase railBlock = getRailBlock(stack); if(railBlock != null) { IBlockState state = e.getWorld().getBlockState(e.getPos()); IRail rail = RailManager.getInstance().getRail(e.getWorld(), e.getPos(), state); if(rail != null && state.getBlock() != railBlock) { EnumRailDirection dir = rail.getDirection(e.getWorld(), e.getPos(), state); e.getWorld().destroyBlock(e.getPos(), !e.getEntityPlayer().isCreative()); List<EntityItem> drops = e.getWorld().getEntitiesWithinAABB(EntityItem.class, new AxisAlignedBB(e.getPos())); for(EntityItem drop : drops) { drop.setPickupDelay(0); drop.onCollideWithPlayer(e.getEntityPlayer()); } e.getWorld().setBlockState(e.getPos(), railBlock.getDefaultState()); if(!e.getEntityPlayer().isCreative()) stack.shrink(1); //Set the rail orientation equal to the old rail, if possible. if(railBlock.getShapeProperty().getAllowedValues().contains(dir)) { IBlockState curState = e.getWorld().getBlockState(e.getPos()); e.getWorld().setBlockState(e.getPos(), curState.withProperty(railBlock.getShapeProperty(), dir)); } } } } }
protected void updateSwitches(AStarRailNode pathNode, EntityMinecart cart, boolean submitMessages){ List<PacketUpdateMessage> messages = new ArrayList<>(); EnumFacing lastHeading = pathNode.getPathDir(); while(pathNode != null) { Map<RailWrapper, EnumFacing> neighbors = pathNode.getRail().getNeighborsForEntryDir(lastHeading); EnumFacing heading = pathNode.getNextNode() != null ? neighbors.get(pathNode.getNextNode().getRail()) : null; if(neighbors.size() > 2 && heading != null && lastHeading != null) { //If on an intersection EnumRailDirection railDir = RailWrapper.getRailDir(EnumSet.of(heading, lastHeading.getOpposite())); String[] args = {Integer.toString(pathNode.getRail().getX()), Integer.toString(pathNode.getRail().getY()), Integer.toString(pathNode.getRail().getZ()), "signals.dir." + lastHeading.toString().toLowerCase(), "signals.dir." + heading.toString().toLowerCase()}; if(pathNode.getRail().setRailDir(railDir)) { messages.add(new PacketUpdateMessage(this, cart, "signals.message.changing_junction", args)); } else { messages.add(new PacketUpdateMessage(this, cart, "signals.message.changing_junction", args)); } } lastHeading = heading; pathNode = pathNode.getNextNode(); if(pathNode != null && heading != null && getNeighborSignal(pathNode.getRail(), heading.getOpposite()) != null) { break; } } if(submitMessages) { for(PacketUpdateMessage message : messages) { NetworkHandler.sendToAllAround(message, getWorld()); } } }
public EnumFacing getFacing(IBlockState state) { if (state.getBlock() == Blocks.ACTIVATOR_RAIL) { EnumRailDirection dir = state.getValue(BlockRailPowered.SHAPE); switch (dir) { case ASCENDING_EAST: return EnumFacing.EAST; case ASCENDING_NORTH: return EnumFacing.NORTH; case ASCENDING_SOUTH: return EnumFacing.SOUTH; case ASCENDING_WEST: return EnumFacing.WEST; case EAST_WEST: return EnumFacing.NORTH; case NORTH_EAST: return EnumFacing.SOUTH; case NORTH_SOUTH: return EnumFacing.WEST; case NORTH_WEST: return EnumFacing.EAST; case SOUTH_EAST: return EnumFacing.NORTH; case SOUTH_WEST: return EnumFacing.EAST; default: break; } } return EnumFacing.NORTH; }
@Override public EnumRailDirection getDirection(World world, BlockPos pos, IBlockState state){ return state.getValue(((BlockRailBase)state.getBlock()).getShapeProperty()); }
@Override public EnumSet<EnumRailDirection> getValidDirections(World world, BlockPos pos, IBlockState state){ return EnumSet.copyOf(((BlockRailBase)state.getBlock()).getShapeProperty().getAllowedValues()); }
@Override public void setDirection(World world, BlockPos pos, IBlockState originalState, EnumRailDirection railDir){ world.setBlockState(pos, originalState.withProperty(((BlockRailBase)originalState.getBlock()).getShapeProperty(), railDir), 2); }
public boolean setRailDir(EnumRailDirection railDir){ boolean valid = rail.getValidDirections(world, this, state).contains(railDir); if(valid) rail.setDirection(world, this, state, railDir); return valid; }
public static EnumRailDirection getRailDir(EnumSet<EnumFacing> facings){ return DIRS_TO_RAIL_DIR.get(facings); }
public boolean apply(EnumRailDirection direction) { return direction == EnumRailDirection.NORTH_SOUTH || direction == EnumRailDirection.EAST_WEST; }
/** * Should return the current rail orientation, for the given position and state. * @param world * @param pos * @param state * @return */ public EnumRailDirection getDirection(World world, BlockPos pos, IBlockState state);
/** * The valid directions this rail can be _set_ to. Any element returned here should be allowed to be passed in setDirection * @param world * @param pos * @param state * @return */ public EnumSet<EnumRailDirection> getValidDirections(World world, BlockPos pos, IBlockState state);
/** * Should set the rail to the given railDir. * @param world * @param pos * @param originalState * @param railDir */ public void setDirection(World world, BlockPos pos, IBlockState originalState, EnumRailDirection railDir);