Southeast direction incorrect

I am having a strange issue trying to use Direction.SOUTHEAST to get a relative block. Here is the only code being ran on the server:

@Listener
public void onInteract(InteractBlockEvent event, @First Player player) {
    Location<World> loc = event.getTargetBlock().getLocation().get();

    System.out.println(loc.getRelative(Direction.SOUTHEAST).getBlock().getName());
    System.out.println(loc.getRelative(Direction.SOUTH).getRelative(Direction.EAST).getBlock().getName());
}

The two lines print different block types, when they should be identical. Direction.SOUTHEAST seems to display the block being clicked on, whereas the second line prints the correct block.

Here are the blocks being tested:

S S S
S Q S
S S S

S = Stone Brick
Q = Quartz Block

I am clicking on the quartz block in the center. My code prints that the block Direction.SOUTHEAST of the quartz is a quartz block, however it is clearly a stone brick. Is this a Sponge bug, or I am doing something incorrectly?

Is the diagram you’ve given when facing down towards y=0, or towards the horizon?

the north/south/east/west cardinals point along the x and z axes, the UP and DOWN point, well, up and down.

It is from the perspective of someone looking down onto the blocks. Sorry I didn’t clarify that.

You could debug print the coordinates of the relative blocks to check where this location points at. I think there is something going on with decimals, so print the double values of the coordinates.

Okay, so peeking at the Location file, we see that get block position uses .toInt on its position to get the block position. toInt floors valued (rounds them down, eg. floor(1.9) = 1), and that’s the source of your problem. Instead, get the Vector3d from the location, call .round on it, then call toInt.

I had some “fun” with this while I tested out world generation… :slight_smile:

So I can not use Directions to accomplish this, but instead add to the Vector3d?

No, you can still do what you’re doing, but replace .getBlock() with .getPosition and then use the resultant position to get the block, so something like:

Location<World> loc = event.getTargetBlock().getLocation().get();
System.out.println(loc.getExtent().getBlock(loc.getRelative(Direction.SOUTHEAST).getPosistion().round().toInt()).getName());
System.out.println(loc.getExtent().getBlock(loc.getRelative(Direction.SOUTH).getRelative(Direction.EAST).getPosistion.round().toInt()).getName());

Oh I see, I’ll try it out. Thanks!

Would you consider this a Sponge bug, as Direction.SOUTHEAST is not doing what it is intended to do?

Well, yes I would, but it’s not Direction.SOUTHEAST's fault. The Directions are all ‘directional vectors’ (see here). I think the problem is that getBlockPosistion uses .toInt() and not .round().

1 Like

Opened an issue: Add support for ordinal block offsets in Direction enum · Issue #1291 · SpongePowered/SpongeAPI · GitHub
Suggested fix: Add support for ordinal block offsets in Direction by DDoS · Pull Request #1293 · SpongePowered/SpongeAPI · GitHub

2 Likes