Package com.sk89q.craftbook.util

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

// $Id$
/*
* Copyright (C) 2010, 2011 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 java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.event.block.BlockRedstoneEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Lever;

import com.sk89q.craftbook.ChangedSign;
import com.sk89q.craftbook.LocalPlayer;
import com.sk89q.craftbook.bukkit.BukkitPlayer;
import com.sk89q.craftbook.bukkit.CraftBookPlugin;
import com.sk89q.craftbook.bukkit.util.BukkitUtil;
import com.sk89q.craftbook.mechanics.ic.AbstractIC;
import com.sk89q.craftbook.mechanics.ic.ICMechanic;
import com.sk89q.craftbook.mechanics.ic.ICVerificationException;
import com.sk89q.craftbook.mechanics.pipe.PipeRequestEvent;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.regions.CuboidRegionSelector;
import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.SphereRegionSelector;

/**
* IC utility functions.
*
* @author sk89q
*/
public class ICUtil {

    /**
     * Set an IC's output state at a block.
     *
     * @param block
     * @param state
     *
     * @return whether something was changed
     */
    public static boolean setState(Block block, boolean state, Block source) {

        if (block.getType() != Material.LEVER) return false;

        // return if the lever is not attached to our IC block
        Lever lever = (Lever) block.getState().getData();

        if (!block.getRelative(lever.getAttachedFace()).equals(source))
            return false;

        // check if the lever was toggled on
        boolean wasOn = (block.getData() & 0x8) > 0;

        byte data = block.getData();
        int newData;
        // check if the state changed and set the data value
        if (!state) {
            newData = data & 0x7;
        } else {
            newData = data | 0x8;
        }

        // if the state changed lets apply physics to the source block and the lever itself
        if (wasOn != state) {

            // set the new data
            block.setData((byte) newData, true);
            // apply physics to the source block the lever is attached to
            byte sData = source.getData();
            source.setData((byte) (sData - 1), true);
            source.setData(sData, true);

            // lets call blockredstone events on the source block and the lever
            // in order to correctly update all surrounding blocks
            BlockRedstoneEvent leverEvent = new BlockRedstoneEvent(block, wasOn ? 15 : 0, state ? 15 : 0);
            BlockRedstoneEvent sourceEvent = new BlockRedstoneEvent(source, wasOn ? 15 : 0, state ? 15 : 0);
            CraftBookPlugin.inst().getServer().getPluginManager().callEvent(leverEvent);
            CraftBookPlugin.inst().getServer().getPluginManager().callEvent(sourceEvent);
            return true;
        }

        return false;
    }

