Package com.sk89q.craftbook.mechanics

Source Code of com.sk89q.craftbook.mechanics.HeadDrops

package com.sk89q.craftbook.mechanics;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.Skull;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;

import com.sk89q.craftbook.AbstractCraftBookMechanic;
import com.sk89q.craftbook.LocalPlayer;
import com.sk89q.craftbook.bukkit.CraftBookPlugin;
import com.sk89q.craftbook.util.EventUtil;
import com.sk89q.craftbook.util.ItemUtil;
import com.sk89q.craftbook.util.ProtectionUtil;
import com.sk89q.util.yaml.YAMLProcessor;

public class HeadDrops extends AbstractCraftBookMechanic {

    protected static HeadDrops instance;

    @Override
    public boolean enable() {

        instance = this;
        return true;
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void onEntityDeath(EntityDeathEvent event) {

        if(!EventUtil.passesFilter(event)) return;

        if(!(event.getEntity() instanceof LivingEntity)) return;
        if(playerKillsOnly && event.getEntity().getKiller() == null) return;
        if(event.getEntityType() == null) return;

        if(event.getEntity().getKiller() != null && !event.getEntity().getKiller().hasPermission("craftbook.mech.headdrops.kill"))
            return;

        String typeName = event.getEntityType().getName();
        if (typeName == null && event.getEntityType() == EntityType.PLAYER)
            typeName = "PLAYER";
        else if (typeName == null)
            return; //Invalid type.
        else
            typeName = typeName.toUpperCase();

        double chance = Math.min(1, dropRate);
        if(customDropRates.containsKey(typeName))
            chance = Math.min(1, customDropRates.get(typeName));

        if(event.getEntity().getKiller() != null && event.getEntity().getKiller().getItemInHand() != null && event.getEntity().getKiller().getItemInHand().containsEnchantment(Enchantment.LOOT_BONUS_MOBS))
            chance = Math.min(1, chance + rateModifier * event.getEntity().getKiller().getItemInHand().getEnchantmentLevel(Enchantment.LOOT_BONUS_MOBS));

        if(CraftBookPlugin.inst().getRandom().nextDouble() > chance)
            return;

        ItemStack toDrop = null;

        switch(event.getEntityType()) {

            case PLAYER:
                if(!enablePlayers)
                    return;
                String playerName = ((Player) event.getEntity()).getName();
                toDrop = new ItemStack(Material.SKULL_ITEM, 1, (short)3);
                SkullMeta meta = (SkullMeta) toDrop.getItemMeta();
                meta.setOwner(playerName);
                meta.setDisplayName(ChatColor.RESET + playerName + "'s Head");
                toDrop.setItemMeta(meta);
                break;
            case ZOMBIE:
                if(!enableMobs)
                    return;
                toDrop = new ItemStack(Material.SKULL_ITEM, 1, (short)2);
                break;
            case CREEPER:
                if(!enableMobs)
                    return;
                toDrop = new ItemStack(Material.SKULL_ITEM, 1, (short)4);
                break;
            case SKELETON:
                if(!enableMobs)
                    return;
                if(((Skeleton) event.getEntity()).getSkeletonType() == SkeletonType.WITHER && !overrideNatural)
                    return;
                toDrop = new ItemStack(Material.SKULL_ITEM, 1, (short) (((Skeleton) event.getEntity()).getSkeletonType() == SkeletonType.WITHER ? 1 : 0));
                break;
            default:
                if(!enableMobs)
                    return;
                MobSkullType type = MobSkullType.getFromEntityType(event.getEntityType());
                String mobName = null;
                if(type != null)
                    mobName = type.getPlayerName();
                if(customSkins.containsKey(typeName))
                    mobName = customSkins.get(typeName);
                if(mobName == null || mobName.isEmpty())
                    break;
                toDrop = new ItemStack(Material.SKULL_ITEM, 1, (short)3);
                ItemMeta metaD = toDrop.getItemMeta();
                if(metaD instanceof SkullMeta) {
                    SkullMeta itemMeta = (SkullMeta) metaD;
                    itemMeta.setDisplayName(ChatColor.RESET + typeName + " Head");
                    itemMeta.setOwner(mobName);
                    toDrop.setItemMeta(itemMeta);
                } else
                    CraftBookPlugin.logger().warning("Bukkit has failed to set a HeadDrop item to a head!");
                break;
        }

        if(ItemUtil.isStackValid(toDrop)) {
            event.getEntity().getWorld().dropItemNaturally(event.getEntity().getLocation(), toDrop);
        }
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void onPlayerInteract(PlayerInteractEvent event) {

        if(!EventUtil.passesFilter(event)) return;

        if(event.getAction() != Action.RIGHT_CLICK_BLOCK) return;

        if(event.getClickedBlock().getType() == Material.SKULL) {

            Skull skull = (Skull)event.getClickedBlock().getState();
            if(skull == null || !skull.hasOwner())
                return;

            LocalPlayer player = CraftBookPlugin.inst().wrapPlayer(event.getPlayer());

            if(showNameClick && MobSkullType.getEntityType(skull.getOwner()) == null) {
                player.printRaw(ChatColor.YELLOW + player.translate("mech.headdrops.click-message") + " " + skull.getOwner());
            } else if (MobSkullType.getEntityType(skull.getOwner()) != null) {
                skull.setOwner(MobSkullType.getFromEntityType(MobSkullType.getEntityType(skull.getOwner())).getPlayerName());
                skull.update();
            }
        }
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void onBlockBreak(BlockBreakEvent event) {

        if(!miningDrops) return;
        if(!EventUtil.passesFilter(event))
            return;
        if(event.getPlayer().getGameMode() == GameMode.CREATIVE) return;

        if(event.getBlock().getType() == Material.SKULL) {

            Skull skull = (Skull)event.getBlock().getState();
            if(!skull.hasOwner())
                return;
            String playerName = ChatColor.stripColor(skull.getOwner());
            LocalPlayer player = CraftBookPlugin.inst().wrapPlayer(event.getPlayer());

            EntityType type = MobSkullType.getEntityType(playerName);

            ItemStack stack = new ItemStack(Material.SKULL_ITEM, 1, (short)3);
            SkullMeta meta = (SkullMeta) stack.getItemMeta();
            meta.setOwner(playerName);

            if(type != null && !enableMobs)
                return;
            if(type == null && !enablePlayers)
                return;

            if(!event.getPlayer().hasPermission("craftbook.mech.headdrops.break")) {
                player.printError("mech.headdrops.break-permission");
                return;
            }

            if(type != null)
                meta.setDisplayName(ChatColor.RESET + StringUtils.replace(type.getName(), "_", " ") + " Head");
            else
                meta.setDisplayName(ChatColor.RESET + playerName + "'s Head");

            stack.setItemMeta(meta);

            if(!ProtectionUtil.canBuild(event.getPlayer(), event.getBlock(), false))
                return;

            event.setCancelled(true);
            event.getBlock().setType(Material.AIR);
            event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), stack);
        }
    }

    private enum MobSkullType {

        //Official
        BLAZE("MHF_Blaze", "Blaze_Head"),
        CAVE_SPIDER("MHF_CaveSpider"),
        CHICKEN("MHF_Chicken", "scraftbrothers1"),
        COW("MHF_Cow", "VerifiedBernard", "CarlosTheCow"),
        ENDERMAN("MHF_Enderman", "Violit"),
        GHAST("MHF_Ghast", "_QuBra_"),
        MAGMA_CUBE("MHF_LavaSlime"),
        MUSHROOM_COW("MHF_MushroomCow", "Mooshroom_Stew"),
        PIG("MHF_Pig", "XlexerX"),
        PIG_ZOMBIE("MHF_PigZombie", "ManBearPigZombie", "scraftbrothers5"),
        SHEEP("MHF_Sheep", "SGT_KICYORASS", "Eagle_Peak"),
        SLIME("MHF_Slime", "HappyHappyMan"),
        SPIDER("MHF_Spider", "Kelevra_V"),
        VILLAGER("MHF_Villager", "Villager", "Kuvase", "scraftbrothers9"),
        IRON_GOLEM("MHF_Golem", "zippie007"),
        SQUID("MHF_Squid", "squidette8"),
        OCELOT("MHF_Ocelot", "scraftbrothers3"),

        //Unofficial/Community
        BAT("coolwhip101", "bozzobrain"),
        ENDER_DRAGON("KingEndermen", "KingEnderman"),
        SILVERFISH("Xzomag", "AlexVMiner"),
        SNOWMAN("scraftbrothers2", "Koebasti"),
        HORSE("gavertoso"),
        WOLF("Budwolf"),
        WITCH("scrafbrothers4");

        MobSkullType(String playerName, String ... oldNames) {

            this.playerName = playerName;
            this.oldNames = new HashSet<String>(Arrays.asList(oldNames));
        }

        private String playerName;
        private Set<String> oldNames;

        public String getPlayerName() {

            return playerName;
        }

        public boolean isOldName(String name) {

            return oldNames.contains(name);
        }

        public static MobSkullType getFromEntityType(EntityType entType) {

            try {
                return MobSkullType.valueOf(entType.name());
            } catch(Exception e){
                return null;
            }
        }

        public static EntityType getEntityType(String name) {

            if (name == null)
                return null;

            for(MobSkullType type : values())
                if(type.getPlayerName().equalsIgnoreCase(name) || type.isOldName(name) || name.equalsIgnoreCase(instance.customSkins.get(EntityType.valueOf(type.name()).getName().toUpperCase())))
                    return EntityType.valueOf(type.name());

            return null;
        }
    }

    boolean enableMobs;
    boolean enablePlayers;
    boolean playerKillsOnly;
    boolean miningDrops;
    boolean overrideNatural;
    double dropRate;
    double rateModifier;
    boolean showNameClick;
    HashMap<String, Double> customDropRates;
    HashMap<String, String> customSkins;

    @Override
    public void loadConfiguration (YAMLProcessor config, String path) {

        config.setComment(path + "drop-mob-heads", "Allow the Head Drops mechanic to drop mob heads.");
        enableMobs = config.getBoolean(path + "drop-mob-heads", true);

        config.setComment(path + "drop-player-heads", "Allow the Head Drops mechanic to drop player heads.");
        enablePlayers = config.getBoolean(path + "drop-player-heads", true);

        config.setComment(path + "require-player-killed", "Only drop heads when killed by a player. Otherwise they will drop heads on any death.");
        playerKillsOnly = config.getBoolean(path + "require-player-killed", true);

        config.setComment(path + "drop-head-when-mined", "When enabled, heads keep their current skin when mined and are dropped accordingly.");
        miningDrops = config.getBoolean(path + "drop-head-when-mined", true);

        config.setComment(path + "override-natural-head-drops", "Override natural head drops, this will cause natural head drops to use the chances provided by CraftBook. (Eg, Wither Skeleton Heads)");
        overrideNatural = config.getBoolean(path + "override-natural-head-drops", false);

        config.setComment(path + "drop-rate", "A value between 1 and 0 which dictates the global chance of heads being dropped. This can be overridden per-entity type.");
        dropRate = config.getDouble(path + "drop-rate", 0.05);

        config.setComment(path + "looting-rate-modifier", "This amount is added to the chance for every looting level on an item. Eg, a chance of 0.05(5%) and a looting mod of 0.05(5%) on a looting 3 sword, would give a 0.20 chance (20%).");
        rateModifier = config.getDouble(path + "looting-rate-modifier", 0.05);

        config.setComment(path + "show-name-right-click", "When enabled, right clicking a placed head will say the owner of the head's skin.");
        showNameClick = config.getBoolean(path + "show-name-right-click", true);

        customDropRates = new HashMap<String, Double>();
        if(config.getKeys(path + "drop-rates") != null) {
            for(String key : config.getKeys(path + "drop-rates"))
                customDropRates.put(key.toUpperCase(), config.getDouble(path + "drop-rates." + key));
        } else
            config.addNode(path + "drop-rates");
        customSkins = new HashMap<String, String>();
        if(config.getKeys(path + "custom-mob-skins") != null) {
            for(String key : config.getKeys(path + "custom-mob-skins"))
                customSkins.put(key.toUpperCase(), config.getString(path + "custom-mob-skins." + key));
        } else
            config.addNode(path + "custom-mob-skins");
    }
}
TOP

Related Classes of com.sk89q.craftbook.mechanics.HeadDrops

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.