Java Code Examples for net.minecraft.util.math.BlockPos#equals()

The following examples show how to use net.minecraft.util.math.BlockPos#equals() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: GTItemJackHammer.java    From GT-Classic with GNU Lesser General Public License v3.0 6 votes vote down vote up
public boolean shouldBreak(EntityPlayer playerIn, World worldIn, BlockPos originalPos, BlockPos pos) {
	if (originalPos.equals(pos)) {
		return false;
	}
	IBlockState blockState = worldIn.getBlockState(pos);
	if (blockState.getMaterial() == Material.AIR) {
		return false;
	}
	if (blockState.getMaterial().isLiquid()) {
		return false;
	}
	float blockHardness = blockState.getPlayerRelativeBlockHardness(playerIn, worldIn, pos);
	if (blockHardness == -1.0F) {
		return false;
	}
	float originalHardness = worldIn.getBlockState(originalPos).getPlayerRelativeBlockHardness(playerIn, worldIn, originalPos);
	if ((originalHardness / blockHardness) > 10.0F) {
		return false;
	}
	return true;
}
 
Example 2
Source File: BlockMetalDoor.java    From BaseMetals with GNU Lesser General Public License v2.1 6 votes vote down vote up
@Override
  public boolean onBlockActivated(final World world, final BlockPos coord, IBlockState blockstate, 
  		                        final EntityPlayer player,
                                  final EnumHand hand, ItemStack heldItem,
                                  final EnumFacing face,
  		                        final float partialX, final float partialY, final float partialZ) {
if (this.metal.getToolHarvestLevel() > 1) {
          return false;
      }
      final BlockPos pos = (blockstate.getValue(BlockDoor.HALF) == EnumDoorHalf.LOWER) ? coord : coord.down();
      final IBlockState bs = coord.equals(pos) ? blockstate : world.getBlockState(pos);
      if (bs.getBlock() != this) {
          return false;
      }
      blockstate = bs.cycleProperty(BlockDoor.OPEN);
      world.setBlockState(pos, blockstate, 2);
      world.markBlockRangeForRenderUpdate(pos, coord);
      world.playEvent(player, ((Boolean)blockstate.getValue(BlockDoor.OPEN)) ? 1003 : 1006, coord, 0);
      return true;
  }
 
Example 3
Source File: UpgradePlanting.java    From BetterChests with GNU Lesser General Public License v3.0 6 votes vote down vote up
@Override
public void update(IUpgradableBlock chest, ItemStack stack) {
	if (!UpgradeHelper.INSTANCE.isFirstUpgrade(chest, stack) || chest.getWorldObj().isRemote || !hasUpgradeOperationCost(chest)) {
		return;
	}
	int range = chest.getAmountUpgrades(stack) * 4 + 1;
	int states = UpgradeHelper.INSTANCE.getFrequencyTick(chest, stack, range * range);
	int xOffset = states % range - range / 2;
	int zOffset = states / range - range / 2;

	World world = chest.getWorldObj();
	BlockPos pos = chest.getPosition().add(xOffset, 0, zOffset);
	if (pos.equals(chest.getPosition())) {
		return;
	}
	IBlockState state = world.getBlockState(pos);
	if (state.getBlock().isReplaceable(world, pos)) {
		world.setBlockToAir(pos);
	}
	plantBlock((IBetterChest) chest, pos, stack);
}
 