    public static void parseSignFlags(LocalPlayer player, ChangedSign sign) {

        for(int i = 2; i < 4; i++) {

            if(sign.getLine(i).contains("[off]")) {

                if(CraftBookPlugin.plugins.getWorldEdit() == null) {
                    sign.setLine(i, StringUtils.replace(sign.getLine(i), "[off]", ""));
                    player.printError("worldedit.ic.notfound");
                } else {
                    if(CraftBookPlugin.plugins.getWorldEdit().getSelection(((BukkitPlayer) player).getPlayer()) != null && CraftBookPlugin.plugins.getWorldEdit().getSelection(((BukkitPlayer) player).getPlayer()).getRegionSelector() != null) {

                        RegionSelector selector = CraftBookPlugin.plugins.getWorldEdit().getSelection(((BukkitPlayer) player).getPlayer()).getRegionSelector();

                        try {
                            if(selector instanceof CuboidRegionSelector) {

                                Vector centre = selector.getRegion().getMaximumPoint().add(selector.getRegion().getMinimumPoint());

                                centre = centre.divide(2);

                                Vector offset = centre.subtract(sign.getBlockVector());

                                String x,y,z;

                                x = Double.toString(offset.getX());
                                if (x.endsWith(".0"))
                                    x = StringUtils.replace(x, ".0", "");

                                y = Double.toString(offset.getY());
                                if (y.endsWith(".0"))
                                    y = StringUtils.replace(y, ".0", "");

                                z = Double.toString(offset.getZ());
                                if (z.endsWith(".0"))
                                    z = StringUtils.replace(z, ".0", "");

                                sign.setLine(i, StringUtils.replace(sign.getLine(i), "[off]", "&" + x + ":" + y + ":" + z));
                            } else if (selector instanceof SphereRegionSelector) {

                                Vector centre = ((SphereRegionSelector)selector).getRegion().getCenter();

                                Vector offset = centre.subtract(sign.getBlockVector());

                                String x,y,z;

                                x = Double.toString(offset.getX());
                                if (x.endsWith(".0"))
                                    x = StringUtils.replace(x, ".0", "");

                                y = Double.toString(offset.getY());
                                if (y.endsWith(".0"))
                                    y = StringUtils.replace(y, ".0", "");

                                z = Double.toString(offset.getZ());
                                if (z.endsWith(".0"))
                                    z = StringUtils.replace(z, ".0", "");

                                sign.setLine(i, StringUtils.replace(sign.getLine(i), "[off]", "&" + x + ":" + y + ":" + z));
                            } else { // Unsupported.
                                sign.setLine(i, StringUtils.replace(sign.getLine(i), "[off]", ""));
                                player.printError("worldedit.ic.unsupported");
                            }
                        }
                        catch(IncompleteRegionException e) {
                            player.printError("worldedit.ic.noselection");
                        }
                    } else {
                        player.printError("worldedit.ic.noselection");
                    }
                }
            }

            if(sign.getLine(i).contains("[rad]")) {

                if(CraftBookPlugin.plugins.getWorldEdit() == null) {
                    sign.setLine(i, StringUtils.replace(sign.getLine(i), "[rad]", ""));
                    player.printError("worldedit.ic.notfound");
                } else {

                    if(CraftBookPlugin.plugins.getWorldEdit().getSelection(((BukkitPlayer) player).getPlayer()) != null && CraftBookPlugin.plugins.getWorldEdit().getSelection(((BukkitPlayer) player).getPlayer()).getRegionSelector() != null) {

                        RegionSelector selector = CraftBookPlugin.plugins.getWorldEdit().getSelection(((BukkitPlayer) player).getPlayer()).getRegionSelector();

                        try {
                            if(selector instanceof CuboidRegionSelector) {

                                String x,y,z;

                                x = Double.toString(Math.abs(selector.getRegion().getMaximumPoint().getX() - selector.getRegion().getMinimumPoint().getX())/2);
                                if (x.endsWith(".0"))
                                    x = StringUtils.replace(x, ".0", "");

                                y = Double.toString(Math.abs(selector.getRegion().getMaximumPoint().getY() - selector.getRegion().getMinimumPoint().getY())/2);
                                if (y.endsWith(".0"))
                                    y = StringUtils.replace(y, ".0", "");

                                z = Double.toString(Math.abs(selector.getRegion().getMaximumPoint().getZ() - selector.getRegion().getMinimumPoint().getZ())/2);
                                if (z.endsWith(".0"))
                                    z = StringUtils.replace(z, ".0", "");

                                sign.setLine(i, StringUtils.replace(sign.getLine(i), "[rad]", x + "," + y + "," + z));
                            } else if (selector instanceof SphereRegionSelector) {

                                String x;

                                double amounts = ((EllipsoidRegion) selector.getRegion()).getRadius().getX();

                                x = Double.toString(amounts);
                                if (x.endsWith(".0"))
                                    x = StringUtils.replace(x, ".0", "");

                                sign.setLine(i, StringUtils.replace(sign.getLine(i), "[rad]", x));
                            } else { // Unsupported.
                                sign.setLine(i, StringUtils.replace(sign.getLine(i), "[rad]", ""));
                                player.printError("worldedit.ic.unsupported");
                            }
                        }
                        catch(IncompleteRegionException e) {
                            player.printError("worldedit.ic.noselection");
                        }
                    } else {
                        player.printError("worldedit.ic.noselection");
                    }
                }
            }
        }

        sign.update(false);
    }

    public static Vector parseUnsafeBlockLocation(String line) throws NumberFormatException, ArrayIndexOutOfBoundsException {

        line = StringUtils.replace(StringUtils.replace(StringUtils.replace(line, "!", ""), "^", ""), "&", "");
        double offsetX = 0, offsetY = 0, offsetZ = 0;

        if (line.contains("="))
            line = RegexUtil.EQUALS_PATTERN.split(line)[1];
        String[] split = RegexUtil.COLON_PATTERN.split(line);
        if (split.length > 1) {
            offsetX = Double.parseDouble(split[0]);
            offsetY = Double.parseDouble(split[1]);
            offsetZ = Double.parseDouble(split[2]);
        } else
            offsetY = Double.parseDouble(line);

        return new Vector(offsetX, offsetY, offsetZ);
    }

    public static Block parseBlockLocation(ChangedSign sign, String line, LocationCheckType relative) {

        Block target = SignUtil.getBackBlock(BukkitUtil.toSign(sign).getBlock());

        if (line.contains("!"))
            relative = LocationCheckType.getTypeFromChar('!');
        else if (line.contains("^"))
            relative = LocationCheckType.getTypeFromChar('^');
        else if (line.contains("&"))
            relative = LocationCheckType.getTypeFromChar('&');

        Vector offsets = new Vector(0,0,0);

        try {
            offsets = parseUnsafeBlockLocation(line);
        } catch (NumberFormatException ignored) {
        } catch (ArrayIndexOutOfBoundsException ignored) {
        }

        if(offsets.getBlockX() == 0 && offsets.getBlockY() == 0 && offsets.getBlockZ() == 0)
            return target;

        if (relative == LocationCheckType.RELATIVE)
            target = LocationUtil.getRelativeOffset(sign, offsets.getBlockX(), offsets.getBlockY(), offsets.getBlockZ());
        else if (relative == LocationCheckType.OFFSET)
            target = LocationUtil.getOffset(target, offsets.getBlockX(), offsets.getBlockY(), offsets.getBlockZ());
        else if (relative == LocationCheckType.ABSOLUTE)
            target = new Location(target.getWorld(), offsets.getBlockX(), offsets.getBlockY(), offsets.getBlockZ()).getBlock();
        return target;
    }

