/* * CraftBook Copyright (C) 2010-2017 sk89q <http://www.sk89q.com> * CraftBook Copyright (C) 2011-2017 me4502 <http://www.me4502.com> * CraftBook Copyright (C) Contributors * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program. If not, * see <http://www.gnu.org/licenses/>. */ package com.sk89q.craftbook.sponge.util; import com.sk89q.craftbook.core.util.RegexUtil; import org.spongepowered.api.Sponge; import org.spongepowered.api.block.tileentity.TileEntity; import org.spongepowered.api.item.inventory.Carrier; import org.spongepowered.api.item.inventory.Inventory; import org.spongepowered.api.util.Direction; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; import java.util.Optional; public class LocationUtil { /** * Gets an Inventory from a location. * * @param location The location to look for inventories at. * @return An inventory, if present. */ public static Optional<Inventory> getInventoryForLocation(Location location) { Inventory inventory = null; if(location.hasTileEntity()) { TileEntity tileEntity = (TileEntity) location.getTileEntity().get(); if(tileEntity instanceof Carrier) { inventory = ((Carrier) tileEntity).getInventory(); } } return Optional.ofNullable(inventory); } public static boolean isLocationWithinWorld(Location location) { return location.getBlockY() < location.getExtent().getBlockMax().getY() && location.getBlockY() >= location.getExtent().getBlockMin().getY(); } public static Location<World> locationFromString(String string) { String[] parts = RegexUtil.COMMA_PATTERN.split(string); if(parts.length < 4) return null; World world = Sponge.getGame().getServer().getWorld(parts[0]).orElse(null); if(world == null) return null; double x = Double.parseDouble(parts[1]); double y = Double.parseDouble(parts[2]); double z = Double.parseDouble(parts[3]); return world.getLocation(x, y, z); } /** * Gets the offset of the blocks location based on the coordiante grid. * * @param block to get offsetfrom * @param offsetX to add * @param offsetY to add * @param offsetZ to add * * @return block offset by given coordinates */ public static Location<World> getOffset(Location<World> block, int offsetX, int offsetY, int offsetZ) { return block.getExtent().getLocation(block.getX() + offsetX, block.getY() + offsetY, block.getZ() + offsetZ); } public static Location<World> getRelativeOffset(Location<World> block, int offsetX, int offsetY, int offsetZ) { return getRelativeOffset(SignUtil.getBackBlock(block), SignUtil.getFacing(block), offsetX, offsetY, offsetZ); } /** * Gets the block located relative to the signs front. That means that when the sign is attached to a block and * the player is looking at it it * will add the offsetX to left or right, offsetY is added up or down and offsetZ is added front or back. * * @param block to get relative position from * @param front to work with * @param offsetX amount to move left(negative) or right(positive) * @param offsetY amount to move up(positive) or down(negative) * @param offsetZ amount to move back(negative) or front(positive) * * @return block located at the relative offset position */ public static Location<World> getRelativeOffset(Location<World> block, Direction front, int offsetX, int offsetY, int offsetZ) { Direction back; Direction right; Direction left; switch (front) { case SOUTH: back = Direction.NORTH; left = Direction.EAST; right = Direction.WEST; break; case WEST: back = Direction.EAST; left = Direction.SOUTH; right = Direction.NORTH; break; case NORTH: back = Direction.SOUTH; left = Direction.WEST; right = Direction.EAST; break; case EAST: back = Direction.WEST; left = Direction.NORTH; right = Direction.SOUTH; break; default: back = Direction.SOUTH; left = Direction.EAST; right = Direction.WEST; } // apply left and right offset if (offsetX > 0) { block = getRelativeBlock(block, right, offsetX); } else if (offsetX < 0) { block = getRelativeBlock(block, left, offsetX); } // apply front and back offset if (offsetZ > 0) { block = getRelativeBlock(block, front, offsetZ); } else if (offsetZ < 0) { block = getRelativeBlock(block, back, offsetZ); } // apply up and down offset if (offsetY > 0) { block = getRelativeBlock(block, Direction.UP, offsetY); } else if (offsetY < 0) { block = getRelativeBlock(block, Direction.DOWN, offsetY); } return block; } /** * Get relative block X that way. * * @param block The location * @param facing The direction * @param amount The amount * * @return The block */ private static Location<World> getRelativeBlock(Location<World> block, Direction facing, int amount) { amount = Math.abs(amount); for (int i = 0; i < amount; i++) { block = block.getRelative(facing); } return block; } public static String stringFromLocation(Location<World> location) { return location.getExtent().getName() + ',' + location.getPosition().getX() + ',' + location.getPosition().getY() + ',' + location.getPosition().getZ(); } }