mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-04 02:53:43 +01:00 
			
		
		
		
	Initial work on crossbows
This commit is contained in:
		@@ -17,6 +17,7 @@ Version 2.1.133
 | 
				
			|||||||
    Smelting now has a Bonus Drops section in config.yml
 | 
					    Smelting now has a Bonus Drops section in config.yml
 | 
				
			||||||
    Second Smelt now only doubles smelting results for items which have bonus drop entries in the config
 | 
					    Second Smelt now only doubles smelting results for items which have bonus drop entries in the config
 | 
				
			||||||
    Fixed an array out of index bug for inventory click events
 | 
					    Fixed an array out of index bug for inventory click events
 | 
				
			||||||
 | 
					    mcMMO will now register arrows shot from the offhand as being from either Archery or Crossbows (before mcMMO ignored offhand Archery)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    (These permissions are all included in the mcmmo.defaults node)
 | 
					    (These permissions are all included in the mcmmo.defaults node)
 | 
				
			||||||
    New permission node 'mcmmo.commands.tridents'
 | 
					    New permission node 'mcmmo.commands.tridents'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					package com.gmail.nossr50.datatypes.meta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.bukkit.metadata.FixedMetadataValue;
 | 
				
			||||||
 | 
					import org.bukkit.plugin.Plugin;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ProjectileOriginMeta extends FixedMetadataValue {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Initializes a FixedMetadataValue with an Object
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param owningPlugin the {@link Plugin} that created this metadata value
 | 
				
			||||||
 | 
					     * @param value        the value assigned to this metadata value
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public ProjectileOriginMeta(@NotNull Plugin owningPlugin, int value) {
 | 
				
			||||||
 | 
					        super(owningPlugin, value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -4,6 +4,7 @@ import com.gmail.nossr50.config.AdvancedConfig;
 | 
				
			|||||||
import com.gmail.nossr50.config.Config;
 | 
					import com.gmail.nossr50.config.Config;
 | 
				
			||||||
import com.gmail.nossr50.config.WorldBlacklist;
 | 
					import com.gmail.nossr50.config.WorldBlacklist;
 | 
				
			||||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
 | 
					import com.gmail.nossr50.config.experience.ExperienceConfig;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.datatypes.meta.ProjectileOriginMeta;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
					import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
 | 
					import com.gmail.nossr50.datatypes.skills.SubSkillType;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.skills.subskills.interfaces.InteractType;
 | 
					import com.gmail.nossr50.datatypes.skills.subskills.interfaces.InteractType;
 | 
				
			||||||
@@ -19,6 +20,7 @@ import com.gmail.nossr50.skills.taming.Taming;
 | 
				
			|||||||
import com.gmail.nossr50.skills.taming.TamingManager;
 | 
					import com.gmail.nossr50.skills.taming.TamingManager;
 | 
				
			||||||
import com.gmail.nossr50.skills.unarmed.UnarmedManager;
 | 
					import com.gmail.nossr50.skills.unarmed.UnarmedManager;
 | 
				
			||||||
import com.gmail.nossr50.util.BlockUtils;
 | 
					import com.gmail.nossr50.util.BlockUtils;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.util.ItemUtils;
 | 
				
			||||||
import com.gmail.nossr50.util.Misc;
 | 
					import com.gmail.nossr50.util.Misc;
 | 
				
			||||||
import com.gmail.nossr50.util.Permissions;
 | 
					import com.gmail.nossr50.util.Permissions;
 | 
				
			||||||
import com.gmail.nossr50.util.player.NotificationManager;
 | 
					import com.gmail.nossr50.util.player.NotificationManager;
 | 
				
			||||||
@@ -122,7 +124,7 @@ public class EntityListener implements Listener {
 | 
				
			|||||||
        projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, projectile.getLocation()));
 | 
					        projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, projectile.getLocation()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
 | 
					    @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
 | 
				
			||||||
    public void onProjectileLaunch(ProjectileLaunchEvent event) {
 | 
					    public void onProjectileLaunch(ProjectileLaunchEvent event) {
 | 
				
			||||||
        /* WORLD BLACKLIST CHECK */
 | 
					        /* WORLD BLACKLIST CHECK */
 | 
				
			||||||
        if(WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
 | 
					        if(WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
 | 
				
			||||||
@@ -144,9 +146,19 @@ public class EntityListener implements Listener {
 | 
				
			|||||||
            if(!(projectile instanceof Arrow))
 | 
					            if(!(projectile instanceof Arrow))
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            projectile.setMetadata(mcMMO.bowForceKey, new FixedMetadataValue(plugin, 1.0));
 | 
					 | 
				
			||||||
            projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, projectile.getLocation()));
 | 
					            projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(plugin, projectile.getLocation()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //Track origin of projectile
 | 
				
			||||||
 | 
					            if(ItemUtils.hasItemInMainHand(player, "bow")) {
 | 
				
			||||||
 | 
					                markProjectileOriginAsBow(projectile);
 | 
				
			||||||
 | 
					            } else if(ItemUtils.hasItemInMainHand(player, "crossbow")) {
 | 
				
			||||||
 | 
					                markProjectileOriginAsCrossbow(projectile);
 | 
				
			||||||
 | 
					            } else if(ItemUtils.hasItemInOffHand(player, "bow")) {
 | 
				
			||||||
 | 
					                markProjectileOriginAsBow(projectile);
 | 
				
			||||||
 | 
					            } else if(ItemUtils.hasItemInOffHand(player, "crossbow")) {
 | 
				
			||||||
 | 
					                markProjectileOriginAsCrossbow(projectile);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for(Enchantment enchantment : player.getInventory().getItemInMainHand().getEnchantments().keySet()) {
 | 
					            for(Enchantment enchantment : player.getInventory().getItemInMainHand().getEnchantments().keySet()) {
 | 
				
			||||||
                if(enchantment.getName().equalsIgnoreCase("piercing"))
 | 
					                if(enchantment.getName().equalsIgnoreCase("piercing"))
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
@@ -158,6 +170,14 @@ public class EntityListener implements Listener {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void markProjectileOriginAsCrossbow(Projectile projectile) {
 | 
				
			||||||
 | 
					        projectile.setMetadata(mcMMO.PROJECTILE_ORIGIN_METAKEY, new ProjectileOriginMeta(plugin, 2));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void markProjectileOriginAsBow(Projectile projectile) {
 | 
				
			||||||
 | 
					        projectile.setMetadata(mcMMO.PROJECTILE_ORIGIN_METAKEY, new ProjectileOriginMeta(plugin, 1));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Monitor EntityChangeBlock events.
 | 
					     * Monitor EntityChangeBlock events.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -134,6 +134,7 @@ public class mcMMO extends JavaPlugin {
 | 
				
			|||||||
    public final static String greenThumbDataKey   = "mcMMO: Green Thumb";
 | 
					    public final static String greenThumbDataKey   = "mcMMO: Green Thumb";
 | 
				
			||||||
    public final static String databaseCommandKey  = "mcMMO: Processing Database Command";
 | 
					    public final static String databaseCommandKey  = "mcMMO: Processing Database Command";
 | 
				
			||||||
    public final static String bredMetadataKey     = "mcMMO: Bred Animal";
 | 
					    public final static String bredMetadataKey     = "mcMMO: Bred Animal";
 | 
				
			||||||
 | 
					    public final static String PROJECTILE_ORIGIN_METAKEY = "mcMMO: Projectile Origin";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static FixedMetadataValue metadataValue;
 | 
					    public static FixedMetadataValue metadataValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,10 +2,38 @@ package com.gmail.nossr50.skills.crossbows;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
					import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
					import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.mcMMO;
 | 
				
			||||||
import com.gmail.nossr50.skills.SkillManager;
 | 
					import com.gmail.nossr50.skills.SkillManager;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.skills.archery.Archery;
 | 
				
			||||||
 | 
					import org.bukkit.Location;
 | 
				
			||||||
 | 
					import org.bukkit.entity.Entity;
 | 
				
			||||||
 | 
					import org.bukkit.entity.LivingEntity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class CrossbowManager extends SkillManager {
 | 
					public class CrossbowManager extends SkillManager {
 | 
				
			||||||
    public CrossbowManager(McMMOPlayer mcMMOPlayer) {
 | 
					    public CrossbowManager(McMMOPlayer mcMMOPlayer) {
 | 
				
			||||||
        super(mcMMOPlayer, PrimarySkillType.CROSSBOWS);
 | 
					        super(mcMMOPlayer, PrimarySkillType.CROSSBOWS);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Calculate bonus XP awarded for Archery when hitting a far-away target.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param target The {@link LivingEntity} damaged by the arrow
 | 
				
			||||||
 | 
					     * @param damager The {@link Entity} who shot the arrow
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public double distanceXpBonusMultiplier(LivingEntity target, Entity damager) {
 | 
				
			||||||
 | 
					        //Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires
 | 
				
			||||||
 | 
					        if(!damager.hasMetadata(mcMMO.arrowDistanceKey))
 | 
				
			||||||
 | 
					            return damager.getLocation().distance(target.getLocation());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Location firedLocation = (Location) damager.getMetadata(mcMMO.arrowDistanceKey).get(0).value();
 | 
				
			||||||
 | 
					        Location targetLocation = target.getLocation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (firedLocation.getWorld() != targetLocation.getWorld()) {
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //TODO: Should use its own variable
 | 
				
			||||||
 | 
					        return 1 + Math.min(firedLocation.distance(targetLocation), 50) * Archery.DISTANCE_XP_MULTIPLIER;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,9 +31,23 @@ public final class ItemUtils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static boolean hasItemInEitherHand(Player player, Material material) {
 | 
					    public static boolean hasItemInEitherHand(Player player, Material material) {
 | 
				
			||||||
        return player.getInventory().getItemInMainHand().getType() == material || player.getInventory().getItemInOffHand().getType() == material;
 | 
					        return hasItemInEitherHand(player, material.getKey().getKey());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static boolean hasItemInEitherHand(Player player, String id) {
 | 
				
			||||||
 | 
					        return player.getInventory().getItemInMainHand().getType().getKey().getKey().equalsIgnoreCase(id)
 | 
				
			||||||
 | 
					                || player.getInventory().getItemInOffHand().getType().getKey().getKey().equalsIgnoreCase(id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static boolean hasItemInMainHand(Player player, String id) {
 | 
				
			||||||
 | 
					        return player.getInventory().getItemInMainHand().getType().getKey().getKey().equalsIgnoreCase(id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static boolean hasItemInOffHand(Player player, String id) {
 | 
				
			||||||
 | 
					        return player.getInventory().getItemInOffHand().getType().getKey().getKey().equalsIgnoreCase(id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Checks if the item is a sword.
 | 
					     * Checks if the item is a sword.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ import com.gmail.nossr50.runnables.skills.AwardCombatXpTask;
 | 
				
			|||||||
import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
 | 
					import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
 | 
				
			||||||
import com.gmail.nossr50.skills.archery.ArcheryManager;
 | 
					import com.gmail.nossr50.skills.archery.ArcheryManager;
 | 
				
			||||||
import com.gmail.nossr50.skills.axes.AxesManager;
 | 
					import com.gmail.nossr50.skills.axes.AxesManager;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.skills.crossbows.CrossbowManager;
 | 
				
			||||||
import com.gmail.nossr50.skills.swords.SwordsManager;
 | 
					import com.gmail.nossr50.skills.swords.SwordsManager;
 | 
				
			||||||
import com.gmail.nossr50.skills.taming.TamingManager;
 | 
					import com.gmail.nossr50.skills.taming.TamingManager;
 | 
				
			||||||
import com.gmail.nossr50.skills.tridents.TridentManager;
 | 
					import com.gmail.nossr50.skills.tridents.TridentManager;
 | 
				
			||||||
@@ -308,13 +309,49 @@ public final class CombatUtils {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        double distanceMultiplier = archeryManager.distanceXpBonusMultiplier(target, arrow);
 | 
					        double distanceMultiplier = archeryManager.distanceXpBonusMultiplier(target, arrow);
 | 
				
			||||||
        double forceMultiplier = 1.0; //Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires
 | 
					//        double forceMultiplier = 1.0; //Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(arrow.hasMetadata(mcMMO.bowForceKey))
 | 
					//        if(arrow.hasMetadata(mcMMO.bowForceKey))
 | 
				
			||||||
            forceMultiplier = arrow.getMetadata(mcMMO.bowForceKey).get(0).asDouble();
 | 
					//            forceMultiplier = arrow.getMetadata(mcMMO.bowForceKey).get(0).asDouble();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        applyScaledModifiers(initialDamage, finalDamage, event);
 | 
					        applyScaledModifiers(initialDamage, finalDamage, event);
 | 
				
			||||||
        processCombatXP(mcMMOPlayer, target, PrimarySkillType.ARCHERY, forceMultiplier * distanceMultiplier);
 | 
					        processCombatXP(mcMMOPlayer, target, PrimarySkillType.ARCHERY, distanceMultiplier);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static void processCrossbowCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event, Projectile arrow) {
 | 
				
			||||||
 | 
					        double initialDamage = event.getDamage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //Make sure the profiles been loaded
 | 
				
			||||||
 | 
					        if(mcMMOPlayer == null) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CrossbowManager crossbowManager = mcMMOPlayer.getCrossbowManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        double finalDamage = event.getDamage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (target instanceof Player && PrimarySkillType.UNARMED.getPVPEnabled()) {
 | 
				
			||||||
 | 
					            UnarmedManager unarmedManager = UserManager.getPlayer((Player) target).getUnarmedManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (unarmedManager.canDeflect()) {
 | 
				
			||||||
 | 
					                event.setCancelled(unarmedManager.deflectCheck());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (event.isCancelled()) {
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(canUseLimitBreak(player, target, SubSkillType.CROSSBOWS_CROSSBOWS_LIMIT_BREAK))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            finalDamage+=getLimitBreakDamage(player, target, SubSkillType.CROSSBOWS_CROSSBOWS_LIMIT_BREAK);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        double distanceMultiplier = crossbowManager.distanceXpBonusMultiplier(target, arrow);
 | 
				
			||||||
 | 
					        applyScaledModifiers(initialDamage, finalDamage, event);
 | 
				
			||||||
 | 
					        processCombatXP(mcMMOPlayer, target, PrimarySkillType.CROSSBOWS, distanceMultiplier);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -433,18 +470,32 @@ public final class CombatUtils {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (entityType == EntityType.ARROW || entityType == EntityType.SPECTRAL_ARROW) {
 | 
					        else if (entityType == EntityType.ARROW || entityType == EntityType.SPECTRAL_ARROW) {
 | 
				
			||||||
            Projectile arrow = (Projectile) painSource;
 | 
					            Projectile arrow = (Projectile) painSource;
 | 
				
			||||||
            ProjectileSource projectileSource = arrow.getShooter();
 | 
					            ProjectileSource projectileShooter = arrow.getShooter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //Determine if the arrow belongs to a bow or xbow
 | 
					            //Determine if the arrow belongs to a bow or xbow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (projectileSource instanceof Player && PrimarySkillType.ARCHERY.shouldProcess(target)) {
 | 
					            if (projectileShooter instanceof Player) {
 | 
				
			||||||
                Player player = (Player) projectileSource;
 | 
					                Player player = (Player) projectileShooter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.ARCHERY.getPermissions(player)) {
 | 
					                //Has metadata
 | 
				
			||||||
                    processArcheryCombat(target, player, event, arrow);
 | 
					                if(arrow.getMetadata(mcMMO.PROJECTILE_ORIGIN_METAKEY).size() > 0) {
 | 
				
			||||||
 | 
					                    if(isProjectileFromBow(arrow)) {
 | 
				
			||||||
 | 
					                        if(PrimarySkillType.ARCHERY.shouldProcess(target)) {
 | 
				
			||||||
 | 
					                            if (!Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.ARCHERY.getPermissions(player)) {
 | 
				
			||||||
 | 
					                                processArcheryCombat(target, player, event, arrow);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    } else if(isProjectileFromCrossbow(arrow)) {
 | 
				
			||||||
 | 
					                        if(PrimarySkillType.CROSSBOWS.shouldProcess(target)) {
 | 
				
			||||||
 | 
					                            if (!Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.CROSSBOWS.getPermissions(player)) {
 | 
				
			||||||
 | 
					                                processCrossbowCombat(target, player, event, arrow);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (target.getType() != EntityType.CREEPER && !Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.TAMING.getPermissions(player)) {
 | 
					                if (target.getType() != EntityType.CREEPER && !Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.TAMING.getPermissions(player)) {
 | 
				
			||||||
                    McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
 | 
					                    McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
 | 
				
			||||||
                    TamingManager tamingManager = mcMMOPlayer.getTamingManager();
 | 
					                    TamingManager tamingManager = mcMMOPlayer.getTamingManager();
 | 
				
			||||||
@@ -454,6 +505,14 @@ public final class CombatUtils {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean isProjectileFromCrossbow(Projectile arrow) {
 | 
				
			||||||
 | 
					        return arrow.getMetadata(mcMMO.PROJECTILE_ORIGIN_METAKEY).get(0).asInt() == 2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static boolean isProjectileFromBow(Projectile arrow) {
 | 
				
			||||||
 | 
					        return arrow.getMetadata(mcMMO.PROJECTILE_ORIGIN_METAKEY).get(0).asInt() == 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * This cleans up names from displaying in chat as hearts
 | 
					     * This cleans up names from displaying in chat as hearts
 | 
				
			||||||
     * @param entity target entity
 | 
					     * @param entity target entity
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user