Example 4
Source File: GTUtility.java    From GT-Classic with GNU Lesser General Public License v3.0 6 votes vote down vote up
public static boolean tryExplodeOtherAbsorbers(World world, BlockPos checkPos) {
	Iterable<BlockPos> surroundingPos = BlockPos.getAllInBox(checkPos.offset(EnumFacing.SOUTH, 4).offset(EnumFacing.WEST, 4), checkPos.offset(EnumFacing.NORTH, 4).offset(EnumFacing.EAST, 4));
	for (BlockPos absorberPos : surroundingPos) {
		if (absorberPos.equals(checkPos)) {
			continue;
		}
		TileEntity tile = world.getTileEntity(absorberPos);
		if (tile instanceof GTTileMagicEnergyAbsorber) {
			GTTileMagicEnergyAbsorber absorber = (GTTileMagicEnergyAbsorber) tile;
			if (absorber.portalMode && absorber.isAbovePortal) {
				world.setBlockToAir(absorberPos);
				world.removeTileEntity(absorberPos);
				world.createExplosion(null, absorberPos.getX(), absorberPos.getY(), absorberPos.getZ(), 8.0F, true);
				return true;
			}
		}
	}
	return false;
}
 
Example 5
Source File: BloodBlock.java    From the-hallow with MIT License 6 votes vote down vote up
@Override
public void onEntityCollision(BlockState blockState, World world, BlockPos pos, Entity entity) {
	if(!world.isClient) {
		if (pos.equals(entity.getBlockPos())) {
			if (entity instanceof ItemEntity && !((ItemEntity) entity).getStack().isEmpty()) {
				ItemEntity itemEntity = (ItemEntity) entity;
				ItemStack stack = itemEntity.getStack();
				if (stack.getItem() instanceof DyeableItem) {
					DyeableItem item = (DyeableItem) stack.getItem();
					if (item.hasColor(stack)) item.setColor(stack, 0xFF0000 | item.getColor(stack));
					else item.setColor(stack, 0xFF0000);

					return;
				}
			}
		}
	}

	super.onEntityCollision(blockState, world, pos, entity);
}
 
Example 6
Source File: MetaTileEntityMagicEnergyAbsorber.java    From GregTech with GNU Lesser General Public License v3.0 5 votes vote down vote up
private void updateConnectedCrystals() {
    this.connectedCrystalsIds.clear();
    final double maxDistance = 64 * 64;
    List<EntityEnderCrystal> enderCrystals = Arrays.stream(BiomeEndDecorator.getSpikesForWorld(getWorld()))
        .flatMap(endSpike -> getWorld().getEntitiesWithinAABB(EntityEnderCrystal.class, endSpike.getTopBoundingBox()).stream())
        .filter(crystal -> crystal.getDistanceSq(getPos()) < maxDistance)
        .collect(Collectors.toList());

    for (EntityEnderCrystal entityEnderCrystal : enderCrystals) {
        BlockPos beamTarget = entityEnderCrystal.getBeamTarget();
        if (beamTarget == null) {
            //if beam target is null, set ourselves as beam target
            entityEnderCrystal.setBeamTarget(getPos());
            this.connectedCrystalsIds.add(entityEnderCrystal.getEntityId());
        } else if (beamTarget.equals(getPos())) {
            //if beam target is ourselves, just add it to list
            this.connectedCrystalsIds.add(entityEnderCrystal.getEntityId());
        }
    }

    for (EntityDragon entityDragon : getWorld().getEntities(EntityDragon.class, EntitySelectors.IS_ALIVE)) {
        if (entityDragon.healingEnderCrystal != null && connectedCrystalsIds.contains(entityDragon.healingEnderCrystal.getEntityId())) {
            //if dragon is healing from crystal we draw energy from, reset it's healing crystal
            entityDragon.healingEnderCrystal = null;
            //if dragon is holding pattern, than deal damage and set it's phase to attack ourselves
            if (entityDragon.getPhaseManager().getCurrentPhase().getType() == PhaseList.HOLDING_PATTERN) {
                entityDragon.attackEntityFrom(DamageSource.causeExplosionDamage((EntityLivingBase) null), 10.0f);
                entityDragon.getPhaseManager().setPhase(PhaseList.CHARGING_PLAYER);
                ((PhaseChargingPlayer) entityDragon.getPhaseManager().getCurrentPhase()).setTarget(new Vec3d(getPos()));
            }
        }
    }
}
 
