mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-04 11:03:43 +01:00 
			
		
		
		
	merge master + singleton removal on ParticleEffectUtils
This commit is contained in:
		@@ -203,6 +203,21 @@ Version 2.2.0
 | 
			
		||||
    Added API method to check if a skill was being level capped
 | 
			
		||||
    Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill
 | 
			
		||||
 | 
			
		||||
Version 2.1.115
 | 
			
		||||
    Cocoa plants now require GT of at least 2 to start at the second stage of growth
 | 
			
		||||
    Green Terra now boosts growth on Green Thumb by 1 stage (doesn't go above the maximum value though)
 | 
			
		||||
    Green Thumb now requires a hoe to activate
 | 
			
		||||
    You can sneak to break plants with a hoe in your hand (or just put the hoe away)
 | 
			
		||||
    Hoes no longer give free replants
 | 
			
		||||
    There is now a feature in place to prevent breaking a newly automatically replanted (via green thumb) crop from being breakable for a few seconds after it appears
 | 
			
		||||
    Using a hoe on non-fully grown crops will replant them as a convenience feature for those who can't bother to wait for all of their plants to grow (put away the hoe to break non-fully grown crops)
 | 
			
		||||
    Fixed a bug where Salvage always gave the best results
 | 
			
		||||
    Fixed an issue with arrows causing exceptions with players not yet having data loaded
 | 
			
		||||
    Spectral arrows are now tracked by mcMMO
 | 
			
		||||
    Use minimum level of salvageable properly
 | 
			
		||||
    Fix Axes Critical Strikes default permissions ( new fixed permission: mcmmo.ability.axes.criticalstrikes )
 | 
			
		||||
    Fix potential null pointer exception for salvage
 | 
			
		||||
 | 
			
		||||
Version 2.1.114
 | 
			
		||||
    Fix some more locale usages, should aim to further prevent issues with oddball locales
 | 
			
		||||
    Fixed a bug where newer versions of MySQL did not like our rank command
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@ public class ConfigSound {
 | 
			
		||||
        SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.TIRED, new SoundSetting(1.0, 1.7));
 | 
			
		||||
        SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.BLEED, new SoundSetting(2.0, 2.0));
 | 
			
		||||
        SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.GLASS, new SoundSetting(1.0, 1.0));
 | 
			
		||||
        SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.ITEM_CONSUMED, new SoundSetting(1.0, 2.0));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Setting(value = "Sound-Settings", comment = "Adjust sound settings for various mcMMO sounds here." +
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import org.bukkit.metadata.FixedMetadataValue;
 | 
			
		||||
public class MetadataConstants {
 | 
			
		||||
 | 
			
		||||
    /* Metadata Values */
 | 
			
		||||
    public static final String REPLANT_META_KEY = "mcMMO: Recently Replanted";
 | 
			
		||||
    public static final String FISH_HOOK_REF_METAKEY = "mcMMO: Fish Hook Tracker";
 | 
			
		||||
    public static final String DODGE_TRACKER        = "mcMMO: Dodge Tracker";
 | 
			
		||||
    public static final String CUSTOM_DAMAGE_METAKEY = "mcMMO: Custom Damage";
 | 
			
		||||
 
 | 
			
		||||
@@ -11,4 +11,5 @@ public class OldName extends FixedMetadataValue {
 | 
			
		||||
    public OldName(String oldName, mcMMO plugin) {
 | 
			
		||||
        super(plugin, oldName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,17 @@
 | 
			
		||||
package com.gmail.nossr50.datatypes.meta;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.metadata.FixedMetadataValue;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
public class RecentlyReplantedCropMeta extends FixedMetadataValue {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initializes a FixedMetadataValue with an Object
 | 
			
		||||
     *
 | 
			
		||||
     * @param owningPlugin the {@link Plugin} that created this metadata value
 | 
			
		||||
     */
 | 
			
		||||
    public RecentlyReplantedCropMeta(Plugin owningPlugin, Boolean recentlyPlanted) {
 | 
			
		||||
        super(owningPlugin, recentlyPlanted);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -39,6 +39,7 @@ import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.metadata.FixedMetadataValue;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,8 @@ public class HerbalismBehaviour {
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert blocks affected by the Green Thumb & Green Terra abilities.
 | 
			
		||||
     *
 | 
			
		||||
     * @param blockState The {@link BlockState} to check ability activation for
 | 
			
		||||
     * @param blockState
 | 
			
		||||
     *            The {@link BlockState} to check ability activation for
 | 
			
		||||
     * @return true if the ability was successful, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    public boolean convertGreenTerraBlocks(BlockState blockState) {
 | 
			
		||||
@@ -36,16 +37,16 @@ public class HerbalismBehaviour {
 | 
			
		||||
                blockState.setType(Material.MOSSY_STONE_BRICKS);
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            case DIRT:
 | 
			
		||||
            case GRASS_PATH:
 | 
			
		||||
            case DIRT :
 | 
			
		||||
            case GRASS_PATH :
 | 
			
		||||
                blockState.setType(Material.GRASS_BLOCK);
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            case COBBLESTONE:
 | 
			
		||||
            case COBBLESTONE :
 | 
			
		||||
                blockState.setType(Material.MOSSY_COBBLESTONE);
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
            default :
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -53,29 +54,21 @@ public class HerbalismBehaviour {
 | 
			
		||||
    /**
 | 
			
		||||
     * Convert blocks affected by the Green Thumb & Green Terra abilities.
 | 
			
		||||
     *
 | 
			
		||||
     * @param blockState The {@link BlockState} to check ability activation for
 | 
			
		||||
     * @param blockState
 | 
			
		||||
     *            The {@link BlockState} to check ability activation for
 | 
			
		||||
     * @return true if the ability was successful, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    public boolean convertShroomThumb(BlockState blockState) {
 | 
			
		||||
        switch (blockState.getType()) {
 | 
			
		||||
            case DIRT:
 | 
			
		||||
            case DIRT :
 | 
			
		||||
            case GRASS_BLOCK:
 | 
			
		||||
            case GRASS_PATH:
 | 
			
		||||
            case GRASS_PATH :
 | 
			
		||||
                blockState.setType(Material.MYCELIUM);
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
            default :
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if the block has a recently grown crop from Green Thumb
 | 
			
		||||
     *
 | 
			
		||||
     * @param blockState The {@link BlockState} to check green thumb regrown for
 | 
			
		||||
     * @return true if the block is recently regrown, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isRecentlyRegrown(BlockState blockState) {
 | 
			
		||||
        return blockState.hasMetadata(MetadataConstants.GREEN_THUMB_METAKEY) && !pluginRef.getSkillTools().cooldownExpired(blockState.getMetadata(MetadataConstants.GREEN_THUMB_METAKEY).get(0).asInt(), 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -370,7 +370,7 @@
 | 
			
		||||
//        int levelTotal = Misc.getRandom().nextInt(1 + pluginRef.getUserManager().getPlayer(player).getSkillLevel(PrimarySkillType.MINING)) + 1;
 | 
			
		||||
//        pluginRef.getSoundManager().sendSound(player, player.getLocation(), SoundType.LEVEL_UP);
 | 
			
		||||
//        mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.HOLIDAY, "Holiday.AprilFools.Levelup", StringUtils.getCapitalized(fakeSkillType.toString()), String.valueOf(levelTotal));
 | 
			
		||||
////        ParticleEffectUtils.fireworkParticleShower(player, ALL_COLORS.get(Misc.getRandom().nextInt(ALL_COLORS.size())));
 | 
			
		||||
////        pluginRef.getParticleEffectUtils().fireworkParticleShower(player, ALL_COLORS.get(Misc.getRandom().nextInt(ALL_COLORS.size())));
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    public void registerAprilCommand() {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,330 @@
 | 
			
		||||
//package com.gmail.nossr50.skills.salvage;
 | 
			
		||||
//
 | 
			
		||||
//import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
//import com.gmail.nossr50.config.Config;
 | 
			
		||||
//import com.gmail.nossr50.config.experience.ExperienceConfig;
 | 
			
		||||
//import com.gmail.nossr50.datatypes.interactions.NotificationType;
 | 
			
		||||
//import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
			
		||||
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
			
		||||
//import com.gmail.nossr50.datatypes.skills.SubSkillType;
 | 
			
		||||
//import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
//import com.gmail.nossr50.mcMMO;
 | 
			
		||||
//import com.gmail.nossr50.skills.SkillManager;
 | 
			
		||||
//import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
 | 
			
		||||
//import com.gmail.nossr50.util.EventUtils;
 | 
			
		||||
//import com.gmail.nossr50.util.Misc;
 | 
			
		||||
//import com.gmail.nossr50.util.Permissions;
 | 
			
		||||
//import com.gmail.nossr50.util.StringUtils;
 | 
			
		||||
//import com.gmail.nossr50.util.player.NotificationManager;
 | 
			
		||||
//import com.gmail.nossr50.util.random.RandomChanceSkillStatic;
 | 
			
		||||
//import com.gmail.nossr50.util.random.RandomChanceUtil;
 | 
			
		||||
//import com.gmail.nossr50.util.skills.RankUtils;
 | 
			
		||||
//import com.gmail.nossr50.util.skills.SkillUtils;
 | 
			
		||||
//import com.gmail.nossr50.util.sounds.SoundManager;
 | 
			
		||||
//import com.gmail.nossr50.util.sounds.SoundType;
 | 
			
		||||
//import org.bukkit.Location;
 | 
			
		||||
//import org.bukkit.Material;
 | 
			
		||||
//import org.bukkit.enchantments.Enchantment;
 | 
			
		||||
//import org.bukkit.entity.Player;
 | 
			
		||||
//import org.bukkit.inventory.ItemStack;
 | 
			
		||||
//import org.bukkit.inventory.meta.EnchantmentStorageMeta;
 | 
			
		||||
//
 | 
			
		||||
//import java.util.Map;
 | 
			
		||||
//import java.util.Map.Entry;
 | 
			
		||||
//
 | 
			
		||||
//public class SalvageManager extends SkillManager {
 | 
			
		||||
//    private boolean placedAnvil;
 | 
			
		||||
//    private int     lastClick;
 | 
			
		||||
//
 | 
			
		||||
//    public SalvageManager(McMMOPlayer mcMMOPlayer) {
 | 
			
		||||
//        super(mcMMOPlayer, PrimarySkillType.SALVAGE);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * Handles notifications for placing an anvil.
 | 
			
		||||
//     */
 | 
			
		||||
//    public void placedAnvilCheck() {
 | 
			
		||||
//        Player player = getPlayer();
 | 
			
		||||
//
 | 
			
		||||
//        if (getPlacedAnvil()) {
 | 
			
		||||
//            return;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        if (Config.getInstance().getSalvageAnvilMessagesEnabled()) {
 | 
			
		||||
//            NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Salvage.Listener.Anvil");
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        if (Config.getInstance().getSalvageAnvilPlaceSoundsEnabled()) {
 | 
			
		||||
//            SoundManager.sendSound(player, player.getLocation(), SoundType.ANVIL);
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        togglePlacedAnvil();
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    public void handleSalvage(Location location, ItemStack item) {
 | 
			
		||||
//        Player player = getPlayer();
 | 
			
		||||
//
 | 
			
		||||
//        Salvageable salvageable = mcMMO.getSalvageableManager().getSalvageable(item.getType());
 | 
			
		||||
//
 | 
			
		||||
//        if (item.getItemMeta() != null && item.getItemMeta().isUnbreakable()) {
 | 
			
		||||
//            NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Unbreakable");
 | 
			
		||||
//            return;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        // Permissions checks on material and item types
 | 
			
		||||
//        if (!Permissions.salvageItemType(player, salvageable.getSalvageItemType())) {
 | 
			
		||||
//            NotificationManager.sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
 | 
			
		||||
//            return;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        if (!Permissions.salvageMaterialType(player, salvageable.getSalvageMaterialType())) {
 | 
			
		||||
//            NotificationManager.sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
 | 
			
		||||
//            return;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        /*int skillLevel = getSkillLevel();*/
 | 
			
		||||
//        int minimumSalvageableLevel = salvageable.getMinimumLevel();
 | 
			
		||||
//
 | 
			
		||||
//        // Level check
 | 
			
		||||
//        if (getSkillLevel() < minimumSalvageableLevel) {
 | 
			
		||||
//            NotificationManager.sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Salvage.Skills.Adept.Level", String.valueOf(RankUtils.getUnlockLevel(SubSkillType.SALVAGE_ARCANE_SALVAGE)), StringUtils.getPrettyItemString(item.getType()));
 | 
			
		||||
//            return;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        int potentialSalvageYield = Salvage.calculateSalvageableAmount(item.getDurability(), salvageable.getMaximumDurability(), salvageable.getMaximumQuantity());
 | 
			
		||||
//
 | 
			
		||||
//        if (potentialSalvageYield <= 0) {
 | 
			
		||||
//            NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Salvage.Skills.TooDamaged");
 | 
			
		||||
//            return;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        potentialSalvageYield = Math.min(potentialSalvageYield, getSalvageLimit()); // Always get at least something back, if you're capable of salvaging it.
 | 
			
		||||
//
 | 
			
		||||
//        player.getInventory().setItemInMainHand(new ItemStack(Material.AIR));
 | 
			
		||||
//        location.add(0.5, 1, 0.5);
 | 
			
		||||
//
 | 
			
		||||
//        Map<Enchantment, Integer> enchants = item.getEnchantments();
 | 
			
		||||
//
 | 
			
		||||
//        ItemStack enchantBook = null;
 | 
			
		||||
//        if (!enchants.isEmpty()) {
 | 
			
		||||
//            enchantBook = arcaneSalvageCheck(enchants);
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        //Lottery on Salvageable Amount
 | 
			
		||||
//
 | 
			
		||||
//        int lotteryResults = 1;
 | 
			
		||||
//        int chanceOfSuccess = 99;
 | 
			
		||||
//
 | 
			
		||||
//        for(int x = 0; x < potentialSalvageYield-1; x++) {
 | 
			
		||||
//
 | 
			
		||||
//            if(RandomChanceUtil.rollDice(chanceOfSuccess, 100)) {
 | 
			
		||||
//                chanceOfSuccess-=3;
 | 
			
		||||
//                chanceOfSuccess = Math.max(chanceOfSuccess, 90);
 | 
			
		||||
//
 | 
			
		||||
//                lotteryResults+=1;
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        if(lotteryResults == potentialSalvageYield && potentialSalvageYield != 1 && RankUtils.isPlayerMaxRankInSubSkill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE)) {
 | 
			
		||||
//            NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.Lottery.Perfect", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType()));
 | 
			
		||||
//        } else if(salvageable.getMaximumQuantity() == 1 || getSalvageLimit() >= salvageable.getMaximumQuantity()) {
 | 
			
		||||
//            NotificationManager.sendPlayerInformationChatOnly(player,  "Salvage.Skills.Lottery.Normal", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType()));
 | 
			
		||||
//        } else {
 | 
			
		||||
//            NotificationManager.sendPlayerInformationChatOnly(player,  "Salvage.Skills.Lottery.Untrained", String.valueOf(lotteryResults), StringUtils.getPrettyItemString(item.getType()));
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        ItemStack salvageResults = new ItemStack(salvageable.getSalvageMaterial(), lotteryResults);
 | 
			
		||||
//
 | 
			
		||||
//        //Call event
 | 
			
		||||
//        if (EventUtils.callSalvageCheckEvent(player, item, salvageResults, enchantBook).isCancelled()) {
 | 
			
		||||
//            return;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        Location anvilLoc = location.clone();
 | 
			
		||||
//        Location playerLoc = player.getLocation().clone();
 | 
			
		||||
//        double distance = anvilLoc.distance(playerLoc);
 | 
			
		||||
//
 | 
			
		||||
//        double speedLimit = .6;
 | 
			
		||||
//        double minSpeed = .3;
 | 
			
		||||
//
 | 
			
		||||
//        //Clamp the speed and vary it by distance
 | 
			
		||||
//        double vectorSpeed = Math.min(speedLimit, Math.max(minSpeed, distance * .2));
 | 
			
		||||
//
 | 
			
		||||
//        //Add a very small amount of height
 | 
			
		||||
//        anvilLoc.add(0, .1, 0);
 | 
			
		||||
//
 | 
			
		||||
//        if (enchantBook != null) {
 | 
			
		||||
//            Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), enchantBook, vectorSpeed);
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), salvageResults, vectorSpeed);
 | 
			
		||||
//
 | 
			
		||||
//        // BWONG BWONG BWONG - CLUNK!
 | 
			
		||||
//        if (Config.getInstance().getSalvageAnvilUseSoundsEnabled()) {
 | 
			
		||||
//            SoundManager.sendSound(player, player.getLocation(), SoundType.ITEM_BREAK);
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Salvage.Skills.Success");
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /*public double getMaxSalvagePercentage() {
 | 
			
		||||
//        return Math.min((((Salvage.salvageMaxPercentage / Salvage.salvageMaxPercentageLevel) * getSkillLevel()) / 100.0D), Salvage.salvageMaxPercentage / 100.0D);
 | 
			
		||||
//    }*/
 | 
			
		||||
//
 | 
			
		||||
//    public int getSalvageLimit() {
 | 
			
		||||
//        return (RankUtils.getRank(getPlayer(), SubSkillType.SALVAGE_SCRAP_COLLECTOR));
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * Gets the Arcane Salvage rank
 | 
			
		||||
//     *
 | 
			
		||||
//     * @return the current Arcane Salvage rank
 | 
			
		||||
//     */
 | 
			
		||||
//    public int getArcaneSalvageRank() {
 | 
			
		||||
//        return RankUtils.getRank(getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /*public double getExtractFullEnchantChance() {
 | 
			
		||||
//        int skillLevel = getSkillLevel();
 | 
			
		||||
//
 | 
			
		||||
//        for (Tier tier : Tier.values()) {
 | 
			
		||||
//            if (skillLevel >= tier.getLevel()) {
 | 
			
		||||
//                return tier.getExtractFullEnchantChance();
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        return 0;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    public double getExtractPartialEnchantChance() {
 | 
			
		||||
//        int skillLevel = getSkillLevel();
 | 
			
		||||
//
 | 
			
		||||
//        for (Tier tier : Tier.values()) {
 | 
			
		||||
//            if (skillLevel >= tier.getLevel()) {
 | 
			
		||||
//                return tier.getExtractPartialEnchantChance();
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        return 0;
 | 
			
		||||
//    }*/
 | 
			
		||||
//
 | 
			
		||||
//    public double getExtractFullEnchantChance() {
 | 
			
		||||
//        if(Permissions.hasSalvageEnchantBypassPerk(getPlayer()))
 | 
			
		||||
//            return 100.0D;
 | 
			
		||||
//
 | 
			
		||||
//        return AdvancedConfig.getInstance().getArcaneSalvageExtractFullEnchantsChance(getArcaneSalvageRank());
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    public double getExtractPartialEnchantChance() {
 | 
			
		||||
//        return AdvancedConfig.getInstance().getArcaneSalvageExtractPartialEnchantsChance(getArcaneSalvageRank());
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    private ItemStack arcaneSalvageCheck(Map<Enchantment, Integer> enchants) {
 | 
			
		||||
//        Player player = getPlayer();
 | 
			
		||||
//
 | 
			
		||||
//        if (!RankUtils.hasUnlockedSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE) || !Permissions.arcaneSalvage(player)) {
 | 
			
		||||
//            NotificationManager.sendPlayerInformationChatOnly(player, "Salvage.Skills.ArcaneFailed");
 | 
			
		||||
//            return null;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        ItemStack book = new ItemStack(Material.ENCHANTED_BOOK);
 | 
			
		||||
//        EnchantmentStorageMeta enchantMeta = (EnchantmentStorageMeta) book.getItemMeta();
 | 
			
		||||
//
 | 
			
		||||
//        boolean downgraded = false;
 | 
			
		||||
//        int arcaneFailureCount = 0;
 | 
			
		||||
//
 | 
			
		||||
//        for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) {
 | 
			
		||||
//
 | 
			
		||||
//            int enchantLevel = enchant.getValue();
 | 
			
		||||
//
 | 
			
		||||
//            if(!ExperienceConfig.getInstance().allowUnsafeEnchantments()) {
 | 
			
		||||
//                if(enchantLevel > enchant.getKey().getMaxLevel()) {
 | 
			
		||||
//                    enchantLevel = enchant.getKey().getMaxLevel();
 | 
			
		||||
//                }
 | 
			
		||||
//            }
 | 
			
		||||
//
 | 
			
		||||
//            if (!Salvage.arcaneSalvageEnchantLoss
 | 
			
		||||
//                    || Permissions.hasSalvageEnchantBypassPerk(player)
 | 
			
		||||
//                    || RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractFullEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
 | 
			
		||||
//                enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel, true);
 | 
			
		||||
//            }
 | 
			
		||||
//            else if (enchantLevel > 1
 | 
			
		||||
//                    && Salvage.arcaneSalvageDowngrades
 | 
			
		||||
//                    && RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getExtractPartialEnchantChance(), getPlayer(), SubSkillType.SALVAGE_ARCANE_SALVAGE))) {
 | 
			
		||||
//                enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel - 1, true);
 | 
			
		||||
//                downgraded = true;
 | 
			
		||||
//            } else {
 | 
			
		||||
//                arcaneFailureCount++;
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        if(failedAllEnchants(arcaneFailureCount, enchants.entrySet().size()))
 | 
			
		||||
//        {
 | 
			
		||||
//            NotificationManager.sendPlayerInformationChatOnly(player,  "Salvage.Skills.ArcaneFailed");
 | 
			
		||||
//            return null;
 | 
			
		||||
//        } else if(downgraded)
 | 
			
		||||
//        {
 | 
			
		||||
//            NotificationManager.sendPlayerInformationChatOnly(player,  "Salvage.Skills.ArcanePartial");
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        book.setItemMeta(enchantMeta);
 | 
			
		||||
//        return book;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    private boolean failedAllEnchants(int arcaneFailureCount, int size) {
 | 
			
		||||
//        return arcaneFailureCount == size;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * Check if the player has tried to use an Anvil before.
 | 
			
		||||
//     * @param actualize
 | 
			
		||||
//     *
 | 
			
		||||
//     * @return true if the player has confirmed using an Anvil
 | 
			
		||||
//     */
 | 
			
		||||
//    public boolean checkConfirmation(boolean actualize) {
 | 
			
		||||
//        Player player = getPlayer();
 | 
			
		||||
//        long lastUse = getLastAnvilUse();
 | 
			
		||||
//
 | 
			
		||||
//        if (!SkillUtils.cooldownExpired(lastUse, 3) || !Config.getInstance().getSalvageConfirmRequired()) {
 | 
			
		||||
//            return true;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        if (!actualize) {
 | 
			
		||||
//            return false;
 | 
			
		||||
//        }
 | 
			
		||||
//
 | 
			
		||||
//        actualizeLastAnvilUse();
 | 
			
		||||
//
 | 
			
		||||
//        NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Skills.ConfirmOrCancel", LocaleLoader.getString("Salvage.Pretty.Name"));
 | 
			
		||||
//
 | 
			
		||||
//        return false;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /*
 | 
			
		||||
//     * Salvage Anvil Placement
 | 
			
		||||
//     */
 | 
			
		||||
//
 | 
			
		||||
//    public boolean getPlacedAnvil() {
 | 
			
		||||
//        return placedAnvil;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    public void togglePlacedAnvil() {
 | 
			
		||||
//        placedAnvil = !placedAnvil;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /*
 | 
			
		||||
//     * Salvage Anvil Usage
 | 
			
		||||
//     */
 | 
			
		||||
//
 | 
			
		||||
//    public int getLastAnvilUse() {
 | 
			
		||||
//        return lastClick;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    public void setLastAnvilUse(int value) {
 | 
			
		||||
//        lastClick = value;
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    public void actualizeLastAnvilUse() {
 | 
			
		||||
//        lastClick = (int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
 | 
			
		||||
//    }
 | 
			
		||||
//}
 | 
			
		||||
@@ -397,27 +397,24 @@ public class BlockListener implements Listener {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
 | 
			
		||||
        BlockState blockState = event.getBlock().getState();
 | 
			
		||||
        ItemStack heldItem = player.getInventory().getItemInMainHand();
 | 
			
		||||
 | 
			
		||||
        if (pluginRef.getDynamicSettingsManager().getSkillBehaviourManager().getHerbalismBehaviour().isRecentlyRegrown(blockState)) {
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (pluginRef.getItemTools().isSword(heldItem)) {
 | 
			
		||||
            HerbalismManager herbalismManager = pluginRef.getUserManager().getPlayer(player).getHerbalismManager();
 | 
			
		||||
                HerbalismManager herbalismManager = mcMMOPlayer.getHerbalismManager();
 | 
			
		||||
 | 
			
		||||
            if (herbalismManager.canUseHylianLuck()) {
 | 
			
		||||
                if (herbalismManager.processHylianLuck(blockState)) {
 | 
			
		||||
                    blockState.update(true);
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                } else if (blockState.getType() == Material.FLOWER_POT) {
 | 
			
		||||
                    blockState.setType(Material.AIR);
 | 
			
		||||
                    blockState.update(true);
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                if (herbalismManager.canUseHylianLuck()) {
 | 
			
		||||
                    if (herbalismManager.processHylianLuck(blockState)) {
 | 
			
		||||
                        blockState.update(true);
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                    } else if (blockState.getType() == Material.FLOWER_POT) {
 | 
			
		||||
                        blockState.setType(Material.AIR);
 | 
			
		||||
                        blockState.update(true);
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        /*else if (!heldItem.containsEnchantment(Enchantment.SILK_TOUCH)) {
 | 
			
		||||
            SmeltingManager smeltingManager = pluginRef.getUserManager().getPlayer(player).getSmeltingManager();
 | 
			
		||||
 
 | 
			
		||||
@@ -352,12 +352,15 @@ public class EntityListener implements Listener {
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    //Deflect checks
 | 
			
		||||
                    UnarmedManager unarmedManager = pluginRef.getUserManager().getPlayer(defendingPlayer).getUnarmedManager();
 | 
			
		||||
                    final McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(defendingPlayer);
 | 
			
		||||
                    if (mcMMOPlayer != null) {
 | 
			
		||||
                        UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager();
 | 
			
		||||
 | 
			
		||||
                    if (unarmedManager.canDeflect()) {
 | 
			
		||||
                        if(unarmedManager.deflectCheck()) {
 | 
			
		||||
                            event.setCancelled(true);
 | 
			
		||||
                            return;
 | 
			
		||||
                        if (unarmedManager.canDeflect()) {
 | 
			
		||||
                            if (unarmedManager.deflectCheck()) {
 | 
			
		||||
                                event.setCancelled(true);
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -40,10 +40,7 @@ import com.gmail.nossr50.util.player.PlayerLevelTools;
 | 
			
		||||
import com.gmail.nossr50.util.player.UserManager;
 | 
			
		||||
import com.gmail.nossr50.util.random.RandomChanceTools;
 | 
			
		||||
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
 | 
			
		||||
import com.gmail.nossr50.util.skills.CombatTools;
 | 
			
		||||
import com.gmail.nossr50.util.skills.PerkUtils;
 | 
			
		||||
import com.gmail.nossr50.util.skills.RankTools;
 | 
			
		||||
import com.gmail.nossr50.util.skills.SkillTools;
 | 
			
		||||
import com.gmail.nossr50.util.skills.*;
 | 
			
		||||
import com.gmail.nossr50.util.sounds.SoundManager;
 | 
			
		||||
import com.gmail.nossr50.worldguard.WorldGuardManager;
 | 
			
		||||
import com.gmail.nossr50.worldguard.WorldGuardUtils;
 | 
			
		||||
@@ -93,6 +90,7 @@ public class mcMMO extends JavaPlugin {
 | 
			
		||||
    private WorldGuardManager worldGuardManager;
 | 
			
		||||
 | 
			
		||||
    /* Not-Managers but my naming scheme sucks */
 | 
			
		||||
    private ParticleEffectUtils particleEffectUtils;
 | 
			
		||||
    private DatabaseManagerFactory databaseManagerFactory;
 | 
			
		||||
    private ChunkManagerFactory chunkManagerFactory;
 | 
			
		||||
    private CommandTools commandTools;
 | 
			
		||||
@@ -311,6 +309,9 @@ public class mcMMO extends JavaPlugin {
 | 
			
		||||
 | 
			
		||||
        //Init PerkUtils
 | 
			
		||||
        perkUtils = new PerkUtils(this);
 | 
			
		||||
 | 
			
		||||
        //Init particle effect utils
 | 
			
		||||
        particleEffectUtils = new ParticleEffectUtils(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -870,4 +871,8 @@ public class mcMMO extends JavaPlugin {
 | 
			
		||||
    public PlatformManager getPlatformManager() {
 | 
			
		||||
        return platformManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ParticleEffectUtils getParticleEffectUtils() {
 | 
			
		||||
        return particleEffectUtils;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -172,7 +172,7 @@ public class BleedTimerTask extends BukkitRunnable {
 | 
			
		||||
                //Play Bleed Sound
 | 
			
		||||
                pluginRef.getSoundManager().worldSendSound(target.getWorld(), target.getLocation(), SoundType.BLEED);
 | 
			
		||||
 | 
			
		||||
                ParticleEffectUtils.playBleedEffect(target);
 | 
			
		||||
                pluginRef.getParticleEffectUtils().playBleedEffect(target);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //Lower Bleed Ticks
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,101 @@
 | 
			
		||||
package com.gmail.nossr50.runnables.skills;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.core.MetadataConstants;
 | 
			
		||||
import com.gmail.nossr50.datatypes.meta.RecentlyReplantedCropMeta;
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
 | 
			
		||||
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.data.Ageable;
 | 
			
		||||
import org.bukkit.event.block.BlockBreakEvent;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
public class DelayedCropReplant extends BukkitRunnable {
 | 
			
		||||
 | 
			
		||||
    private final int desiredCropAge;
 | 
			
		||||
    private final Location cropLocation;
 | 
			
		||||
    private final Material cropMaterial;
 | 
			
		||||
    private boolean wasImmaturePlant;
 | 
			
		||||
    private final BlockBreakEvent blockBreakEvent;
 | 
			
		||||
    private final mcMMO pluginRef;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Replants a crop after a delay setting the age to desiredCropAge
 | 
			
		||||
     * @param cropState target {@link BlockState}
 | 
			
		||||
     * @param desiredCropAge desired age of the crop
 | 
			
		||||
     */
 | 
			
		||||
    public DelayedCropReplant(mcMMO pluginRef, BlockBreakEvent blockBreakEvent, BlockState cropState, int desiredCropAge, boolean wasImmaturePlant) {
 | 
			
		||||
        this.pluginRef = pluginRef;
 | 
			
		||||
        //The plant was either immature or something cancelled the event, therefor we need to treat it differently
 | 
			
		||||
        this.blockBreakEvent = blockBreakEvent;
 | 
			
		||||
        this.wasImmaturePlant = wasImmaturePlant;
 | 
			
		||||
        this.cropMaterial = cropState.getType();
 | 
			
		||||
        this.desiredCropAge = desiredCropAge;
 | 
			
		||||
        this.cropLocation = cropState.getLocation();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        Block cropBlock = cropLocation.getBlock();
 | 
			
		||||
        BlockState currentState = cropBlock.getState();
 | 
			
		||||
 | 
			
		||||
        //Remove the metadata marking the block as recently replanted
 | 
			
		||||
        new markPlantAsOld(blockBreakEvent.getBlock().getLocation()).runTaskLater(pluginRef, 20*5);
 | 
			
		||||
 | 
			
		||||
        if(blockBreakEvent.isCancelled()) {
 | 
			
		||||
            wasImmaturePlant = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Two kinds of air in Minecraft
 | 
			
		||||
        if(currentState.getType().equals(cropMaterial) || currentState.getType().equals(Material.AIR) || currentState.getType().equals(Material.CAVE_AIR)) {
 | 
			
		||||
//            if(currentState.getBlock().getRelative(BlockFace.DOWN))
 | 
			
		||||
            //The space is not currently occupied by a block so we can fill it
 | 
			
		||||
            cropBlock.setType(cropMaterial);
 | 
			
		||||
 | 
			
		||||
            //Get new state (necessary?)
 | 
			
		||||
            BlockState newState = cropBlock.getState();
 | 
			
		||||
//            newState.update();
 | 
			
		||||
 | 
			
		||||
            Ageable ageable = (Ageable) newState.getBlockData();
 | 
			
		||||
 | 
			
		||||
            //Crop age should always be 0 if the plant was immature
 | 
			
		||||
            if(wasImmaturePlant) {
 | 
			
		||||
                ageable.setAge(0);
 | 
			
		||||
            } else {
 | 
			
		||||
                //Otherwise make the plant the desired age
 | 
			
		||||
                ageable.setAge(desiredCropAge);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //Age the crop
 | 
			
		||||
            newState.setBlockData(ageable);
 | 
			
		||||
            newState.update(true);
 | 
			
		||||
 | 
			
		||||
            //Play an effect
 | 
			
		||||
            pluginRef.getParticleEffectUtils().playGreenThumbEffect(cropLocation);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private class markPlantAsOld extends BukkitRunnable {
 | 
			
		||||
 | 
			
		||||
        private final Location cropLoc;
 | 
			
		||||
 | 
			
		||||
        public markPlantAsOld(Location cropLoc) {
 | 
			
		||||
            this.cropLoc = cropLoc;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void run() {
 | 
			
		||||
            Block cropBlock = cropLoc.getBlock();
 | 
			
		||||
            if(cropBlock.getMetadata(MetadataConstants.REPLANT_META_KEY).size() > 0)
 | 
			
		||||
                cropBlock.setMetadata(MetadataConstants.REPLANT_META_KEY, new RecentlyReplantedCropMeta(pluginRef, false));
 | 
			
		||||
 | 
			
		||||
            pluginRef.getParticleEffectUtils().playFluxEffect(cropLocation);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -87,7 +87,7 @@ public class AcrobaticsManager extends SkillManager {
 | 
			
		||||
        Player player = getPlayer();
 | 
			
		||||
 | 
			
		||||
        if (!isFatal(modifiedDamage) && pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.ACROBATICS_DODGE, player)) {
 | 
			
		||||
            ParticleEffectUtils.playDodgeEffect(player);
 | 
			
		||||
            pluginRef.getParticleEffectUtils().playDodgeEffect(player);
 | 
			
		||||
 | 
			
		||||
            if (mcMMOPlayer.useChatNotifications()) {
 | 
			
		||||
                pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Combat.Proc");
 | 
			
		||||
 
 | 
			
		||||
@@ -143,7 +143,7 @@ public class AxesManager extends SkillManager {
 | 
			
		||||
 | 
			
		||||
        Player player = getPlayer();
 | 
			
		||||
 | 
			
		||||
        ParticleEffectUtils.playGreaterImpactEffect(target);
 | 
			
		||||
        pluginRef.getParticleEffectUtils().playGreaterImpactEffect(target);
 | 
			
		||||
        target.setVelocity(player.getLocation().getDirection().normalize().multiply(pluginRef.getConfigManager().getConfigAxes().getGreaterImpactKnockBackModifier()));
 | 
			
		||||
 | 
			
		||||
        if (mcMMOPlayer.useChatNotifications()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.BlockSnapshot;
 | 
			
		||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
 | 
			
		||||
import com.gmail.nossr50.datatypes.experience.XPGainSource;
 | 
			
		||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.meta.RecentlyReplantedCropMeta;
 | 
			
		||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
 | 
			
		||||
@@ -12,11 +13,15 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.ToolType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.behaviours.HerbalismBehaviour;
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.runnables.skills.DelayedCropReplant;
 | 
			
		||||
import com.gmail.nossr50.runnables.skills.DelayedHerbalismXPCheckTask;
 | 
			
		||||
import com.gmail.nossr50.runnables.skills.HerbalismBlockUpdaterTask;
 | 
			
		||||
import com.gmail.nossr50.skills.SkillManager;
 | 
			
		||||
import com.gmail.nossr50.util.StringUtils;
 | 
			
		||||
import com.gmail.nossr50.util.skills.SkillActivationType;
 | 
			
		||||
import com.gmail.nossr50.util.sounds.SoundManager;
 | 
			
		||||
import com.gmail.nossr50.util.sounds.SoundType;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.block.BlockFace;
 | 
			
		||||
@@ -134,6 +139,23 @@ public class HerbalismManager extends SkillManager {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Check if the plant was recently replanted
 | 
			
		||||
        if(blockBreakEvent.getBlock().getBlockData() instanceof Ageable) {
 | 
			
		||||
            Ageable ageableCrop = (Ageable) blockBreakEvent.getBlock().getBlockData();
 | 
			
		||||
 | 
			
		||||
            if(blockBreakEvent.getBlock().getMetadata(MetadataConstants.REPLANT_META_KEY).size() >= 1) {
 | 
			
		||||
                if(blockBreakEvent.getBlock().getMetadata(MetadataConstants.REPLANT_META_KEY).get(0).asBoolean()) {
 | 
			
		||||
                    if(isAgeableMature(ageableCrop)) {
 | 
			
		||||
                        blockBreakEvent.getBlock().removeMetadata(MetadataConstants.REPLANT_META_KEY, pluginRef);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        //Crop is recently replanted to back out of destroying it
 | 
			
		||||
                        blockBreakEvent.setCancelled(true);
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * There are single-block plants and multi-block plants in Minecraft
 | 
			
		||||
         * In order to give out proper rewards, we need to collect all blocks that would be broken from this event
 | 
			
		||||
@@ -142,6 +164,9 @@ public class HerbalismManager extends SkillManager {
 | 
			
		||||
        //Grab all broken blocks
 | 
			
		||||
        HashSet<Block> brokenBlocks = getBrokenHerbalismBlocks(blockBreakEvent);
 | 
			
		||||
 | 
			
		||||
        if(brokenBlocks.size() == 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        //Handle rewards, xp, ability interactions, etc
 | 
			
		||||
        processHerbalismOnBlocksBroken(blockBreakEvent, brokenBlocks);
 | 
			
		||||
    }
 | 
			
		||||
@@ -153,10 +178,19 @@ public class HerbalismManager extends SkillManager {
 | 
			
		||||
     */
 | 
			
		||||
    private void processHerbalismOnBlocksBroken(BlockBreakEvent blockBreakEvent, HashSet<Block> brokenPlants) {
 | 
			
		||||
        BlockState originalBreak = blockBreakEvent.getBlock().getState();
 | 
			
		||||
        boolean greenThumbActivated = false;
 | 
			
		||||
 | 
			
		||||
        //TODO: The design of Green Terra needs to change, this is a mess
 | 
			
		||||
        if(pluginRef.getPermissionTools().greenThumbPlant(getPlayer(), originalBreak.getType())) {
 | 
			
		||||
            processGreenThumbPlants(originalBreak, isGreenTerraActive());
 | 
			
		||||
            if(!getPlayer().isSneaking()) {
 | 
			
		||||
                greenThumbActivated = processGreenThumbPlants(originalBreak, blockBreakEvent, isGreenTerraActive());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //When replanting a immature crop we cancel the block break event and back out
 | 
			
		||||
        if(greenThumbActivated) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
@@ -339,9 +373,11 @@ public class HerbalismManager extends SkillManager {
 | 
			
		||||
                //Calculate XP
 | 
			
		||||
                if(plantData instanceof Ageable) {
 | 
			
		||||
                    Ageable plantAgeable = (Ageable) plantData;
 | 
			
		||||
 | 
			
		||||
                    if(isAgeableMature(plantAgeable) || isBizarreAgeable(plantData)) {
 | 
			
		||||
                        xpToReward += pluginRef.getDynamicSettingsManager().getExperienceManager().getHerbalismXp(brokenBlockNewState.getType());
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
                    xpToReward += pluginRef.getDynamicSettingsManager().getExperienceManager().getHerbalismXp(brokenPlantBlock.getType());
 | 
			
		||||
                }
 | 
			
		||||
@@ -437,8 +473,7 @@ public class HerbalismManager extends SkillManager {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private HashSet<Block> getBrokenChorusBlocks(BlockState originalBreak) {
 | 
			
		||||
        HashSet<Block> traversedBlocks = grabChorusTreeBrokenBlocksRecursive(originalBreak.getBlock(), new HashSet<>());
 | 
			
		||||
        return traversedBlocks;
 | 
			
		||||
        return grabChorusTreeBrokenBlocksRecursive(originalBreak.getBlock(), new HashSet<>());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private HashSet<Block> grabChorusTreeBrokenBlocksRecursive(Block currentBlock, HashSet<Block> traversed) {
 | 
			
		||||
@@ -565,6 +600,7 @@ public class HerbalismManager extends SkillManager {
 | 
			
		||||
     * @param blockState The {@link BlockState} to check ability activation for
 | 
			
		||||
     * @return true if the ability was successful, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    //TODO: Fix hylian luck? Do we give a #*$%?
 | 
			
		||||
    public boolean processHylianLuck(BlockState blockState) {
 | 
			
		||||
//        if (!pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.HERBALISM_HYLIAN_LUCK, getPlayer())) {
 | 
			
		||||
//            return false;
 | 
			
		||||
@@ -631,15 +667,38 @@ public class HerbalismManager extends SkillManager {
 | 
			
		||||
        return herbalismBehaviour.convertShroomThumb(blockState);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Starts the delayed replant task and turns
 | 
			
		||||
     * @param desiredCropAge the desired age of the crop
 | 
			
		||||
     * @param blockBreakEvent the {@link BlockBreakEvent} this crop was involved in
 | 
			
		||||
     * @param cropState the {@link BlockState} of the crop
 | 
			
		||||
     */
 | 
			
		||||
    private void startReplantTask(int desiredCropAge, BlockBreakEvent blockBreakEvent, BlockState cropState, boolean isImmature) {
 | 
			
		||||
        //Mark the plant as recently replanted to avoid accidental breakage
 | 
			
		||||
        new DelayedCropReplant(pluginRef, blockBreakEvent, cropState, desiredCropAge, isImmature).runTaskLater(pluginRef, 20 * 2);
 | 
			
		||||
        blockBreakEvent.getBlock().setMetadata(MetadataConstants.REPLANT_META_KEY, new RecentlyReplantedCropMeta(pluginRef, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Process the Green Thumb ability for plants.
 | 
			
		||||
     *
 | 
			
		||||
     * @param blockState The {@link BlockState} to check ability activation for
 | 
			
		||||
     * @param greenTerra boolean to determine if greenTerra is active or not
 | 
			
		||||
     */
 | 
			
		||||
    private void processGreenThumbPlants(BlockState blockState, boolean greenTerra) {
 | 
			
		||||
        if (!pluginRef.getBlockTools().isFullyGrown(blockState))
 | 
			
		||||
            return;
 | 
			
		||||
    private boolean processGreenThumbPlants(BlockState blockState, BlockBreakEvent blockBreakEvent, boolean greenTerra) {
 | 
			
		||||
        if(!pluginRef.getItemTools().isHoe(blockBreakEvent.getPlayer().getInventory().getItemInMainHand())) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        BlockData blockData = blockState.getBlockData();
 | 
			
		||||
 | 
			
		||||
        if (!(blockData instanceof Ageable)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ageable ageable = (Ageable) blockData;
 | 
			
		||||
 | 
			
		||||
        //If the ageable is NOT mature and the player is NOT using a hoe, abort
 | 
			
		||||
 | 
			
		||||
        Player player = getPlayer();
 | 
			
		||||
        PlayerInventory playerInventory = player.getInventory();
 | 
			
		||||
@@ -671,36 +730,49 @@ public class HerbalismManager extends SkillManager {
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                return;
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ItemStack seedStack = new ItemStack(seed);
 | 
			
		||||
 | 
			
		||||
        if (!greenTerra && !pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(player, SubSkillType.HERBALISM_GREEN_THUMB)) {
 | 
			
		||||
            return;
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!processGrowingPlants(blockState, greenTerra)) {
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (!playerInventory.containsAtLeast(seedStack, 1)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!pluginRef.getItemTools().isHoe(getPlayer().getInventory().getItemInMainHand())) {
 | 
			
		||||
            if (!playerInventory.containsAtLeast(seedStack, 1)) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            playerInventory.removeItem(seedStack);
 | 
			
		||||
            player.updateInventory(); // Needed until replacement available
 | 
			
		||||
        if (!processGrowingPlants(blockState, ageable, blockBreakEvent, greenTerra)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        new HerbalismBlockUpdaterTask(blockState).runTaskLater(pluginRef, 0);
 | 
			
		||||
        playerInventory.removeItem(seedStack);
 | 
			
		||||
        player.updateInventory(); // Needed until replacement available
 | 
			
		||||
        //Play sound
 | 
			
		||||
        pluginRef.getSoundManager().sendSound(player, player.getLocation(), SoundType.ITEM_CONSUMED);
 | 
			
		||||
        return true;
 | 
			
		||||
//        new HerbalismBlockUpdaterTask(blockState).runTaskLater(mcMMO.p, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean processGrowingPlants(BlockState blockState, boolean greenTerra) {
 | 
			
		||||
        int greenThumbStage = getGreenThumbStage();
 | 
			
		||||
    private boolean processGrowingPlants(BlockState blockState, Ageable ageable, BlockBreakEvent blockBreakEvent, boolean greenTerra) {
 | 
			
		||||
        //This check is needed
 | 
			
		||||
        if(isBizarreAgeable(ageable)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        blockState.setMetadata(MetadataConstants.GREEN_THUMB_METAKEY, new FixedMetadataValue(pluginRef, (int) (System.currentTimeMillis() / pluginRef.getMiscTools().TIME_CONVERSION_FACTOR)));
 | 
			
		||||
        Ageable crops = (Ageable) blockState.getBlockData();
 | 
			
		||||
        int finalAge = 0;
 | 
			
		||||
        int greenThumbStage = getGreenThumbStage(greenTerra);
 | 
			
		||||
 | 
			
		||||
        //Immature plants will start over at 0
 | 
			
		||||
        if(!isAgeableMature(ageable)) {
 | 
			
		||||
//            blockBreakEvent.setCancelled(true);
 | 
			
		||||
            startReplantTask(0, blockBreakEvent, blockState, true);
 | 
			
		||||
//            blockState.setType(Material.AIR);
 | 
			
		||||
            blockBreakEvent.setDropItems(false);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (blockState.getType()) {
 | 
			
		||||
 | 
			
		||||
@@ -708,42 +780,47 @@ public class HerbalismManager extends SkillManager {
 | 
			
		||||
            case CARROTS:
 | 
			
		||||
            case WHEAT:
 | 
			
		||||
 | 
			
		||||
                if (greenTerra) {
 | 
			
		||||
                    crops.setAge(3);
 | 
			
		||||
                } else {
 | 
			
		||||
                    crops.setAge(greenThumbStage);
 | 
			
		||||
                }
 | 
			
		||||
                    finalAge = getGreenThumbStage(greenTerra);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case BEETROOTS:
 | 
			
		||||
            case NETHER_WART:
 | 
			
		||||
 | 
			
		||||
                if (greenTerra || greenThumbStage > 2) {
 | 
			
		||||
                    crops.setAge(2);
 | 
			
		||||
                } else if (greenThumbStage == 2) {
 | 
			
		||||
                    crops.setAge(1);
 | 
			
		||||
                } else {
 | 
			
		||||
                    crops.setAge(0);
 | 
			
		||||
                    finalAge = 2;
 | 
			
		||||
                }
 | 
			
		||||
                else if (greenThumbStage == 2) {
 | 
			
		||||
                    finalAge = 1;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    finalAge = 0;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case COCOA:
 | 
			
		||||
 | 
			
		||||
                if (greenTerra || getGreenThumbStage() > 1) {
 | 
			
		||||
                    crops.setAge(1);
 | 
			
		||||
                } else {
 | 
			
		||||
                    crops.setAge(0);
 | 
			
		||||
                if (getGreenThumbStage(greenTerra) >= 2) {
 | 
			
		||||
                    finalAge = 1;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    finalAge = 0;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
        blockState.setBlockData(crops);
 | 
			
		||||
 | 
			
		||||
        //Start the delayed replant
 | 
			
		||||
        startReplantTask(finalAge, blockBreakEvent, blockState, false);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private int getGreenThumbStage() {
 | 
			
		||||
    private int getGreenThumbStage(boolean greenTerraActive) {
 | 
			
		||||
        if(greenTerraActive)
 | 
			
		||||
            return Math.min(pluginRef.getRankTools().getHighestRank(SubSkillType.HERBALISM_GREEN_THUMB),
 | 
			
		||||
                    pluginRef.getRankTools().getRank(getPlayer(), SubSkillType.HERBALISM_GREEN_THUMB) + 1);
 | 
			
		||||
 | 
			
		||||
        return pluginRef.getRankTools().getRank(getPlayer(), SubSkillType.HERBALISM_GREEN_THUMB);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -208,7 +208,7 @@ public class TamingManager extends SkillManager {
 | 
			
		||||
        if(!pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(pluginRef, pluginRef.getDynamicSettingsManager().getSkillPropertiesManager().getStaticChance(SubSkillType.TAMING_PUMMEL), getPlayer(), SubSkillType.TAMING_PUMMEL)))
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        ParticleEffectUtils.playGreaterImpactEffect(target);
 | 
			
		||||
        pluginRef.getParticleEffectUtils().playGreaterImpactEffect(target);
 | 
			
		||||
        target.setVelocity(wolf.getLocation().getDirection().normalize().multiply(1.5D));
 | 
			
		||||
 | 
			
		||||
        if (target instanceof Player) {
 | 
			
		||||
@@ -381,7 +381,7 @@ public class TamingManager extends SkillManager {
 | 
			
		||||
        callOfWildEntity.setCustomName(pluginRef.getLocaleManager().getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(entityType)));
 | 
			
		||||
 | 
			
		||||
        //Particle effect
 | 
			
		||||
        ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity);
 | 
			
		||||
        pluginRef.getParticleEffectUtils().playCallOfTheWildEffect(callOfWildEntity);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void spawnHorse(Location spawnLocation) {
 | 
			
		||||
@@ -408,7 +408,7 @@ public class TamingManager extends SkillManager {
 | 
			
		||||
        callOfWildEntity.setCustomName(pluginRef.getLocaleManager().getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(EntityType.HORSE)));
 | 
			
		||||
 | 
			
		||||
        //Particle effect
 | 
			
		||||
        ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity);
 | 
			
		||||
        pluginRef.getParticleEffectUtils().playCallOfTheWildEffect(callOfWildEntity);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void setBaseCOTWEntityProperties(LivingEntity callOfWildEntity) {
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ public class TrackedTamingEntity extends BukkitRunnable {
 | 
			
		||||
        if (livingEntity.isValid()) {
 | 
			
		||||
            Location location = livingEntity.getLocation();
 | 
			
		||||
            location.getWorld().playSound(location, Sound.BLOCK_FIRE_EXTINGUISH, 0.8F, 0.8F);
 | 
			
		||||
            ParticleEffectUtils.playCallOfTheWildEffect(livingEntity);
 | 
			
		||||
            pluginRef.getParticleEffectUtils().playCallOfTheWildEffect(livingEntity);
 | 
			
		||||
            pluginRef.getCombatTools().dealDamage(livingEntity, livingEntity.getMaxHealth(), EntityDamageEvent.DamageCause.SUICIDE, livingEntity);
 | 
			
		||||
 | 
			
		||||
            if(tamingManagerRef != null)
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import org.bukkit.OfflinePlayer;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.metadata.FixedMetadataValue;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
@@ -51,9 +52,11 @@ public final class UserManager {
 | 
			
		||||
    public void remove(Player player) {
 | 
			
		||||
        McMMOPlayer mcMMOPlayer = getPlayer(player);
 | 
			
		||||
        player.removeMetadata(MetadataConstants.PLAYER_DATA_METAKEY, pluginRef);
 | 
			
		||||
        mcMMOPlayer.cleanup();
 | 
			
		||||
 | 
			
		||||
        if(playerDataSet != null && playerDataSet.contains(mcMMOPlayer)) {
 | 
			
		||||
        if(mcMMOPlayer != null)
 | 
			
		||||
            mcMMOPlayer.cleanup();
 | 
			
		||||
 | 
			
		||||
        if(playerDataSet != null) {
 | 
			
		||||
            playerDataSet.remove(mcMMOPlayer); //Clear sync save tracking
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -114,10 +117,12 @@ public final class UserManager {
 | 
			
		||||
     * @param playerName The name of the player whose McMMOPlayer to retrieve
 | 
			
		||||
     * @return the player's McMMOPlayer object
 | 
			
		||||
     */
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public McMMOPlayer getPlayer(String playerName) {
 | 
			
		||||
        return retrieveMcMMOPlayer(playerName, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public McMMOPlayer getOfflinePlayer(OfflinePlayer player) {
 | 
			
		||||
        if (player instanceof Player) {
 | 
			
		||||
            return getPlayer((Player) player);
 | 
			
		||||
@@ -136,6 +141,7 @@ public final class UserManager {
 | 
			
		||||
     * @param player target player
 | 
			
		||||
     * @return McMMOPlayer object for this player, null if Player has not been loaded
 | 
			
		||||
     */
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public McMMOPlayer getPlayer(Player player) {
 | 
			
		||||
        //Avoid Array Index out of bounds
 | 
			
		||||
        if (player != null && player.hasMetadata(MetadataConstants.PLAYER_DATA_METAKEY))
 | 
			
		||||
@@ -144,6 +150,7 @@ public final class UserManager {
 | 
			
		||||
            return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
    private McMMOPlayer retrieveMcMMOPlayer(String playerName, boolean offlineValid) {
 | 
			
		||||
        Player player = pluginRef.getServer().getPlayerExact(playerName);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -222,7 +222,7 @@ public final class CombatTools {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void processArcheryCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event, Arrow arrow) {
 | 
			
		||||
    private void processArcheryCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event, Projectile arrow) {
 | 
			
		||||
        double initialDamage = event.getDamage();
 | 
			
		||||
 | 
			
		||||
        McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
 | 
			
		||||
@@ -376,8 +376,9 @@ public final class CombatTools {
 | 
			
		||||
                    processTamingCombat(target, master, wolf, event);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else if (entityType == EntityType.ARROW) {
 | 
			
		||||
            Arrow arrow = (Arrow) damager;
 | 
			
		||||
        }
 | 
			
		||||
        else if (entityType == EntityType.ARROW || entityType == EntityType.SPECTRAL_ARROW) {
 | 
			
		||||
            Projectile arrow = (Projectile) damager;
 | 
			
		||||
            ProjectileSource projectileSource = arrow.getShooter();
 | 
			
		||||
 | 
			
		||||
            if (projectileSource instanceof Player && pluginRef.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.ARCHERY, target)) {
 | 
			
		||||
@@ -407,11 +408,9 @@ public final class CombatTools {
 | 
			
		||||
        if (metadataValue.size() <= 0)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (metadataValue != null) {
 | 
			
		||||
            OldName oldName = (OldName) metadataValue.get(0);
 | 
			
		||||
            entity.setCustomName(oldName.asString());
 | 
			
		||||
            entity.setCustomNameVisible(false);
 | 
			
		||||
        }
 | 
			
		||||
        OldName oldName = (OldName) metadataValue.get(0);
 | 
			
		||||
        entity.setCustomName(oldName.asString());
 | 
			
		||||
        entity.setCustomNameVisible(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,8 @@
 | 
			
		||||
package com.gmail.nossr50.util.skills;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.util.sounds.SoundManager;
 | 
			
		||||
import com.gmail.nossr50.util.sounds.SoundType;
 | 
			
		||||
import org.bukkit.Effect;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
@@ -11,10 +14,19 @@ import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
public final class ParticleEffectUtils {
 | 
			
		||||
 | 
			
		||||
    private ParticleEffectUtils() {
 | 
			
		||||
    private final mcMMO pluginRef;
 | 
			
		||||
 | 
			
		||||
    public ParticleEffectUtils(mcMMO pluginRef) {
 | 
			
		||||
        this.pluginRef = pluginRef;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void playBleedEffect(LivingEntity livingEntity) {
 | 
			
		||||
    public void playGreenThumbEffect(Location location) {
 | 
			
		||||
        World world = location.getWorld();
 | 
			
		||||
        playSmokeEffect(location);
 | 
			
		||||
        pluginRef.getSoundManager().worldSendSoundMaxPitch(world, location, SoundType.POP);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void playBleedEffect(LivingEntity livingEntity) {
 | 
			
		||||
        /*if (!MainConfig.getInstance().getBleedEffectEnabled()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }*/
 | 
			
		||||
@@ -22,15 +34,15 @@ public final class ParticleEffectUtils {
 | 
			
		||||
        livingEntity.getWorld().playEffect(livingEntity.getEyeLocation(), Effect.STEP_SOUND, Material.REDSTONE_WIRE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void playDodgeEffect(Player player) {
 | 
			
		||||
    public void playDodgeEffect(Player player) {
 | 
			
		||||
        /*if (!MainConfig.getInstance().getDodgeEffectEnabled()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }*/
 | 
			
		||||
 | 
			
		||||
        playSmokeEffect(player);
 | 
			
		||||
        playSmokeEffect(player.getLocation());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void playFluxEffect(Location location) {
 | 
			
		||||
    public void playFluxEffect(Location location) {
 | 
			
		||||
        /*if (!MainConfig.getInstance().getFluxEffectEnabled()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }*/
 | 
			
		||||
@@ -38,9 +50,8 @@ public final class ParticleEffectUtils {
 | 
			
		||||
        location.getWorld().playEffect(location, Effect.MOBSPAWNER_FLAMES, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void playSmokeEffect(LivingEntity livingEntity) {
 | 
			
		||||
        Location location = livingEntity.getEyeLocation();
 | 
			
		||||
        World world = livingEntity.getWorld();
 | 
			
		||||
    public void playSmokeEffect(Location location) {
 | 
			
		||||
        World world = location.getWorld();
 | 
			
		||||
 | 
			
		||||
        // Have to do it this way, because not all block directions are valid for smoke
 | 
			
		||||
        world.playEffect(location, Effect.SMOKE, BlockFace.SOUTH_EAST);
 | 
			
		||||
@@ -54,7 +65,7 @@ public final class ParticleEffectUtils {
 | 
			
		||||
        world.playEffect(location, Effect.SMOKE, BlockFace.NORTH_WEST);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void playGreaterImpactEffect(LivingEntity livingEntity) {
 | 
			
		||||
    public void playGreaterImpactEffect(LivingEntity livingEntity) {
 | 
			
		||||
        /*if (!MainConfig.getInstance().getGreaterImpactEffectEnabled()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }*/
 | 
			
		||||
@@ -64,7 +75,7 @@ public final class ParticleEffectUtils {
 | 
			
		||||
        livingEntity.getWorld().createExplosion(location.getX(), location.getY(), location.getZ(), 0F, false, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void playCallOfTheWildEffect(LivingEntity livingEntity) {
 | 
			
		||||
    public void playCallOfTheWildEffect(LivingEntity livingEntity) {
 | 
			
		||||
        /*if (!MainConfig.getInstance().getCallOfTheWildEffectEnabled()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }*/
 | 
			
		||||
@@ -87,7 +98,7 @@ public final class ParticleEffectUtils {
 | 
			
		||||
        firework.setFireworkMeta(fireworkMeta);
 | 
			
		||||
    }*/
 | 
			
		||||
 | 
			
		||||
    private static boolean hasHeadRoom(Player player) {
 | 
			
		||||
    private boolean hasHeadRoom(Player player) {
 | 
			
		||||
        boolean hasHeadRoom = true;
 | 
			
		||||
        Block headBlock = player.getEyeLocation().getBlock();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,11 @@ public class SoundManager {
 | 
			
		||||
            world.playSound(location, getSound(soundType), getVolume(soundType), getPitch(soundType));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void worldSendSoundMaxPitch(World world, Location location, SoundType soundType) {
 | 
			
		||||
        if(pluginRef.getConfigManager().getConfigSound().isSoundEnabled(soundType))
 | 
			
		||||
            world.playSound(location, getSound(soundType), getVolume(soundType), 2.0F);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * All volume is multiplied by the master volume to get its final value
 | 
			
		||||
     *
 | 
			
		||||
@@ -95,6 +100,8 @@ public class SoundManager {
 | 
			
		||||
                return Sound.ENTITY_ENDER_EYE_DEATH;
 | 
			
		||||
            case GLASS:
 | 
			
		||||
                return Sound.BLOCK_GLASS_BREAK;
 | 
			
		||||
            case ITEM_CONSUMED:
 | 
			
		||||
                return Sound.ITEM_BOTTLE_EMPTY;
 | 
			
		||||
            default:
 | 
			
		||||
                return null;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ public enum SoundType {
 | 
			
		||||
    ABILITY_ACTIVATED_BERSERK,
 | 
			
		||||
    BLEED,
 | 
			
		||||
    GLASS,
 | 
			
		||||
    ITEM_CONSUMED,
 | 
			
		||||
    TIRED;
 | 
			
		||||
 | 
			
		||||
    public boolean usesCustomPitch() {
 | 
			
		||||
 
 | 
			
		||||
@@ -261,7 +261,7 @@ permissions:
 | 
			
		||||
        description: Allows access to all Axes abilities
 | 
			
		||||
        children:
 | 
			
		||||
            mcmmo.ability.axes.axemastery: true
 | 
			
		||||
            mcmmo.ability.axes.criticalhit: true
 | 
			
		||||
            mcmmo.ability.axes.criticalstrikes: true
 | 
			
		||||
            mcmmo.ability.axes.greaterimpact: true
 | 
			
		||||
            mcmmo.ability.axes.armorimpact: true
 | 
			
		||||
            mcmmo.ability.axes.skullsplitter: true
 | 
			
		||||
@@ -270,8 +270,8 @@ permissions:
 | 
			
		||||
        description: Adds damage to axes
 | 
			
		||||
    mcmmo.ability.axes.axemastery:
 | 
			
		||||
        description: Allows bonus damage from Axes
 | 
			
		||||
    mcmmo.ability.axes.criticalhit:
 | 
			
		||||
        description: Allows access to the Critical Hit ability
 | 
			
		||||
    mcmmo.ability.axes.criticalstrikes:
 | 
			
		||||
        description: Allows access to the Critical Strikes ability
 | 
			
		||||
    mcmmo.ability.axes.greaterimpact:
 | 
			
		||||
        description: Allows access to the Greater Impact ability
 | 
			
		||||
    mcmmo.ability.axes.armorimpact:
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,10 @@ Sounds:
 | 
			
		||||
    # 1.0 = Max volume
 | 
			
		||||
    # 0.0 = No Volume
 | 
			
		||||
    MasterVolume: 1.0
 | 
			
		||||
    ITEM_CONSUMED:
 | 
			
		||||
        Enable: true
 | 
			
		||||
        Volume: 1.0
 | 
			
		||||
        Pitch: 1.0
 | 
			
		||||
    GLASS:
 | 
			
		||||
        Enable: true
 | 
			
		||||
        Volume: 1.0
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user