Package com.sk89q.craftbook.mechanics.minecart.blocks

Source Code of com.sk89q.craftbook.mechanics.minecart.blocks.CartMechanismBlocks

package com.sk89q.craftbook.mechanics.minecart.blocks;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.material.Attachable;
import org.bukkit.material.Vine;

import com.sk89q.craftbook.ChangedSign;
import com.sk89q.craftbook.bukkit.util.BukkitUtil;
import com.sk89q.craftbook.util.ItemInfo;
import com.sk89q.craftbook.util.LocationUtil;
import com.sk89q.craftbook.util.RailUtil;
import com.sk89q.craftbook.util.SignUtil;
import com.sk89q.craftbook.util.exceptions.InvalidMechanismException;

/**
* <p>
* Stores the tuple of three blocks over which any typical CartMechanism is implemented,
* and also performs detection of two of the blocks if only one
* is given.
* </p>
* <p>
* Sign text and base block type are not validated by any constructors; this must be performed explicitly by calling
* the appropriate methods after
* construction. Selection of signs thus does not concern itself with sign text at all; but this is fine,
* since if you have two signs in an area where
* they could concievably contend for control of the mechanism, you would be doing something that ought be physically
* impossible anyway (though yes,
* it is possible if editing the world directly without physics).
* </p>
*
* @author hash
*/
public class CartMechanismBlocks {

    /**
     * Declarative constructor. No arguments are validated in any way.
     *
     * @param rail the block containing the rails.
     * @param base the block on which the rails sit; the type of this block is what determines the mechanism type.
     * @param sign the block containing the sign that gives additional configuration to the mechanism,
     *             or null if not interested.
     */
    public CartMechanismBlocks(Block rail, Block base, Block sign) {

        this.rail = rail;
        this.base = base;
        this.sign = sign;
    }

    /**
     * Detecting factory; defers to one of the other three specific detecting factories based on whether the given
     * unknown block appears to be a sign,
     * rail, or base.
     *
     * @param unknown the block to examine.
     */
    public static CartMechanismBlocks find(Block unknown) throws InvalidMechanismException {

        Material ti = unknown.getType();
        if (SignUtil.isSign(unknown)) return findBySign(unknown);
        else if (RailUtil.isTrack(ti)) return findByRail(unknown);
        else return findByBase(unknown);
    }

    /**
     * <p>
     * Detecting factory, based on the position of the rails. The base must be one block below and the sign if it
     * exists must be two or three blocks
     * below. Signs are guaranteed to be signs (unless they're null) and rails are guaranteed to be rails.
     * </p>
     * <p>
     * This is the most important constructor, since it is the one invoked when processing cart move events.
     * </p>
     *
     * @param rail the block containing the rails.
     */
    public static CartMechanismBlocks findByRail(Block rail) throws InvalidMechanismException {

        if (!RailUtil.isTrack(rail.getType()))
            throw new InvalidMechanismException("rail argument must be a rail!");
        BlockFace face = BlockFace.DOWN;

        if (rail.getType() == Material.LADDER)
            face = ((Attachable) rail.getState().getData()).getAttachedFace();
        else if (rail.getType() == Material.VINE) {
            Vine vine = (Vine) rail.getState().getData();
            for(BlockFace test : LocationUtil.getDirectFaces()) {
                if(vine.isOnFace(test)) {
                    face = test;
                    break;
                }
            }
        }

        if (SignUtil.isSign(rail.getRelative(face, 2))) return new CartMechanismBlocks(rail, rail.getRelative(face, 1), rail.getRelative(face, 2));
        else if (SignUtil.isSign(rail.getRelative(face, 3)))
            return new CartMechanismBlocks(rail, rail.getRelative(face, 1), rail.getRelative(face, 3));
        else if (SignUtil.isSign(rail.getRelative(face, 1).getRelative(BlockFace.EAST, 1)))
            return new CartMechanismBlocks(rail, rail.getRelative(face, 1), rail.getRelative(face, 1).getRelative(BlockFace.EAST, 1));
        else if (SignUtil.isSign(rail.getRelative(face, 1).getRelative(BlockFace.WEST, 1)))
            return new CartMechanismBlocks(rail, rail.getRelative(face, 1), rail.getRelative(face, 1).getRelative(BlockFace.WEST, 1));
        else if (SignUtil.isSign(rail.getRelative(face, 1).getRelative(BlockFace.NORTH, 1)))
            return new CartMechanismBlocks(rail, rail.getRelative(face, 1), rail.getRelative(face, 1).getRelative(BlockFace.NORTH, 1));
        else if (SignUtil.isSign(rail.getRelative(face, 1).getRelative(BlockFace.SOUTH, 1)))
            return new CartMechanismBlocks(rail, rail.getRelative(face, 1), rail.getRelative(face, 1).getRelative(BlockFace.SOUTH, 1));
        return new CartMechanismBlocks(rail, rail.getRelative(face, 1), null);
    }

