Package com.sk89q.craftbook.util

Source Code of com.sk89q.craftbook.util.SignUtil

// $Id$
/*
* CraftBook Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* 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.util;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.event.block.SignChangeEvent;

import com.sk89q.craftbook.bukkit.util.BukkitUtil;

/**
* <p>
* Convenience methods for dealing with some sign block data.
* </p>
* <p>
* If you intend to care about the eight further directions (as opposed to the four cardinal directions and the four
* ordinal directions), this isn't
* for you -- since BlockFace has no such directions, those will be rounded to the nearest ordinal direction. (If the
* term "further direction"
* confuses you, see https://secure.wikimedia.org/wikipedia/en/wiki/Cardinal_directions).
* </p>
* <p>
* This is direly close to being a replicate of things you can access via org.bukkit.material.Sign (which extends
* MaterialData). However, that thing:
* <ul>
* <li>doesn't provide the relative direction methods.
* <li>rounds the further divisions to cardinal/ordinal differently (and wrong, in my book).
* <li>has the same class name for that MaterialData thing as the BlockState, which is annoying as hell import-wise.
* <li>requires allocating an object and copying two bytes in a fashion that I consider kinda unnecessary.
* </ul>
* Ideally, I think I'd like to see if I can get something like these methods pushed to bukkit.
* </p>
*
* @author hash
*/
public class SignUtil {

    public static boolean isSign(Block block) {

        return block.getType() == Material.SIGN_POST || block.getType() == Material.WALL_SIGN;
    }

    /**
     * @param sign treated as sign post if it is such, or else assumed to be a wall sign (i.e.,
     *             if you ask about a stone block, it's considered a wall
     *             sign).
     *
     * @return the direction a player would be facing when reading the sign; i.e. the face that is actually the back
     *         side of the sign.
     */
    public static BlockFace getFacing(Block sign) {

        return getBack(sign);
    }

    /**
     * @param sign treated as sign post if it is such, or else assumed to be a wall sign (i.e.,
     *             if you ask about a stone block, it's considered a wall
     *             sign).
     *
     * @return the side of the sign containing the text (in other words, when a player places a new sign,
     *         while facing north, this will return south).
     */
    public static BlockFace getFront(Block sign) {

        if (sign.getType() == Material.SIGN_POST) {
            switch (sign.getData()) {
                case 0x0:
                    return BlockFace.SOUTH;
                case 0x1:
                case 0x2:
                case 0x3:
                    return BlockFace.SOUTH_WEST;
                case 0x4:
                    return BlockFace.WEST;
                case 0x5:
                case 0x6:
                case 0x7:
                    return BlockFace.NORTH_WEST;
                case 0x8:
                    return BlockFace.NORTH;
                case 0x9:
                case 0xA:
                case 0xB:
                    return BlockFace.NORTH_EAST;
                case 0xC:
                    return BlockFace.EAST;
                case 0xD:
                case 0xE:
                case 0xF:
                    return BlockFace.SOUTH_EAST;
                default:
                    return BlockFace.SELF;
            }
        } else {
            switch (sign.getData()) {
                case 0x2:
                    return BlockFace.NORTH;
                case 0x3:
                    return BlockFace.SOUTH;
                case 0x4:
                    return BlockFace.WEST;
                case 0x5:
                    return BlockFace.EAST;
                default:
                    return BlockFace.SELF;
            }
        }
    }

    public static Block getFrontBlock(Block sign) {

        return sign.getRelative(getFront(sign));
    }

    /**
     * @param sign treated as sign post if it is such, or else assumed to be a wall sign (i.e.,
     *             if you ask about a stone block, it's considered a wall
     *             sign).
     *
     * @return the blank side of the sign opposite the text. In the case of a wall sign,
     *         the block in this direction is the block to which the sign is
     *         attached. This is also the direction a player would be facing when reading the sign; see {@link
     *         #getFacing(Block)}.
     */
    public static BlockFace getBack(Block sign) {

        if (sign.getType() == Material.SIGN_POST) {
            switch (sign.getData()) {
                case 0x0:
                    return BlockFace.NORTH;
                case 0x1:
                case 0x2:
                case 0x3:
                    return BlockFace.NORTH_EAST;
                case 0x4:
                    return BlockFace.EAST;
                case 0x5:
                case 0x6:
                case 0x7:
                    return BlockFace.SOUTH_EAST;
                case 0x8:
                    return BlockFace.SOUTH;
                case 0x9:
                case 0xA:
                case 0xB:
                    return BlockFace.SOUTH_WEST;
                case 0xC:
                    return BlockFace.WEST;
                case 0xD:
                case 0xE:
                case 0xF:
                    return BlockFace.NORTH_WEST;
                default:
                    return BlockFace.SELF;
            }
        } else {
            switch (sign.getData()) {
                case 0x2:
                    return BlockFace.SOUTH;
                case 0x3:
                    return BlockFace.NORTH;
                case 0x4:
                    return BlockFace.EAST;
                case 0x5:
                    return BlockFace.WEST;
                default:
                    return BlockFace.SELF;
            }
        }
    }

    public static Block getBackBlock(Block sign) {

        return sign.getRelative(getBack(sign));
    }

    public static Block getNextSign(Block sign, String criterea, int searchRadius) {

        Block otherBlock = sign;
        BlockFace way = sign.getFace(getBackBlock(sign));
        boolean found = false;
        for (int i = 0; i < searchRadius; i++) {
            if (isSign(otherBlock.getRelative(way))) {
                otherBlock = otherBlock.getRelative(way);
                if (BukkitUtil.toChangedSign(otherBlock).getLine(1).equalsIgnoreCase(criterea)) {
                    found = true;
                    break;
                }
            } else
                otherBlock = otherBlock.getRelative(way);
        }
        if (!found) return null;
        return otherBlock;
    }