Example 7
Source File: TofuVillageCollection.java    From TofuCraftReload with MIT License 5 votes vote down vote up
private boolean positionInList(BlockPos pos) {
    for (BlockPos blockpos : this.villagerPositionsList) {
        if (blockpos.equals(pos)) {
            return true;
        }
    }

    return false;
}
 
Example 8
Source File: GTIBlockFilters.java    From GT-Classic with GNU Lesser General Public License v3.0 5 votes vote down vote up
@Override
public boolean isValidBlock(World world, BlockPos blockPos) {
	Block block = world.getBlockState(blockPos).getBlock();
	if (block == GTBlocks.tileLESU) {
		if (blockPos.equals(this.tile.getPos())) {
			return false;
		}
		TileEntity worldTile = world.getTileEntity(blockPos);
		if (worldTile instanceof GTTileMultiLESU) {
			((GTTileMultiLESU) worldTile).enabled = false;
		}
		return false;
	}
	return block == GTBlocks.casingLapotron;
}
 
Example 9
Source File: TunnellerHack.java    From ForgeWurst with GNU General Public License v3.0 5 votes vote down vote up
@Override
public void run()
{
	BlockPos player = new BlockPos(WMinecraft.getPlayer());
	KeyBinding forward = mc.gameSettings.keyBindForward;
	
	Vec3d diffVec = new Vec3d(player.subtract(start));
	Vec3d dirVec = new Vec3d(direction.getDirectionVec());
	double dotProduct = diffVec.dotProduct(dirVec);
	
	BlockPos pos1 = start.offset(direction, (int)dotProduct);
	if(!player.equals(pos1))
	{
		RotationUtils.faceVectorForWalking(toVec3d(pos1));
		KeyBindingUtils.setPressed(forward, true);
		return;
	}
	
	BlockPos pos2 = start.offset(direction, Math.max(0, length - 10));
	if(!player.equals(pos2))
	{
		RotationUtils.faceVectorForWalking(toVec3d(pos2));
		KeyBindingUtils.setPressed(forward, true);
		WMinecraft.getPlayer().setSprinting(true);
		return;
	}
	
	BlockPos pos3 = start.offset(direction, length + 1);
	RotationUtils.faceVectorForWalking(toVec3d(pos3));
	KeyBindingUtils.setPressed(forward, false);
	WMinecraft.getPlayer().setSprinting(false);
	
	if(disableTimer > 0)
	{
		disableTimer--;
		return;
	}
	
	setEnabled(false);
}
 
Example 10
Source File: RenderEventHandler.java    From enderutilities with GNU Lesser General Public License v3.0 5 votes vote down vote up
protected void updatePointedBlockHilight(World world, BlockPos pos, IBlockState state, BlockEnderUtilities block, float partialTicks)
{
    EnumFacing facing = state.getValue(block.propFacing);

    if (pos.equals(this.pointedPosLast) == false || facing != this.pointedBlockFacingLast)
    {
        block.updateBlockHilightBoxes(world, pos, facing);
        this.pointedPosLast = pos;
        this.pointedBlockFacingLast = facing;
    }

    this.partialTicks = partialTicks;
}
 
