Package net.aufdemrand.denizen.utilities

Source Code of net.aufdemrand.denizen.utilities.Utilities

package net.aufdemrand.denizen.utilities;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import net.aufdemrand.denizen.Settings;
import net.aufdemrand.denizen.npc.traits.TriggerTrait;
import net.aufdemrand.denizen.objects.dNPC;
import net.aufdemrand.denizen.objects.dPlayer;
import net.aufdemrand.denizen.tags.TagManager;

import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizencore.utilities.CoreUtilities;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;

/**
* This class has utility methods for various tasks.
*
* @author aufdemrand, dbixler, AgentK
*/
public class Utilities {


    // TODO: Javadocs, comments
    //
    public static Location getWalkableLocationNear(Location location, int range) {
        Location returnable;

        int selected_x = CoreUtilities.getRandom().nextInt(range * 2);
        int selected_z = CoreUtilities.getRandom().nextInt(range * 2);
        returnable = location.clone().add(selected_x - range, 1, selected_z - range);

        // TODO: Handle location being underground/in a wall better than a stack overflow?
        if (!isWalkable(returnable)) return getWalkableLocationNear(location, range);
        else return returnable;
    }


    // TODO: Javadocs, comments
    //
    public static boolean isWalkable(Location location) {
        return ((location.getBlock().getType() == Material.AIR
                || location.getBlock().getType() == Material.GRASS)
                && (location.add(0, 1, 0).getBlock().getType() == Material.AIR));
    }


    // TODO: Javadocs, comments
    //
    public static String arrayToString(String[] input, String glue) {
        String output="";
        int length = input.length;
        int i = 1;
        for(String s : input) { // TODO: Should this be? : output = output.concat(s);
            output.concat(s);
            i++;
            if(i!=length){
                output.concat(glue); // TODO: Same as above
            }
        }
        return output;
    }


    // TODO: Javadocs, comments
    //
    public static String[] wrapWords(String text, int width) {
        StringBuilder sb = new StringBuilder(text);

        int i = 0;
        while (i + width < sb.length() && (i = sb.lastIndexOf(" ", i + width)) != -1) {
            sb.replace(i, i + 1, "\n");
        }

        return sb.toString().split("\n");
    }


    /**
     *
     *
     * @param player  the player doing the talking
     * @param npc  the npc being talked to
     * @param range  the range, in blocks, that 'bystanders' will hear he chat
     *
     */
    public static void talkToNPC(String message, dPlayer player, dNPC npc, double range) {
        String replacer = String.valueOf((char)0x04);
        // Get formats from Settings, and fill in <TEXT>
        String talkFormat = Settings.chatToNpcFormat()
                .replaceAll("(?i)<TEXT>", replacer);
        String bystanderFormat = Settings.chatToNpcOverheardFormat()
                .replaceAll("(?i)<TEXT>", replacer);

        // Fill in tags
        talkFormat = TagManager.tag(player, npc, talkFormat, false).replace(replacer, message);
        bystanderFormat = TagManager.tag(player, npc, bystanderFormat, false).replace(replacer, message);

        // Send message to player
        player.getPlayerEntity().sendMessage(talkFormat);

        // Send message to bystanders
        for (Player target : Bukkit.getOnlinePlayers()) {
            if (target != player.getPlayerEntity())
                if (target.getWorld().equals(player.getPlayerEntity().getWorld())
                        && target.getLocation().distance(player.getPlayerEntity().getLocation()) <= range)
                    target.sendMessage(bystanderFormat);
        }
    }


    public static int lastIndexOfUCL(String str) {
        for(int i=str.length()-1; i>=0; i--) {
            if(Character.isUpperCase(str.charAt(i))) {
                return i;
            }
        }
        return -1;
    }


    /**
     * Checks if c is in between a and b, or equal to a or b.
     *
     * @param a first number
     * @param b second number
     * @param c number to check if between
     * @return  true if c is in between.
     */
    public static boolean isBetween(double a, double b, double c) {
        return a == c || b == c || (b > a ? c > a && c < b : c > b && c < a);
    }


    /**
     * Gets the plugin version from the maven info in the jar, if available.
     *
     * @return the version string
     */
    @Deprecated // TODO: Can this be removed?
    public String getVersionNumber() {
        Properties props = new Properties();
        //Set a default just in case.
        props.put("version", "Unknown development build");
        try { props.load(this.getClass()
                .getResourceAsStream("/META-INF/maven/net.aufdemrand/denizen/pom.properties"));
        } catch(Exception e) { }

        return props.getProperty("version");
    }


    // TODO: Finish?
    //
    public static List<Block> getRandomSolidBlocks(Location location, int range, int count) {
        List<Block> blocks = new ArrayList<Block>();

        int x = 0;
        int f = 0;

        while (x < count) {

            if (f > 1000) break;
            f++;

            Location loc = location.clone()
                    .add(CoreUtilities.getRandom().nextInt(range * 2) - range,
                            CoreUtilities.getRandom().nextInt(range * 2) - range,
                            CoreUtilities.getRandom().nextInt(range * 2) - range);

            if (loc.getBlock().getType().isSolid()) {
                blocks.add(loc.getBlock());
                x++;
            }

        }

        dB.log(blocks.size() + " blocksize");

        return blocks;
    }


