mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-10-31 01:03:44 +01:00 
			
		
		
		
	Fix Blast Mining Fixes #5021
This commit is contained in:
		| @@ -48,7 +48,7 @@ public class MiningCommand extends SkillCommand { | ||||
|  | ||||
|             blastMiningRank = miningManager.getBlastMiningTier(); | ||||
|             bonusTNTDrops = miningManager.getDropMultiplier(); | ||||
|             oreBonus = percent.format(miningManager.getOreBonus() / 30.0D); // Base received in TNT is 30% | ||||
|             oreBonus = percent.format(miningManager.getOreBonus()); // Base received in TNT is 30% | ||||
| //            debrisReduction = percent.format(miningManager.getDebrisReduction() / 30.0D); // Base received in TNT is 30% | ||||
|             blastDamageDecrease = percent.format(miningManager.getBlastDamageModifier() / 100.0D); | ||||
|             blastRadiusIncrease = miningManager.getBlastRadiusModifier(); | ||||
|   | ||||
| @@ -75,7 +75,8 @@ public class Roll extends AcrobaticsSubSkill { | ||||
|              */ | ||||
|              | ||||
|             if (canRoll(mmoPlayer)) { | ||||
|                 entityDamageEvent.setDamage(rollCheck(mmoPlayer, entityDamageEvent.getFinalDamage())); | ||||
|                 entityDamageEvent.setDamage( | ||||
|                         rollCheck(mmoPlayer, entityDamageEvent.getFinalDamage(), mmoPlayer.getPlayer().isSneaking())); | ||||
|  | ||||
|                 if (entityDamageEvent.getFinalDamage() == 0) { | ||||
|                     entityDamageEvent.setCancelled(true); | ||||
| @@ -189,64 +190,24 @@ public class Roll extends AcrobaticsSubSkill { | ||||
|                 && Permissions.isSubSkillEnabled(mmoPlayer.getPlayer(), SubSkillType.ACROBATICS_ROLL); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle the damage reduction and XP gain from the Roll ability | ||||
|      * | ||||
|      * @param damage The amount of damage initially dealt by the event | ||||
|      * @return the modified event damage if the ability was successful, the original event damage otherwise | ||||
|      */ | ||||
|     @VisibleForTesting | ||||
|     public double rollCheck(McMMOPlayer mmoPlayer, double damage) { | ||||
|         int skillLevel = mmoPlayer.getSkillLevel(getPrimarySkill()); | ||||
|  | ||||
|         if (mmoPlayer.getPlayer().isSneaking()) { | ||||
|             return gracefulRollCheck(mmoPlayer, damage, skillLevel); | ||||
|         } | ||||
|  | ||||
|         double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold()); | ||||
|  | ||||
|         if (!isFatal(mmoPlayer, modifiedDamage) | ||||
|                 && ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ACROBATICS_ROLL, mmoPlayer)) { | ||||
|             NotificationManager.sendPlayerInformation(mmoPlayer.getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Roll.Text"); | ||||
|             SoundManager.sendCategorizedSound(mmoPlayer.getPlayer(), mmoPlayer.getPlayer().getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS); | ||||
|             //mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text")); | ||||
|  | ||||
|             //if (!SkillUtils.cooldownExpired((long) mcMMOmmoPlayer.getPlayer().getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) { | ||||
|             if (!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP()) | ||||
|                 SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, true), XPGainReason.PVE); | ||||
|             //} | ||||
|  | ||||
|             addFallLocation(mmoPlayer); | ||||
|             return modifiedDamage; | ||||
|         } else if (!isFatal(mmoPlayer, damage)) { | ||||
|             //if (!SkillUtils.cooldownExpired((long) mmoPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) { | ||||
|             if (!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP()) | ||||
|                 SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, false), XPGainReason.PVE); | ||||
|             //} | ||||
|         } | ||||
|  | ||||
|         addFallLocation(mmoPlayer); | ||||
|         return damage; | ||||
|     } | ||||
|  | ||||
|     private int getActivationChance(McMMOPlayer mmoPlayer) { | ||||
|         return PerksUtils.handleLuckyPerks(mmoPlayer, getPrimarySkill()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle the damage reduction and XP gain from the Graceful Roll ability | ||||
|      * Handle the damage reduction and XP gain from the Roll / Graceful Roll ability | ||||
|      * | ||||
|      * @param damage The amount of damage initially dealt by the event | ||||
|      * @return the modified event damage if the ability was successful, the original event damage otherwise | ||||
|      */ | ||||
|     private double gracefulRollCheck(McMMOPlayer mmoPlayer, double damage, int skillLevel) { | ||||
|         double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold() * 2); | ||||
|  | ||||
|         final Probability gracefulProbability = getGracefulProbability(mmoPlayer); | ||||
|     private double rollCheck(McMMOPlayer mmoPlayer, double damage, boolean isGracefulRoll) { | ||||
|         final Probability probability | ||||
|                 = isGracefulRoll ? getGracefulProbability(mmoPlayer) : getNonGracefulProbability(mmoPlayer); | ||||
|         double modifiedDamage = calculateModifiedRollDamage(damage, | ||||
|                 mcMMO.p.getAdvancedConfig().getRollDamageThreshold() * 2); | ||||
|  | ||||
|         if (!isFatal(mmoPlayer, modifiedDamage) | ||||
|                 //TODO: Graceful isn't sending out an event | ||||
|                 && ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.ACROBATICS, mmoPlayer, gracefulProbability)) { | ||||
|                 && ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.ACROBATICS, mmoPlayer, probability)) { | ||||
|             NotificationManager.sendPlayerInformation(mmoPlayer.getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Ability.Proc"); | ||||
|             SoundManager.sendCategorizedSound(mmoPlayer.getPlayer(), mmoPlayer.getPlayer().getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS,0.5F); | ||||
|             if (!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP()) | ||||
| @@ -270,6 +231,11 @@ public class Roll extends AcrobaticsSubSkill { | ||||
|         return Probability.ofValue(gracefulOdds); | ||||
|     } | ||||
|  | ||||
|     public static Probability getNonGracefulProbability(McMMOPlayer mmoPlayer) { | ||||
|         double gracefulOdds = ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, mmoPlayer).getValue(); | ||||
|         return Probability.ofValue(gracefulOdds); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if the player is "farming" Acrobatics XP using | ||||
|      * exploits in the game. | ||||
|   | ||||
| @@ -756,7 +756,7 @@ public class EntityListener implements Listener { | ||||
|         if (WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld())) | ||||
|             return; | ||||
|  | ||||
|         Entity entity = event.getEntity(); | ||||
|         final Entity entity = event.getEntity(); | ||||
|  | ||||
|         if (!(entity instanceof TNTPrimed) || !entity.hasMetadata(MetadataConstants.METADATA_KEY_TRACKED_TNT)) { | ||||
|             return; | ||||
| @@ -764,13 +764,14 @@ public class EntityListener implements Listener { | ||||
|  | ||||
|         // We can make this assumption because we (should) be the only ones | ||||
|         // using this exact metadata | ||||
|         Player player = pluginRef.getServer().getPlayerExact(entity.getMetadata(MetadataConstants.METADATA_KEY_TRACKED_TNT).get(0).asString()); | ||||
|         final Player player = pluginRef.getServer().getPlayerExact( | ||||
|                 entity.getMetadata(MetadataConstants.METADATA_KEY_TRACKED_TNT).get(0).asString()); | ||||
|  | ||||
|         if (!UserManager.hasPlayerDataKey(player)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         //Profile not loaded | ||||
|         // Profile is not loaded | ||||
|         if (UserManager.getPlayer(player) == null) { | ||||
|             return; | ||||
|         } | ||||
| @@ -781,7 +782,7 @@ public class EntityListener implements Listener { | ||||
|                 return; | ||||
|         } | ||||
|  | ||||
|         MiningManager miningManager = UserManager.getPlayer(player).getMiningManager(); | ||||
|         final MiningManager miningManager = UserManager.getPlayer(player).getMiningManager(); | ||||
|  | ||||
|         if (miningManager.canUseBiggerBombs()) { | ||||
|             event.setRadius(miningManager.biggerBombs(event.getRadius())); | ||||
|   | ||||
| @@ -10,58 +10,17 @@ import org.bukkit.entity.TNTPrimed; | ||||
| import org.bukkit.event.entity.EntityDamageByEntityEvent; | ||||
|  | ||||
| public class BlastMining { | ||||
|     // The order of the values is extremely important, a few methods depend on it to work properly | ||||
|    /* public enum Tier { | ||||
|         EIGHT(8), | ||||
|         SEVEN(7), | ||||
|         SIX(6), | ||||
|         FIVE(5), | ||||
|         FOUR(4), | ||||
|         THREE(3), | ||||
|         TWO(2), | ||||
|         ONE(1); | ||||
|  | ||||
|         int numerical; | ||||
|  | ||||
|         private Tier(int numerical) { | ||||
|             this.numerical = numerical; | ||||
|         } | ||||
|  | ||||
|         public int toNumerical() { | ||||
|             return numerical; | ||||
|         } | ||||
|  | ||||
|         protected int getLevel() { | ||||
|             return mcMMO.p.getAdvancedConfig().getBlastMiningRankLevel(this); | ||||
|         } | ||||
|  | ||||
|  | ||||
|     }*/ | ||||
|  | ||||
|     public final static int MAXIMUM_REMOTE_DETONATION_DISTANCE = 100; | ||||
|  | ||||
|     public static double getBlastRadiusModifier(int rank) { | ||||
|         return mcMMO.p.getAdvancedConfig().getBlastRadiusModifier(rank); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     public static double getBlastDamageDecrease(int rank) { | ||||
|         return mcMMO.p.getAdvancedConfig().getBlastDamageDecrease(rank); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     public static int getDemolitionExpertUnlockLevel() { | ||||
|         /*List<Tier> tierList = Arrays.asList(Tier.values()); | ||||
|         for (Tier tier : tierList) { | ||||
|             if (tier.getBlastDamageDecrease() > 0) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             return tier == Tier.EIGHT ? tier.getLevel() : tierList.get(tierList.indexOf(tier) - 1).getLevel(); | ||||
|         }*/ | ||||
|  | ||||
|         for(int i = 0; i < SubSkillType.MINING_BLAST_MINING.getNumRanks()-1; i++) { | ||||
|             if (getBlastDamageDecrease(i+1) > 0) | ||||
|                 return RankUtils.getRankUnlockLevel(SubSkillType.MINING_BLAST_MINING, i+1); | ||||
| @@ -71,15 +30,6 @@ public class BlastMining { | ||||
|     } | ||||
|  | ||||
|     public static int getBiggerBombsUnlockLevel() { | ||||
|         /*List<Tier> tierList = Arrays.asList(Tier.values()); | ||||
|         for (Tier tier : tierList) { | ||||
|             if (tier.getBlastRadiusModifier() > 1.0) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             return tier == Tier.EIGHT ? tier.getLevel() : tierList.get(tierList.indexOf(tier) - 1).getLevel(); | ||||
|         }*/ | ||||
|  | ||||
|         for(int i = 0; i < SubSkillType.MINING_BLAST_MINING.getNumRanks()-1; i++) { | ||||
|             if (getBlastRadiusModifier(i+1) > 0) | ||||
|                 return RankUtils.getRankUnlockLevel(SubSkillType.MINING_BLAST_MINING, i+1); | ||||
| @@ -104,7 +54,7 @@ public class BlastMining { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         MiningManager miningManager =  UserManager.getPlayer(defender).getMiningManager(); | ||||
|         final MiningManager miningManager =  UserManager.getPlayer(defender).getMiningManager(); | ||||
|  | ||||
|         if (!miningManager.canUseDemolitionsExpertise()) { | ||||
|             return false; | ||||
|   | ||||
| @@ -17,7 +17,6 @@ import com.gmail.nossr50.util.random.Probability; | ||||
| import com.gmail.nossr50.util.random.ProbabilityUtil; | ||||
| import com.gmail.nossr50.util.skills.RankUtils; | ||||
| import com.gmail.nossr50.util.skills.SkillUtils; | ||||
| import org.apache.commons.lang3.RandomUtils; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.block.Block; | ||||
| import org.bukkit.block.BlockState; | ||||
| @@ -30,8 +29,11 @@ import org.bukkit.inventory.ItemStack; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
|  | ||||
| import static com.gmail.nossr50.util.ItemUtils.isPickaxe; | ||||
|  | ||||
| public class MiningManager extends SkillManager { | ||||
|  | ||||
|     public static final String BUDDING_AMETHYST = "budding_amethyst"; | ||||
| @@ -51,7 +53,7 @@ public class MiningManager extends SkillManager { | ||||
|         Player player = getPlayer(); | ||||
|  | ||||
|         return canUseBlastMining() && player.isSneaking() | ||||
|                 && (ItemUtils.isPickaxe(getPlayer().getInventory().getItemInMainHand()) || player.getInventory().getItemInMainHand().getType() == mcMMO.p.getGeneralConfig().getDetonatorItem()) | ||||
|                 && (isPickaxe(getPlayer().getInventory().getItemInMainHand()) || player.getInventory().getItemInMainHand().getType() == mcMMO.p.getGeneralConfig().getDetonatorItem()) | ||||
|                 && Permissions.remoteDetonation(player); | ||||
|     } | ||||
|  | ||||
| @@ -168,69 +170,76 @@ public class MiningManager extends SkillManager { | ||||
|      * @param yield The % of blocks to drop | ||||
|      * @param event The {@link EntityExplodeEvent} | ||||
|      */ | ||||
|     //TODO: Rewrite this garbage | ||||
|     public void blastMiningDropProcessing(float yield, EntityExplodeEvent event) { | ||||
|         if (yield == 0) | ||||
|             return; | ||||
|  | ||||
|         //Strip out only stuff that gives mining XP | ||||
|         var increasedYieldFromBonuses = yield + (yield * getOreBonus()); | ||||
|         // Strip out only stuff that gives mining XP | ||||
|         List<BlockState> ores = new ArrayList<>(); | ||||
|  | ||||
|         List<BlockState> notOres = new ArrayList<>(); | ||||
|         for (Block targetBlock : event.blockList()) { | ||||
|             BlockState blockState = targetBlock.getState(); | ||||
|             //Containers usually have 0 XP unless someone edited their config in a very strange way | ||||
|             if (ExperienceConfig.getInstance().getXp(PrimarySkillType.MINING, targetBlock) != 0 | ||||
|                     && !(targetBlock instanceof Container) | ||||
|                     && !mcMMO.getUserBlockTracker().isIneligible(targetBlock)) { | ||||
|                 if (BlockUtils.isOre(blockState)) { | ||||
|  | ||||
|             if(mcMMO.getUserBlockTracker().isIneligible(targetBlock)) | ||||
|                 continue; | ||||
|  | ||||
|             if (ExperienceConfig.getInstance().getXp(PrimarySkillType.MINING, targetBlock) != 0) { | ||||
|                 if (BlockUtils.isOre(blockState) && !(targetBlock instanceof Container)) { | ||||
|                     ores.add(blockState); | ||||
|                 } else { | ||||
|                     notOres.add(blockState); | ||||
|                 } | ||||
|             } else { | ||||
|                 notOres.add(blockState); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         int xp = 0; | ||||
|  | ||||
|         float oreBonus = (float) (getOreBonus() / 100); | ||||
|         float debrisReduction = (float) (getDebrisReduction() / 100); | ||||
|         int dropMultiplier = getDropMultiplier(); | ||||
|         float debrisYield = yield - debrisReduction; | ||||
|  | ||||
|         //Drop "debris" based on skill modifiers | ||||
|         for(BlockState blockState : notOres) { | ||||
|             if (isDropIllegal(blockState.getType())) | ||||
|                 continue; | ||||
|  | ||||
|             if (Probability.ofPercent(50).evaluate()) { | ||||
|                 ItemUtils.spawnItem(getPlayer(), Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_DEBRIS_NON_ORES); // Initial block that would have been dropped | ||||
|                 ItemUtils.spawnItem(getPlayer(), | ||||
|                         Misc.getBlockCenter(blockState), | ||||
|                         new ItemStack(blockState.getType()), | ||||
|                         ItemSpawnReason.BLAST_MINING_DEBRIS_NON_ORES); // Initial block that would have been dropped | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for (BlockState blockState : ores) { | ||||
|             if (isDropIllegal(blockState.getType())) | ||||
|             // currentOreYield only used for drop calculations for ores | ||||
|             float currentOreYield = increasedYieldFromBonuses; | ||||
|  | ||||
|             if (isDropIllegal(blockState.getType())) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if (RandomUtils.nextFloat() < (yield + oreBonus)) { | ||||
|                 xp += Mining.getBlockXp(blockState); | ||||
|             // Always give XP for every ore destroyed | ||||
|             xp += Mining.getBlockXp(blockState); | ||||
|             while(currentOreYield > 0) { | ||||
|                 if (Probability.ofValue(currentOreYield).evaluate()) { | ||||
|                     Collection<ItemStack> oreDrops = isPickaxe(mmoPlayer.getPlayer().getInventory().getItemInMainHand()) | ||||
|                             ? blockState.getBlock().getDrops(mmoPlayer.getPlayer().getInventory().getItemInMainHand()) | ||||
|                             : List.of(new ItemStack(blockState.getType())); | ||||
|                     ItemUtils.spawnItems(getPlayer(), Misc.getBlockCenter(blockState), | ||||
|                             oreDrops, ItemSpawnReason.BLAST_MINING_ORES); | ||||
|  | ||||
|                 ItemUtils.spawnItem(getPlayer(), Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_ORES); // Initial block that would have been dropped | ||||
|  | ||||
|                 if (mcMMO.p.getAdvancedConfig().isBlastMiningBonusDropsEnabled() && !mcMMO.getUserBlockTracker().isIneligible(blockState)) { | ||||
|                     for (int i = 1; i < dropMultiplier; i++) { | ||||
| //                        Bukkit.broadcastMessage("Bonus Drop on Ore: "+blockState.getType().toString()); | ||||
|                         ItemUtils.spawnItem(getPlayer(), Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_ORES_BONUS_DROP); // Initial block that would have been dropped | ||||
|                     if (mcMMO.p.getAdvancedConfig().isBlastMiningBonusDropsEnabled()) { | ||||
|                         for (int i = 1; i < dropMultiplier; i++) { | ||||
|                             ItemUtils.spawnItems(getPlayer(), | ||||
|                                     Misc.getBlockCenter(blockState), | ||||
|                                     oreDrops, | ||||
|                                     ItemSpawnReason.BLAST_MINING_ORES_BONUS_DROP); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 currentOreYield = Math.max(currentOreYield - 1, 0); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         //Replace the event blocklist with the newYield list | ||||
|         // Replace the event blocklist with the newYield list | ||||
|         event.setYield(0F); | ||||
| //        event.blockList().clear(); | ||||
| //        event.blockList().addAll(notOres); | ||||
|  | ||||
|         applyXpGain(xp, XPGainReason.PVE); | ||||
|     } | ||||
|  | ||||
| @@ -273,10 +282,11 @@ public class MiningManager extends SkillManager { | ||||
|      * | ||||
|      * @return the Blast Mining tier | ||||
|      */ | ||||
|     public double getOreBonus() { | ||||
|         return getOreBonus(getBlastMiningTier()); | ||||
|     public float getOreBonus() { | ||||
|         return (float) (mcMMO.p.getAdvancedConfig().getOreBonus(getBlastMiningTier()) / 100F); | ||||
|     } | ||||
|  | ||||
|     @Deprecated(since = "2.2.017", forRemoval = true) | ||||
|     public static double getOreBonus(int rank) { | ||||
|         return mcMMO.p.getAdvancedConfig().getOreBonus(rank); | ||||
|     } | ||||
|   | ||||
| @@ -681,6 +681,21 @@ public final class ItemUtils { | ||||
|         return enchantmentWrappers.get(randomIndex); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Drop items at a given location. | ||||
|      * | ||||
|      * @param location The location to drop the items at | ||||
|      * @param itemStacks The items to drop | ||||
|      */ | ||||
|     public static void spawnItems(@Nullable Player player, | ||||
|                                   @NotNull Location location, | ||||
|                                   @NotNull Collection<ItemStack> itemStacks, | ||||
|                                   @NotNull ItemSpawnReason itemSpawnReason) { | ||||
|         for (ItemStack is : itemStacks) { | ||||
|             spawnItem(player, location, is, itemSpawnReason); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Drop items at a given location. | ||||
|      * | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 nossr50
					nossr50