Example 11
Source File: SchematicPlacementManager.java    From litematica with GNU Lesser General Public License v3.0 5 votes vote down vote up
public void setPositionOfCurrentSelectionTo(BlockPos pos, Minecraft mc)
{
    SchematicPlacement schematicPlacement = this.getSelectedSchematicPlacement();

    if (schematicPlacement != null)
    {
        if (schematicPlacement.isLocked())
        {
            InfoUtils.showGuiOrActionBarMessage(MessageType.ERROR, "litematica.message.placement.cant_modify_is_locked");
            return;
        }

        boolean movingBox = schematicPlacement.getSelectedSubRegionPlacement() != null;

        if (movingBox)
        {
            this.moveSubRegionTo(schematicPlacement, schematicPlacement.getSelectedSubRegionName(), pos, InfoUtils.INFO_MESSAGE_CONSUMER);

            String posStr = String.format("x: %d, y: %d, z: %d", pos.getX(), pos.getY(), pos.getZ());
            InfoUtils.showGuiOrActionBarMessage(MessageType.SUCCESS, "litematica.message.placement.moved_subregion_to", posStr);
        }
        // Moving the origin point
        else
        {
            BlockPos old = schematicPlacement.getOrigin();
            this.setOrigin(schematicPlacement, pos, InfoUtils.INFO_MESSAGE_CONSUMER);

            if (old.equals(schematicPlacement.getOrigin()) == false)
            {
                String posStrOld = String.format("x: %d, y: %d, z: %d", old.getX(), old.getY(), old.getZ());
                String posStrNew = String.format("x: %d, y: %d, z: %d", pos.getX(), pos.getY(), pos.getZ());
                InfoUtils.showGuiOrActionBarMessage(MessageType.SUCCESS, "litematica.message.placement.moved_placement_origin", posStrOld, posStrNew);
            }
        }
    }
}
 
Example 12
Source File: SubRegionPlacement.java    From litematica with GNU Lesser General Public License v3.0 5 votes vote down vote up
void setPos(BlockPos pos)
{
    BlockPos newPos = PositionUtils.getModifiedPartiallyLockedPosition(this.pos, pos, this.coordinateLockMask);

    if (newPos.equals(this.pos) == false)
    {
        this.pos = newPos;
    }
    else if (pos.equals(this.pos) == false && this.coordinateLockMask != 0)
    {
        InfoUtils.showGuiOrInGameMessage(MessageType.ERROR, 2000, "litematica.error.schematic_placements.coordinate_locked");
    }
}
 
Example 13
Source File: WorldGenBigMaple.java    From Sakura_mod with MIT License 5 votes vote down vote up
/**
 * Generates additional wood blocks to fill out the bases of different leaf nodes that would otherwise degrade.
 */
void generateLeafNodeBases()
{
    for (WorldGenBigMaple.FoliageCoordinates worldgenbigtree$foliagecoordinates : this.foliageCoords)
    {
        int i = worldgenbigtree$foliagecoordinates.getBranchBase();
        BlockPos blockpos = new BlockPos(this.basePos.getX(), i, this.basePos.getZ());

        if (!blockpos.equals(worldgenbigtree$foliagecoordinates) && this.leafNodeNeedsBase(i - this.basePos.getY()))
        {
            this.limb(blockpos, worldgenbigtree$foliagecoordinates,metaWood.getBlock());
        }
    }
}
 
Example 14
Source File: WorldGenBigSakura.java    From Sakura_mod with MIT License 5 votes vote down vote up
/**
 * Generates additional wood blocks to fill out the bases of different leaf nodes that would otherwise degrade.
 */
void generateLeafNodeBases()
{
    for (WorldGenBigSakura.FoliageCoordinates worldgenbigtree$foliagecoordinates : this.foliageCoords)
    {
        int i = worldgenbigtree$foliagecoordinates.getBranchBase();
        BlockPos blockpos = new BlockPos(this.basePos.getX(), i, this.basePos.getZ());

        if (!blockpos.equals(worldgenbigtree$foliagecoordinates) && this.leafNodeNeedsBase(i - this.basePos.getY()))
        {
            this.limb(blockpos, worldgenbigtree$foliagecoordinates, BlockLoader.SAKURA_LOG);
        }
    }
}
 
