MiningManager.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. package com.gmail.nossr50.skills.mining;
  2. import com.gmail.nossr50.api.ItemSpawnReason;
  3. import com.gmail.nossr50.config.experience.ExperienceConfig;
  4. import com.gmail.nossr50.datatypes.experience.XPGainReason;
  5. import com.gmail.nossr50.datatypes.interactions.NotificationType;
  6. import com.gmail.nossr50.datatypes.player.McMMOPlayer;
  7. import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
  8. import com.gmail.nossr50.datatypes.skills.SubSkillType;
  9. import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
  10. import com.gmail.nossr50.mcMMO;
  11. import com.gmail.nossr50.runnables.skills.AbilityCooldownTask;
  12. import com.gmail.nossr50.skills.SkillManager;
  13. import com.gmail.nossr50.util.*;
  14. import com.gmail.nossr50.util.player.NotificationManager;
  15. import com.gmail.nossr50.util.random.RandomChanceUtil;
  16. import com.gmail.nossr50.util.skills.RankUtils;
  17. import com.gmail.nossr50.util.skills.SkillUtils;
  18. import org.apache.commons.lang.math.RandomUtils;
  19. import org.bukkit.Material;
  20. import org.bukkit.block.Block;
  21. import org.bukkit.block.BlockState;
  22. import org.bukkit.block.Container;
  23. import org.bukkit.enchantments.Enchantment;
  24. import org.bukkit.entity.Player;
  25. import org.bukkit.entity.TNTPrimed;
  26. import org.bukkit.event.entity.EntityExplodeEvent;
  27. import org.bukkit.inventory.ItemStack;
  28. import org.jetbrains.annotations.NotNull;
  29. import java.util.ArrayList;
  30. import java.util.List;
  31. public class MiningManager extends SkillManager {
  32. public static final String BUDDING_AMETHYST = "budding_amethyst";
  33. public MiningManager(McMMOPlayer mcMMOPlayer) {
  34. super(mcMMOPlayer, PrimarySkillType.MINING);
  35. }
  36. public boolean canUseDemolitionsExpertise() {
  37. if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_DEMOLITIONS_EXPERTISE))
  38. return false;
  39. return getSkillLevel() >= BlastMining.getDemolitionExpertUnlockLevel() && Permissions.demolitionsExpertise(getPlayer());
  40. }
  41. public boolean canDetonate() {
  42. Player player = getPlayer();
  43. return canUseBlastMining() && player.isSneaking()
  44. && (ItemUtils.isPickaxe(getPlayer().getInventory().getItemInMainHand()) || player.getInventory().getItemInMainHand().getType() == mcMMO.p.getGeneralConfig().getDetonatorItem())
  45. && Permissions.remoteDetonation(player);
  46. }
  47. public boolean canUseBlastMining() {
  48. //Not checking permissions?
  49. return RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_BLAST_MINING);
  50. }
  51. public boolean canUseBiggerBombs() {
  52. if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_BIGGER_BOMBS))
  53. return false;
  54. return getSkillLevel() >= BlastMining.getBiggerBombsUnlockLevel() && Permissions.biggerBombs(getPlayer());
  55. }
  56. public boolean canDoubleDrop() {
  57. return RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS);
  58. }
  59. /**
  60. * Process double drops & XP gain for Mining.
  61. *
  62. * @param blockState The {@link BlockState} to check ability activation for
  63. */
  64. public void miningBlockCheck(BlockState blockState) {
  65. Player player = getPlayer();
  66. applyXpGain(Mining.getBlockXp(blockState), XPGainReason.PVE);
  67. if (!Permissions.isSubSkillEnabled(player, SubSkillType.MINING_DOUBLE_DROPS)) {
  68. return;
  69. }
  70. if (mmoPlayer.getAbilityMode(mcMMO.p.getSkillTools().getSuperAbility(skill))) {
  71. SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), mcMMO.p.getGeneralConfig().getAbilityToolDamage());
  72. }
  73. if(!mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.MINING, blockState.getType()) || !canDoubleDrop())
  74. return;
  75. boolean silkTouch = player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH);
  76. if(silkTouch && !mcMMO.p.getAdvancedConfig().getDoubleDropSilkTouchEnabled())
  77. return;
  78. //TODO: Make this readable
  79. if (RandomChanceUtil.checkRandomChanceExecutionSuccess(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS, true)) {
  80. boolean useTriple = mmoPlayer.getAbilityMode(mcMMO.p.getSkillTools().getSuperAbility(skill)) && mcMMO.p.getAdvancedConfig().getAllowMiningTripleDrops();
  81. BlockUtils.markDropsAsBonus(blockState, useTriple);
  82. }
  83. }
  84. /**
  85. * Detonate TNT for Blast Mining
  86. */
  87. public void remoteDetonation() {
  88. Player player = getPlayer();
  89. Block targetBlock = player.getTargetBlock(BlockUtils.getTransparentBlocks(), BlastMining.MAXIMUM_REMOTE_DETONATION_DISTANCE);
  90. //Blast mining cooldown check needs to be first so the player can be messaged
  91. if (!blastMiningCooldownOver() || targetBlock.getType() != Material.TNT || !EventUtils.simulateBlockBreak(targetBlock, player, true)) {
  92. return;
  93. }
  94. TNTPrimed tnt = player.getWorld().spawn(targetBlock.getLocation(), TNTPrimed.class);
  95. //SkillUtils.sendSkillMessage(player, SuperAbilityType.BLAST_MINING.getAbilityPlayer(player));
  96. NotificationManager.sendPlayerInformation(player, NotificationType.SUPER_ABILITY, "Mining.Blast.Boom");
  97. //player.sendMessage(LocaleLoader.getString("Mining.Blast.Boom"));
  98. tnt.setMetadata(mcMMO.tntMetadataKey, mmoPlayer.getPlayerMetadata());
  99. tnt.setFuseTicks(0);
  100. if (mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 16, 4)) {
  101. tnt.setSource(player);
  102. }
  103. targetBlock.setType(Material.AIR);
  104. mmoPlayer.setAbilityDATS(SuperAbilityType.BLAST_MINING, System.currentTimeMillis());
  105. mmoPlayer.setAbilityInformed(SuperAbilityType.BLAST_MINING, false);
  106. new AbilityCooldownTask(mmoPlayer, SuperAbilityType.BLAST_MINING).runTaskLater(mcMMO.p, SuperAbilityType.BLAST_MINING.getCooldown() * Misc.TICK_CONVERSION_FACTOR);
  107. }
  108. /**
  109. * Handler for explosion drops and XP gain.
  110. *
  111. * @param yield The % of blocks to drop
  112. * @param event The {@link EntityExplodeEvent}
  113. */
  114. //TODO: Rewrite this garbage
  115. public void blastMiningDropProcessing(float yield, EntityExplodeEvent event) {
  116. if (yield == 0)
  117. return;
  118. //Strip out only stuff that gives mining XP
  119. List<BlockState> ores = new ArrayList<>();
  120. List<BlockState> notOres = new ArrayList<>();
  121. for (Block targetBlock : event.blockList()) {
  122. BlockState blockState = targetBlock.getState();
  123. //Containers usually have 0 XP unless someone edited their config in a very strange way
  124. if (ExperienceConfig.getInstance().getXp(PrimarySkillType.MINING, targetBlock) != 0
  125. && !(targetBlock instanceof Container)
  126. && !mcMMO.getPlaceStore().isTrue(targetBlock)) {
  127. if(BlockUtils.isOre(blockState)) {
  128. ores.add(blockState);
  129. } else {
  130. notOres.add(blockState);
  131. }
  132. }
  133. }
  134. int xp = 0;
  135. float oreBonus = (float) (getOreBonus() / 100);
  136. float debrisReduction = (float) (getDebrisReduction() / 100);
  137. int dropMultiplier = getDropMultiplier();
  138. float debrisYield = yield - debrisReduction;
  139. //Drop "debris" based on skill modifiers
  140. for(BlockState blockState : notOres) {
  141. if(isDropIllegal(blockState.getType()))
  142. continue;
  143. if(RandomUtils.nextFloat() < debrisYield) {
  144. Misc.spawnItem(getPlayer(), Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_DEBRIS_NON_ORES); // Initial block that would have been dropped
  145. }
  146. }
  147. for (BlockState blockState : ores) {
  148. if(isDropIllegal(blockState.getType()))
  149. continue;
  150. if (RandomUtils.nextFloat() < (yield + oreBonus)) {
  151. xp += Mining.getBlockXp(blockState);
  152. Misc.spawnItem(getPlayer(), Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_ORES); // Initial block that would have been dropped
  153. if (!mcMMO.getPlaceStore().isTrue(blockState)) {
  154. for (int i = 1; i < dropMultiplier; i++) {
  155. // Bukkit.broadcastMessage("Bonus Drop on Ore: "+blockState.getType().toString());
  156. Misc.spawnItem(getPlayer(), Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_ORES_BONUS_DROP); // Initial block that would have been dropped
  157. }
  158. }
  159. }
  160. }
  161. //Replace the event blocklist with the newYield list
  162. event.setYield(0F);
  163. // event.blockList().clear();
  164. // event.blockList().addAll(notOres);
  165. applyXpGain(xp, XPGainReason.PVE);
  166. }
  167. /**
  168. * Checks if it would be illegal (in vanilla) to obtain the block
  169. * Certain things should never drop ( such as budding_amethyst )
  170. *
  171. * @param material target material
  172. * @return true if it's not legal to obtain the block through normal gameplay
  173. */
  174. public boolean isDropIllegal(@NotNull Material material) {
  175. return material.getKey().getKey().equalsIgnoreCase(BUDDING_AMETHYST);
  176. }
  177. /**
  178. * Increases the blast radius of the explosion.
  179. *
  180. * @param radius to modify
  181. * @return modified radius
  182. */
  183. public float biggerBombs(float radius) {
  184. return (float) (radius + getBlastRadiusModifier());
  185. }
  186. public double processDemolitionsExpertise(double damage) {
  187. return damage * ((100.0D - getBlastDamageModifier()) / 100.0D);
  188. }
  189. /**
  190. * Gets the Blast Mining tier
  191. *
  192. * @return the Blast Mining tier
  193. */
  194. public int getBlastMiningTier() {
  195. return RankUtils.getRank(getPlayer(), SubSkillType.MINING_BLAST_MINING);
  196. }
  197. /**
  198. * Gets the Blast Mining tier
  199. *
  200. * @return the Blast Mining tier
  201. */
  202. public double getOreBonus() {
  203. return getOreBonus(getBlastMiningTier());
  204. }
  205. public static double getOreBonus(int rank) {
  206. return mcMMO.p.getAdvancedConfig().getOreBonus(rank);
  207. }
  208. public static double getDebrisReduction(int rank) {
  209. return mcMMO.p.getAdvancedConfig().getDebrisReduction(rank);
  210. }
  211. /**
  212. * Gets the Blast Mining tier
  213. *
  214. * @return the Blast Mining tier
  215. */
  216. public double getDebrisReduction() {
  217. return getDebrisReduction(getBlastMiningTier());
  218. }
  219. public static int getDropMultiplier(int rank) {
  220. return mcMMO.p.getAdvancedConfig().getDropMultiplier(rank);
  221. }
  222. /**
  223. * Gets the Blast Mining tier
  224. *
  225. * @return the Blast Mining tier
  226. */
  227. public int getDropMultiplier() {
  228. switch(getBlastMiningTier()) {
  229. case 8:
  230. case 7:
  231. return 3;
  232. case 6:
  233. case 5:
  234. case 4:
  235. case 3:
  236. return 2;
  237. case 2:
  238. case 1:
  239. return 1;
  240. default:
  241. return 0;
  242. }
  243. }
  244. /**
  245. * Gets the Blast Mining tier
  246. *
  247. * @return the Blast Mining tier
  248. */
  249. public double getBlastRadiusModifier() {
  250. return BlastMining.getBlastRadiusModifier(getBlastMiningTier());
  251. }
  252. /**
  253. * Gets the Blast Mining tier
  254. *
  255. * @return the Blast Mining tier
  256. */
  257. public double getBlastDamageModifier() {
  258. return BlastMining.getBlastDamageDecrease(getBlastMiningTier());
  259. }
  260. private boolean blastMiningCooldownOver() {
  261. int timeRemaining = mmoPlayer.calculateTimeRemaining(SuperAbilityType.BLAST_MINING);
  262. if (timeRemaining > 0) {
  263. //getPlayer().sendMessage(LocaleLoader.getString("Skills.TooTired", timeRemaining));
  264. NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.ABILITY_COOLDOWN, "Skills.TooTired", String.valueOf(timeRemaining));
  265. return false;
  266. }
  267. return true;
  268. }
  269. }