    public static Block parseBlockLocation(ChangedSign sign, int lPos, LocationCheckType relative) {

        return parseBlockLocation(sign, sign.getLine(lPos), relative);
    }

    public static Block parseBlockLocation(ChangedSign sign, int lPos) {

        return parseBlockLocation(sign, lPos, ICMechanic.instance.defaultCoordinates);
    }

    public static Block parseBlockLocation(ChangedSign sign) {

        return parseBlockLocation(sign, 2, ICMechanic.instance.defaultCoordinates);
    }

    public static void verifySignSyntax(ChangedSign sign) throws ICVerificationException {

        verifySignLocationSyntax(sign, 2);
    }

    public static void verifySignLocationSyntax(ChangedSign sign, int i) throws ICVerificationException {

        try {
            String line = sign.getLine(i);
            String[] strings;
            line = StringUtils.replace(StringUtils.replace(StringUtils.replace(line, "!", ""), "^", ""), "&", "");
            if (line.contains("=")) {
                String[] split = RegexUtil.EQUALS_PATTERN.split(line, 2);
                if(RegexUtil.COMMA_PATTERN.split(split[0]).length > 1) {

                    String[] rads = RegexUtil.COMMA_PATTERN.split(split[0]);
                    Double.parseDouble(rads[0]);
                    Double.parseDouble(rads[1]);
                    Double.parseDouble(rads[2]);
                } else
                    Double.parseDouble(split[0]);
                strings = RegexUtil.COLON_PATTERN.split(split[1], 3);
            } else
                strings = RegexUtil.COLON_PATTERN.split(line);
            if (strings.length > 1) {
                Double.parseDouble(strings[1]);
                Double.parseDouble(strings[2]);
            }
            Double.parseDouble(strings[0]);
        } catch (Exception e) {
            throw new ICVerificationException("Wrong syntax! Needs to be: radius=x:y:z or radius=y or y");
        }
    }

    public static Vector parseRadius(ChangedSign sign) {

        return parseRadius(sign, 2);
    }

    public static Vector parseRadius(ChangedSign sign, int lPos) {

        return parseRadius(sign.getLine(lPos));
    }

    public static Vector parseRadius(String line) {

        Vector radius = new Vector(10,10,10);
        try {
            radius = parseUnsafeRadius(line);
        } catch (NumberFormatException ignored) {
        }
        return radius;
    }

    public static Vector parseUnsafeRadius(String line) throws NumberFormatException {
        String[] radians = RegexUtil.COMMA_PATTERN.split(RegexUtil.EQUALS_PATTERN.split(line, 2)[0]);
        if(radians.length > 1) {
            double x = VerifyUtil.verifyRadius(Double.parseDouble(radians[0]), ICMechanic.instance.maxRange);
            double y = VerifyUtil.verifyRadius(Double.parseDouble(radians[1]), ICMechanic.instance.maxRange);
            double z = VerifyUtil.verifyRadius(Double.parseDouble(radians[2]), ICMechanic.instance.maxRange);
            return new Vector(x,y,z);
        }
        else {
            double r = Double.parseDouble(radians[0]);
            r = VerifyUtil.verifyRadius(r, ICMechanic.instance.maxRange);
            return new Vector(r,r,r);
        }
    }

    public static void collectItem(AbstractIC ic, Vector offset, ItemStack... items) {
        Sign sign = BukkitUtil.toSign(ic.getSign());
        Block backB = ic.getBackBlock();
        BlockFace back = SignUtil.getBack(sign.getBlock());

        Block pipe = backB.getRelative(back);

        // Handle the event
        PipeRequestEvent event = new PipeRequestEvent(pipe, new ArrayList<ItemStack>(Arrays.asList(items)), backB);
        Bukkit.getPluginManager().callEvent(event);

        if (!event.isValid()) return;

        Collection<ItemStack> results = event.getItems();

        // If there is a chest add the results to the chest
        Block invHolder = backB.getRelative(offset.getBlockX(), offset.getBlockY(), offset.getBlockZ());
        if (InventoryUtil.doesBlockHaveInventory(invHolder)) {
            InventoryHolder c = (InventoryHolder) invHolder.getState();
            results = c.getInventory().addItem(results.toArray(new ItemStack[results.size()])).values();
        }

        // Drop whatever results were not added to the chest
        for (ItemStack item : results) {
            backB.getWorld().dropItemNaturally(sign.getLocation().add(0.5, 0, 0.5), item);
        }
    }

    public enum LocationCheckType {

        RELATIVE('^'),
        OFFSET('&'),
        ABSOLUTE('!');

        char c;

        LocationCheckType(char c) {

            this.c = c;
        }

        public static LocationCheckType getTypeFromChar(char c) {

            for(LocationCheckType t : values())
                if(t.c == c)
                    return t;

            return RELATIVE;
        }

        public static LocationCheckType getTypeFromName(String name) {

            if(name.length() == 1)
                return getTypeFromChar(name.charAt(0));
            for(LocationCheckType t : values())
                if(t.name().equalsIgnoreCase(name))
                    return t;

            return RELATIVE;
        }
    }
}
TOP

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

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.