Example 15
Source File: JobSetBlock.java    From CommunityMod with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void finishJob(boolean near)
{
	if (near)
	{
		IBlockState oldstate_actual = this.gnome.world.getBlockState(this.pos);
		Block oldblock_actual = oldstate_actual.getBlock();
		if (oldblock_actual == this.assign.oldblock)	// no mismatch, continue
		{
			if (!this.gnome.world.isRemote)
			{	
				// if destroying a block, need line of sight
				if (this.assign.type == EnumAssignType.DESTROY || this.assign.type == EnumAssignType.HARVEST)
				{
					// first, check if there's another block in the way
					BlockPos hitpos = WorldHelper.getTargetBlockTowards(this.gnome.world, this.gnome, this.pos);
					
					if (hitpos != null && !hitpos.equals(this.pos) && !this.gnome.world.isAirBlock(hitpos)) // if there's another block in the way, potentially break it
					{
						Block hitblock = WorldHelper.getBlock(this.gnome.world, hitpos);
						if (this.gnome.canDigBlock(hitpos))	// if can dig, break it
						{
							GnomeAssignment newAssign = new GnomeAssignment(hitpos, hitblock, Blocks.AIR, EnumAssignType.DESTROY);
							this.gnome.finishSetBlock(newAssign, true, false, false);
							this.setBlock(newAssign);
						}
						// finish the original setblock job to return it to the gnode if necessary
						this.gnome.finishSetBlock(this.assign, true, true, true);
					}
					else
					{
						// otherwise, continue
						this.gnome.finishSetBlock(this.assign, true, false, true);	
						this.setBlock(this.assign);
					}
				}
				else
				{
					this.gnome.finishSetBlock(this.assign, true, false, true);	
					this.setBlock(this.assign);
				}
			}
		}
		else	// mismatch, invalid job, return to blueprint
		{
			this.gnome.finishSetBlock(this.assign, true, true, true);
		}
	}
	else	// failed and not near yet
	{// do gnome-specific end-of-job stuff
		this.gnome.finishSetBlock(this.assign, false, false, true);
	}
}
 
Example 16
Source File: TunnellerHack.java    From Wurst7 with GNU General Public License v3.0 4 votes vote down vote up
@Override
public void run()
{
	BlockPos player = new BlockPos(MC.player.getPos());
	KeyBinding forward = MC.options.keyForward;
	
	Vec3d diffVec = Vec3d.of(player.subtract(start));
	Vec3d dirVec = Vec3d.of(direction.getVector());
	double dotProduct = diffVec.dotProduct(dirVec);
	
	BlockPos pos1 = start.offset(direction, (int)dotProduct);
	if(!player.equals(pos1))
	{
		WURST.getRotationFaker()
			.faceVectorClientIgnorePitch(toVec3d(pos1));
		forward.setPressed(true);
		return;
	}
	
	BlockPos pos2 = start.offset(direction, Math.max(0, length - 10));
	if(!player.equals(pos2))
	{
		WURST.getRotationFaker()
			.faceVectorClientIgnorePitch(toVec3d(pos2));
		forward.setPressed(true);
		MC.player.setSprinting(true);
		return;
	}
	
	BlockPos pos3 = start.offset(direction, length + 1);
	WURST.getRotationFaker().faceVectorClientIgnorePitch(toVec3d(pos3));
	forward.setPressed(false);
	MC.player.setSprinting(false);
	
	if(disableTimer > 0)
	{
		disableTimer--;
		return;
	}
	
	setEnabled(false);
}
 