    // TODO: Check why this is no longer used. Possible duplication of code?
    //
    /**
     * Finds the closest Player to a particular location.
     *
     * @param location    The location to find the closest Player to.
     * @param range    The maximum range to look for the Player.
     * @return    The closest Player to the location, or null if no Player was found
     *                     within the range specified.
     */
    public static Player getClosestPlayer (Location location, int range) {

        Player closestPlayer = null;
        double closestDistance = Math.pow(range, 2);
        // TODO: Why is this manually iterating?
        List<Player> playerList = new ArrayList<Player>(Bukkit.getOnlinePlayers());
        Iterator<Player> it = playerList.iterator();
        while (it.hasNext()) {
            Player player = it.next();
            Location loc = player.getLocation();
            if (loc.getWorld().equals(location.getWorld())
                    && loc.distanceSquared(location) < closestDistance) {
                closestPlayer = player;
                closestDistance = player.getLocation().distanceSquared(location);
            }
        }
        return closestPlayer;
    }


    // TODO: Check why this is no longer used. Possible duplication of code?
    //
    /**
     * Finds the closest Players to a particular location.
     *
     * @param location    The location to find the closest Player to.
     * @param range    The maximum range to look for the Player.
     * @return    The closest Player to the location, or null if no Player was found
     *                     within the range specified.
     */
    public static List<dPlayer> getClosestPlayers(Location location, int range) {

        List<dPlayer> closestPlayers = new ArrayList<dPlayer>();
        double closestDistance = Math.pow(range, 2);
        // TODO: Why is this manually iterating?
        List<Player> playerList = new ArrayList<Player>(Bukkit.getOnlinePlayers());
        Iterator<Player> it = playerList.iterator();
        while (it.hasNext()) {
            Player player = it.next();
            Location loc = player.getLocation();
            if (loc.getWorld().equals(location.getWorld())
                    && loc.distanceSquared(location) < closestDistance) {
                closestPlayers.add(dPlayer.mirrorBukkitPlayer(player));
            }
        }
        return closestPlayers;
    }


    // TODO: Check why this is no longer used. Possible duplication of code?
    //
    /**
     * Finds the closest NPC to a particular location.
     *
     * @param location    The location to find the closest NPC to.
     * @param range    The maximum range to look for the NPC.
     * @return    The closest NPC to the location, or null if no NPC was found
     *                     within the range specified.
     */
    public static dNPC getClosestNPC (Location location, int range) {
        dNPC closestNPC = null;
        double closestDistance = Math.pow(range, 2);
        // TODO: Why is this manually iterating?
        Iterator<dNPC> it = DenizenAPI.getSpawnedNPCs().iterator();
        while (it.hasNext()) {
            dNPC npc = it.next();
            Location loc = npc.getLocation();
            if (loc.getWorld().equals(location.getWorld())
                    && loc.distanceSquared(location) < closestDistance) {
                closestNPC = npc;
                closestDistance = npc.getLocation().distanceSquared(location);
            }
        }
        return closestNPC;
    }


    /**
     * Finds the closest NPC to a particular location.
     *
     * @param location    The location to find the closest NPC to.
     * @param range    The maximum range to look for the NPC.
     * @return    The closest NPC to the location, or null if no NPC was found
     *                     within the range specified.
     */
    public static dNPC getClosestNPC_ChatTrigger (Location location, int range) {
        dNPC closestNPC = null;
        double closestDistance = Math.pow(range, 2);
        // TODO: Why is this manually iterating?
        Iterator<dNPC> it = DenizenAPI.getSpawnedNPCs().iterator();
        while (it.hasNext()) {
            dNPC npc = it.next();
            Location loc = npc.getLocation();
            if (npc.getCitizen().hasTrait(TriggerTrait.class) && npc.getTriggerTrait().hasTrigger("CHAT") &&
                    loc.getWorld().equals(location.getWorld())
                    && loc.distanceSquared(location) < closestDistance) {
                closestNPC = npc;
                closestDistance = npc.getLocation().distanceSquared(location);
            }
        }
        return closestNPC;
    }


    /**
     * Returns a list of all NPCs within a certain range.
     *
     * @param location    The location to search.
     * @param maxRange    The maximum range of the NPCs
     *
     * @return    The list of NPCs within the max range.
     */
    public static Set<dNPC> getClosestNPCs (Location location, int maxRange) {
        maxRange = (int) Math.pow(maxRange, 2);
        Set<dNPC> closestNPCs = new HashSet<dNPC> ();
        // TODO: Why is this manually iterating?
        Iterator<dNPC> it = DenizenAPI.getSpawnedNPCs().iterator();
        while (it.hasNext ()) {
            dNPC npc = it.next ();
            Location loc = npc.getLocation();
            if (loc.getWorld().equals(location.getWorld()) && loc.distanceSquared(location) < maxRange) {
                closestNPCs.add(npc);
            }
        }
        return closestNPCs;
    }