    /**
     * @param sign treated as sign post if it is such, or else assumed to be a wall sign (i.e.,
     *             if you ask about a stone block, it's considered a wall
     *             sign).
     *
     * @return the cardinal or ordinal direction to a player's left as they face the sign to read it; if the sign is
     *         oriented in a further direction,
     *         the result is rounded to the nearest ordinal direction.
     */
    public static BlockFace getRight(Block sign) {

        if (sign.getType() == Material.SIGN_POST) {
            switch (sign.getData()) {
                case 0x0:
                    return BlockFace.EAST;
                case 0x1:
                case 0x2:
                case 0x3:
                    return BlockFace.SOUTH_EAST;
                case 0x4:
                    return BlockFace.SOUTH;
                case 0x5:
                case 0x6:
                case 0x7:
                    return BlockFace.SOUTH_WEST;
                case 0x8:
                    return BlockFace.WEST;
                case 0x9:
                case 0xA:
                case 0xB:
                    return BlockFace.NORTH_WEST;
                case 0xC:
                    return BlockFace.NORTH;
                case 0xD:
                case 0xE:
                case 0xF:
                    return BlockFace.NORTH_EAST;
                default:
                    return BlockFace.SELF;
            }
        } else {
            switch (sign.getData()) {
                case 0x2:
                    return BlockFace.WEST;
                case 0x3:
                    return BlockFace.EAST;
                case 0x4:
                    return BlockFace.SOUTH;
                case 0x5:
                    return BlockFace.NORTH;
                default:
                    return BlockFace.SELF;
            }
        }
    }

    public static Block getLeftBlock(Block sign) {

        return sign.getRelative(getLeft(sign));
    }

    /**
     * @param sign treated as sign post if it is such, or else assumed to be a wall sign (i.e.,
     *             if you ask about a stone block, it's considered a wall
     *             sign).
     *
     * @return the cardinal or ordinal direction to a player's right they face the sign to read it; if the sign is
     *         oriented in a further direction, the
     *         result is rounded to the nearest ordinal direction.
     */
    public static BlockFace getLeft(Block sign) {

        if (sign.getType() == Material.SIGN_POST) {
            switch (sign.getData()) {
                case 0x0:
                    return BlockFace.WEST;
                case 0x1:
                case 0x2:
                case 0x3:
                    return BlockFace.NORTH_WEST;
                case 0x4:
                    return BlockFace.NORTH;
                case 0x5:
                case 0x6:
                case 0x7:
                    return BlockFace.NORTH_EAST;
                case 0x8:
                    return BlockFace.EAST;
                case 0x9:
                case 0xA:
                case 0xB:
                    return BlockFace.SOUTH_EAST;
                case 0xC:
                    return BlockFace.SOUTH;
                case 0xD:
                case 0xE:
                case 0xF:
                    return BlockFace.SOUTH_WEST;
                default:
                    return BlockFace.SELF;
            }
        } else {
            switch (sign.getData()) {
                case 0x2:
                    return BlockFace.EAST;
                case 0x3:
                    return BlockFace.WEST;
                case 0x4:
                    return BlockFace.NORTH;
                case 0x5:
                    return BlockFace.SOUTH;
                default:
                    return BlockFace.SELF;
            }
        }
    }

    public static Block getRightBlock(Block sign) {

        return sign.getRelative(getRight(sign));
    }

    /**
     * @param sign treated as sign post if it is such, or else assumed to be a wall sign (i.e.,
     *             if you ask about a stone block, it's considered a wall
     *             sign).
     *
     * @return true if the sign is oriented along a cardinal direction (or if it's a wall sign,
     *         since those are always oriented along cardinal
     *         directions); false otherwise.
     */
    public static boolean isCardinal(Block sign) {

        if (sign.getType() == Material.SIGN_POST) {
            switch (sign.getData()) {
                case 0x0:
                case 0x4:
                case 0x8:
                case 0xC:
                    return true;
                default:
                    return false;
            }
        } else return true;
    }

    /**
     * @param face Start from direction
     *
     * @return clockwise direction
     */
    public static BlockFace getClockWise(BlockFace face) {

        switch (face) {
            case NORTH:
                return BlockFace.EAST;
            case EAST:
                return BlockFace.SOUTH;
            case SOUTH:
                return BlockFace.WEST;
            case WEST:
                return BlockFace.NORTH;

            default:
                return BlockFace.SELF;
        }
    }

    /**
     * @param face Start from direction
     *
     * @return clockwise direction
     */
    public static BlockFace getCounterClockWise(BlockFace face) {

        switch (face) {
            case NORTH:
                return BlockFace.WEST;
            case EAST:
                return BlockFace.NORTH;
            case SOUTH:
                return BlockFace.EAST;
            case WEST:
                return BlockFace.SOUTH;

            default:
                return BlockFace.SELF;
        }
    }

    /**
     * Cancels a sign change event, and destroys the sign in the process.
     *
     * @param event The event that is to be cancelled.
     */
    public static void cancelSign(SignChangeEvent event) {
        event.setCancelled(true);
        event.getBlock().breakNaturally();
    }

    /**
     * Check whether or not the block is a sign, and if so, does it contain the said text on that specific line.
     *
     * @param sign The sign to check.
     * @param text The text to check.
     * @param line The line to check the text on.
     * @return
     */
    public static boolean doesSignHaveText(Block sign, String text, int line) {
        return isSign(sign) && BukkitUtil.toChangedSign(sign).getLine(line).equals(text);
    }
}
TOP

Related Classes of com.sk89q.craftbook.util.SignUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.