Example 17
Source File: OptimizedExplosion.java    From fabric-carpet with MIT License 4 votes vote down vote up
private static void blastCalc(Explosion e){
    ExplosionAccessor eAccess = (ExplosionAccessor) e;
    if(blastChanceLocation == null || blastChanceLocation.getSquaredDistance(eAccess.getX(), eAccess.getY(), eAccess.getZ(), false) > 200) return;
    chances.clear();
    for (int j = 0; j < 16; ++j) {
        for (int k = 0; k < 16; ++k) {
            for (int l = 0; l < 16; ++l) {
                if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
                    double d0 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
                    double d1 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
                    double d2 = (double) ((float) l / 15.0F * 2.0F - 1.0F);
                    double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
                    d0 = d0 / d3;
                    d1 = d1 / d3;
                    d2 = d2 / d3;
                    float f = eAccess.getPower() * (0.7F + 0.6F);
                    double d4 = eAccess.getX();
                    double d6 = eAccess.getY();
                    double d8 = eAccess.getZ();
                    boolean found = false;

                    for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
                        BlockPos blockpos = new BlockPos(d4, d6, d8);
                        BlockState state = eAccess.getWorld().getBlockState(blockpos);
                        FluidState fluidState = eAccess.getWorld().getFluidState(blockpos);

                        if (state.getMaterial() != Material.AIR) {
                            float f2 = Math.max(state.getBlock().getBlastResistance(), fluidState.getBlastResistance());
                            if (eAccess.getEntity() != null)
                                f2 = eAccess.getEntity().getEffectiveExplosionResistance(e, eAccess.getWorld(), blockpos, state, fluidState, f2);
                            f -= (f2 + 0.3F) * 0.3F;
                        }

                        if (f > 0.0F && (eAccess.getEntity() == null ||
                                eAccess.getEntity().canExplosionDestroyBlock(e, eAccess.getWorld(), blockpos, state, f))) {
                            if(!found && blockpos.equals(blastChanceLocation)){
                                chances.add(f);
                                found = true;
                            }
                        }

                        d4 += d0 * 0.30000001192092896D;
                        d6 += d1 * 0.30000001192092896D;
                        d8 += d2 * 0.30000001192092896D;
                    }
                }
            }
        }
    }

    showTNTblastChance(e);
}
 
Example 18
Source File: PortalFormer.java    From enderutilities with GNU Lesser General Public License v3.0 4 votes vote down vote up
private EnumFacing checkFramePositionIgnoringSide(BlockPos posIn, EnumFacing ignoreSide)
{
    BlockPos pos = posIn;
    IBlockState state;
    Block block;
    EnumFacing continueTo = null;
    int frames = 0;

    if (this.visited.contains(posIn))
    {
        return null;
    }

    for (EnumFacing side : EnumFacing.values())
    {
        if (side != ignoreSide)
        {
            pos = posIn.offset(side);

            if (pos.equals(this.lastPos))
            {
                continue;
            }

            state = this.world.getBlockState(pos);
            block = state.getBlock();

            if (block.isAir(state, this.world, pos) || block == this.blockPortal)
            {
                this.checkForCorner(pos, false);

                // This is to fix single block portals not getting found via the checkForCorner() method.
                // The actual portal block count will be skewed, but it isn't used for anything other than a "> 0" check anyway.
                if (block == this.blockPortal)
                {
                    this.portalsFound++;
                }
            }
            else if (block == this.blockFrame)
            {
                if (this.visited.contains(pos) == false)
                {
                    if (frames == 0)
                    {
                        continueTo = side;
                    }
                    else
                    {
                        this.branches.add(pos);
                    }
                }
                frames++;
            }
        }
    }

    this.visited.add(posIn);
    this.lastPos = posIn;

    return continueTo;
}
 