    /**
     * Checks entity's location against a Location (with leeway). Should be faster than
     * bukkit's built in Location.distance(Location) since there's no sqrt math.
     *
     * Thanks chainsol :)
     *
     * @return true if within the specified location, false otherwise.
     */
    public static boolean checkLocation(LivingEntity entity, Location theLocation, double theLeeway) {
        if (entity.getWorld() != theLocation.getWorld())
            return false;

        Location entityLocation = entity.getLocation();

        if (Math.abs(entityLocation.getX() - theLocation.getX())
                > theLeeway) return false;
        if (Math.abs(entityLocation.getY() - theLocation.getY())
                > theLeeway) return false;
        if (Math.abs(entityLocation.getZ() - theLocation.getZ())
                > theLeeway) return false;

        return true;
    }


    /**
     * Checks entity's location against a Location (with leeway). Should be faster than
     * bukkit's built in Location.distance(Location) since there's no sqrt math.
     *
     * @return true if within the specified location, false otherwise.
     */
    public static boolean checkLocation(Location baseLocation, Location theLocation, double theLeeway) {

        if (!baseLocation.getWorld().getName().equals(theLocation.getWorld().getName()))
            return false;

        return baseLocation.distanceSquared(theLocation) < theLeeway * theLeeway;
    }

    /**
     * Set the lines on a sign to the strings in a string array
     *
     * @param sign  The sign
     * @param lines  The string array
     */
    public static void setSignLines(Sign sign, String[] lines) {

        for (int n = 0; n < 4; n++) {
            sign.setLine(n, lines[n]);
        }

        sign.update();
    }


    /**
     * Make a wall sign attach itself to an available surface
     *
     * @param signState  The sign's blockState
     */
    public static void setSignRotation(BlockState signState) {

        BlockFace[] blockFaces = {BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH};

        for (BlockFace blockFace : blockFaces) {

            Block block = signState.getBlock().getRelative(blockFace);

            if ((block.getType() != Material.AIR)
                    && block.getType() != Material.SIGN_POST
                    && block.getType() != Material.WALL_SIGN) {

                ((org.bukkit.material.Sign) signState.getData())
                        .setFacingDirection(blockFace.getOppositeFace());
                signState.update();
            }
        }
    }

    // TODO: Javadocs, comments
    //
    public static void setSignRotation(BlockState signState, String direction) {

        BlockFace[] blockFaces = {BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH};

        for (BlockFace blockFace : blockFaces) {
            if (blockFace.name().startsWith(direction.toUpperCase().substring(0, 1)))
                ((org.bukkit.material.Sign) signState.getData())
                        .setFacingDirection(blockFace);
        }
        signState.update();
    }


    /**
     * Check if a block location equals another location.
     * @param block The block location to check for.
     * @param location The location to check against.
     * @return Whether or not the block location equals the location.
     */
    public static boolean isBlock(Location block, Location location) {

        if (!block.getWorld().getName().equals(location.getWorld().getName()))
            return false;

        if (Math.abs(block.getBlockX() - location.getBlockX())
                > 0) return false;
        if (Math.abs(block.getBlockY() - location.getBlockY())
                > 0) return false;
        if (Math.abs(block.getBlockZ() - location.getBlockZ())
                > 0) return false;

        return true;
    }


    /**
     * Extract a file from a zip or jar.
     * @param jarFile The zip/jar file to use
     * @param fileName Which file to extract
     * @param destDir Where to extract it to
     */
    public static void extractFile(File jarFile, String fileName, String destDir) {
        java.util.jar.JarFile jar = null;

        try {
            jar = new java.util.jar.JarFile(jarFile);
            java.util.Enumeration myEnum = jar.entries();
            while (myEnum.hasMoreElements()) {
                java.util.jar.JarEntry file = (java.util.jar.JarEntry) myEnum.nextElement();
                if (file.getName().equalsIgnoreCase(fileName)) {
                    java.io.File f = new java.io.File(destDir + "/" + file.getName());
                    if (file.isDirectory()) {
                        continue;
                    }
                    java.io.InputStream is = jar.getInputStream(file);
                    java.io.FileOutputStream fos = new java.io.FileOutputStream(f);
                    while (is.available() > 0)
                        fos.write(is.read());
                    fos.close();
                    is.close();
                    return;
                }
            }
            dB.echoError(fileName + " not found in the jar!");

        } catch (IOException e) {
            dB.echoError(e);

        } finally {
            if (jar != null) {
                try {
                    jar.close();
                } catch (IOException e) {
                    dB.echoError(e);
                }
            }
        }
    }

    private final static String colors = "0123456789abcdefklmnorABCDEFKLMNOR";

    public static String generateRandomColors(int count) {
        String ret = "";
        for (int i = 0; i < count; i++) {
            ret += String.valueOf(ChatColor.COLOR_CHAR) + colors.charAt(CoreUtilities.getRandom().nextInt(34));
        }
        return ret;
    }
}
TOP

Related Classes of net.aufdemrand.denizen.utilities.Utilities

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.