    /**
     * Detecting factory, based on the position of the base. The rails must be one block above and the sign if it
     * exists must be one or two blocks
     * below. Signs are guaranteed to be signs (unless they're null) and rails are guaranteed to be rails.
     *
     * @param base the block on which the rails sit; the type of this block is what determines the mechanism type.
     */
    public static CartMechanismBlocks findByBase(Block base) throws InvalidMechanismException {

        if (!RailUtil.isTrack(base.getRelative(BlockFace.UP, 1).getType()))
            throw new InvalidMechanismException("could not find rails.");
        if (SignUtil.isSign(base.getRelative(BlockFace.DOWN, 1)))
            return new CartMechanismBlocks(base.getRelative(BlockFace.UP, 1), base, base.getRelative(BlockFace.DOWN, 1));
        else if (SignUtil.isSign(base.getRelative(BlockFace.DOWN, 2)))
            return new CartMechanismBlocks(base.getRelative(BlockFace.UP, 1), base, base.getRelative(BlockFace.DOWN, 2));
        else if (SignUtil.isSign(base.getRelative(BlockFace.EAST, 1)))
            return new CartMechanismBlocks(base.getRelative(BlockFace.UP, 1), base, base.getRelative(BlockFace.EAST, 1));
        else if (SignUtil.isSign(base.getRelative(BlockFace.WEST, 1)))
            return new CartMechanismBlocks(base.getRelative(BlockFace.UP, 1), base, base.getRelative(BlockFace.WEST, 1));
        else if (SignUtil.isSign(base.getRelative(BlockFace.NORTH, 1)))
            return new CartMechanismBlocks(base.getRelative(BlockFace.UP, 1), base, base.getRelative(BlockFace.NORTH, 1));
        else if (SignUtil.isSign(base.getRelative(BlockFace.SOUTH, 1)))
            return new CartMechanismBlocks(base.getRelative(BlockFace.UP, 1), base, base.getRelative(BlockFace.SOUTH, 1));
        return new CartMechanismBlocks(base.getRelative(BlockFace.UP, 1), base, null);
    }

    /**
     * Detecting factory, based on the position of the sign. The base must be one or two blocks above and the rails
     * an additional block above the
     * base. Signs are guaranteed to be signs and rails are guaranteed to be rails.
     *
     * @param sign the block containing the sign that gives additional configuration to the mechanism.
     */
    public static CartMechanismBlocks findBySign(Block sign) throws InvalidMechanismException {

        if (!SignUtil.isSign(sign)) throw new InvalidMechanismException("sign argument must be a sign!");
        if (RailUtil.isTrack(sign.getRelative(BlockFace.UP, 2).getType()))
            return new CartMechanismBlocks(sign.getRelative(BlockFace.UP, 2), sign.getRelative(BlockFace.UP, 1), sign);
        else if (RailUtil.isTrack(sign.getRelative(BlockFace.UP, 3).getType()))
            return new CartMechanismBlocks(sign.getRelative(BlockFace.UP, 3), sign.getRelative(BlockFace.UP, 2), sign);
        else if (RailUtil.isTrack(sign.getRelative(SignUtil.getBack(sign), 1).getRelative(BlockFace.UP, 1).getType()))
            return new CartMechanismBlocks(sign.getRelative(SignUtil.getBack(sign), 1).getRelative(BlockFace.UP, 1), sign.getRelative( SignUtil.getBack(sign), 1), sign);
        throw new InvalidMechanismException("could not find rails.");
    }

    public final Block rail;
    public final Block base;
    public final Block sign;
    public Block from;

    /**
     * This is a stupid but necessary thing since hash completely broke the ability to get the from location of the
     * move event from a mechanism
     * itself.
     */
    public void setFromBlock(Block block) {

        from = block;
    }

    /**
     * @param mechname
     *
     * @return true if the bracketed keyword on the sign matches the given mechname; false otherwise or if no sign.
     *
     * @throws ClassCastException if the declarative constructor was used in such a way that a non-sign block was
     *                            specified for a sign.
     */
    public boolean matches(String mechname) {

        return hasSign() && getSign().getLine(1).equalsIgnoreCase("[" + mechname + "]");
        // the astute will notice there's a problem coming up here with the one dang thing that had to go and break
        // the mold with second line definer.
    }

    /**
     * @param mat
     *
     * @return true if the base block is the same type as the given block.
     */
    public boolean matches(ItemInfo mat) {

        return base.getType() == mat.getType() && base.getData() == mat.getData();
    }

    /**
     * @return a Sign BlockState, or null if there is no sign block.
     *
     * @throws ClassCastException if there a sign block is set, but it's not *actually* a sign block.
     */
    public ChangedSign getSign() {

        return !hasSign() ? null : BukkitUtil.toChangedSign(sign);
    }

    public boolean hasSign() {

        return sign != null && SignUtil.isSign(sign);
    }

    public boolean hasRail() {

        return rail != null;
    }

    public boolean hasBase() {

        return base != null;
    }
}
TOP

Related Classes of com.sk89q.craftbook.mechanics.minecart.blocks.CartMechanismBlocks

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.