Example 19
Source File: PortalFormer.java    From enderutilities with GNU Lesser General Public License v3.0 4 votes vote down vote up
private boolean walkFrameLoop(BlockPos pos, EnumFacing.Axis axis, EnumFacing frameSide, int distanceLimit)
{
    int counter = 0;
    int turns = 0;
    int tries = 0;
    IBlockState state;
    Block block;
    BlockPos startPos = pos;
    BlockPos posLast = startPos;
    EnumFacing firstTrySide = frameSide;
    EnumFacing moveDirection = frameSide;

    while (counter < distanceLimit)
    {
        moveDirection = firstTrySide;

        for (tries = 0; tries < 4; tries++)
        {
            pos = posLast.offset(moveDirection);
            state = this.world.getBlockState(pos);
            block = state.getBlock();

            if (block.isAir(state, this.world, pos))
            {
                posLast = pos;

                // The firstTrySide is facing into the adjacent portal frame when traveling
                // along a straight frame. Thus we need to rotate it once to keep going straight.
                // If we need to rotate it more than once, then we have hit a "right hand corner".
                if (tries > 1)
                {
                    turns++;
                }
                // If we didn't have to rotate the firstTrySide at all, then we hit a "left hand turn"
                // ie. traveled through an outer bend.
                else if (tries == 0)
                {
                    turns--;
                }

                // Set the firstTrySide one rotation back from the side that we successfully moved to
                // so that we can go around possible outer bends.
                firstTrySide = moveDirection.rotateAround(axis).getOpposite();

                break;
            }
            // Found a portal frame block, try the next adjacent side...
            else if (block == this.blockFrame)
            {
                moveDirection = moveDirection.rotateAround(axis);
            }
            // Found a non-air, non-portal-frame block -> invalid area.
            else
            {
                return false;
            }
        }

        // If we can return to the starting position hugging the portal frame,
        // then this is a valid portal frame loop.
        // Note that it is only valid if it forms an inside area, thus the turns check.
        // the tries == 4 && counter == 0 check is for a 1x1 area special case
        if ((tries == 4 && counter == 0) || pos.equals(startPos))
        {
            return turns >= 0;
        }

        counter++;
    }

    return false;
}
 
Example 20
Source File: ItemRelayWire.java    From Valkyrien-Skies with Apache License 2.0 4 votes vote down vote up
@Override
public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos,
    EnumHand hand,
    EnumFacing facing, float hitX, float hitY, float hitZ) {
    IBlockState clickedState = worldIn.getBlockState(pos);
    Block block = clickedState.getBlock();
    TileEntity currentTile = worldIn.getTileEntity(pos);
    ItemStack stack = player.getHeldItem(hand);

    if (currentTile instanceof IVSNodeProvider && !worldIn.isRemote) {
        ICapabilityLastRelay inst = stack
            .getCapability(ValkyrienSkiesControl.lastRelayCapability, null);
        if (inst != null) {
            if (!inst.hasLastRelay()) {
                inst.setLastRelay(pos);
                // Draw a wire in the player's hand after this
            } else {
                BlockPos lastPos = inst.getLastRelay();
                double distanceSq = lastPos.distanceSq(pos);
                TileEntity lastPosTile = worldIn.getTileEntity(lastPos);
                // System.out.println(lastPos.toString());

                if (!lastPos.equals(pos) && lastPosTile != null && currentTile != null) {
                    if (distanceSq < VSConfig.relayWireLength * VSConfig.relayWireLength) {
                        IVSNode lastPosNode = ((IVSNodeProvider) lastPosTile).getNode();
                        IVSNode currentPosNode = ((IVSNodeProvider) currentTile).getNode();
                        if (lastPosNode != null && currentPosNode != null) {
                            if (currentPosNode.isLinkedToNode(lastPosNode)) {
                                player.sendMessage(
                                    new TextComponentString("These nodes are already linked!"));
                            } else if (currentPosNode.canLinkToOtherNode(lastPosNode)) {
                                currentPosNode.makeConnection(lastPosNode);
                                stack.damageItem(1, player);
                            } else {
                                // Tell the player what they did wrong
                                player.sendMessage(new TextComponentString(TextFormatting.RED +
                                    I18n.format("message.vs_control.error_relay_wire_limit", VSConfig.networkRelayLimit)));
                            }
                            inst.setLastRelay(null);
                        }
                    } else {
                        player.sendMessage(
                            new TextComponentString(TextFormatting.RED +
                                I18n.format("message.vs_control.error_relay_wire_length")));
                        inst.setLastRelay(null);
                    }
                } else {
                    inst.setLastRelay(pos);
                }
            }
        }
    }

    if (currentTile instanceof IVSNodeProvider) {
        return EnumActionResult.SUCCESS;
    }

    return EnumActionResult.PASS;
}