MiningManager.java 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. package com.gmail.nossr50.skills.mining;
  2. import java.util.ArrayList;
  3. import java.util.HashSet;
  4. import java.util.List;
  5. import org.bukkit.Material;
  6. import org.bukkit.block.Block;
  7. import org.bukkit.block.BlockState;
  8. import org.bukkit.enchantments.Enchantment;
  9. import org.bukkit.entity.Player;
  10. import org.bukkit.entity.TNTPrimed;
  11. import org.bukkit.metadata.FixedMetadataValue;
  12. import com.gmail.nossr50.mcMMO;
  13. import com.gmail.nossr50.config.Config;
  14. import com.gmail.nossr50.datatypes.player.McMMOPlayer;
  15. import com.gmail.nossr50.datatypes.player.PlayerProfile;
  16. import com.gmail.nossr50.datatypes.skills.AbilityType;
  17. import com.gmail.nossr50.datatypes.skills.SkillType;
  18. import com.gmail.nossr50.locale.LocaleLoader;
  19. import com.gmail.nossr50.runnables.skills.AbilityCooldownTask;
  20. import com.gmail.nossr50.skills.SkillManager;
  21. import com.gmail.nossr50.skills.mining.BlastMining.Tier;
  22. import com.gmail.nossr50.util.BlockUtils;
  23. import com.gmail.nossr50.util.Misc;
  24. import com.gmail.nossr50.util.Permissions;
  25. import com.gmail.nossr50.util.skills.SkillUtils;
  26. public class MiningManager extends SkillManager {
  27. public MiningManager(McMMOPlayer mcMMOPlayer) {
  28. super(mcMMOPlayer, SkillType.MINING);
  29. }
  30. public boolean canUseDemolitionsExpertise() {
  31. return getSkillLevel() >= BlastMining.Tier.FOUR.getLevel() && Permissions.demolitionsExpertise(getPlayer());
  32. }
  33. public boolean canDetonate() {
  34. Player player = getPlayer();
  35. return canUseBlastMining() && player.isSneaking() && player.getItemInHand().getTypeId() == BlastMining.detonatorID && Permissions.remoteDetonation(player);
  36. }
  37. public boolean canUseBlastMining() {
  38. return getSkillLevel() >= BlastMining.Tier.ONE.getLevel();
  39. }
  40. public boolean canUseBiggerBombs() {
  41. return getSkillLevel() >= BlastMining.Tier.TWO.getLevel() && Permissions.biggerBombs(getPlayer());
  42. }
  43. /**
  44. * Process double drops & XP gain for Mining.
  45. *
  46. * @param blockState The {@link BlockState} to check ability activation for
  47. */
  48. public void miningBlockCheck(BlockState blockState) {
  49. Player player = getPlayer();
  50. applyXpGain(Mining.getBlockXp(blockState));
  51. if (!Permissions.doubleDrops(player, skill)) {
  52. return;
  53. }
  54. Material material = blockState.getType();
  55. if (mcMMOPlayer.getAbilityMode(skill.getAbility())) {
  56. SkillUtils.handleDurabilityChange(getPlayer().getItemInHand(), Config.getInstance().getAbilityToolDamage());
  57. }
  58. if (material != Material.GLOWING_REDSTONE_ORE && !Config.getInstance().getDoubleDropsEnabled(skill, material)) {
  59. return;
  60. }
  61. boolean silkTouch = player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH);
  62. for (int i = mcMMOPlayer.getAbilityMode(skill.getAbility()) ? 2 : 1; i != 0; i--) {
  63. if (SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Mining.doubleDropsMaxChance, Mining.doubleDropsMaxLevel)) {
  64. if (silkTouch) {
  65. Mining.handleSilkTouchDrops(blockState);
  66. }
  67. else {
  68. Mining.handleMiningDrops(blockState);
  69. }
  70. }
  71. }
  72. }
  73. /**
  74. * Detonate TNT for Blast Mining
  75. */
  76. public void remoteDetonation() {
  77. Player player = getPlayer();
  78. HashSet<Byte> transparentBlocks = BlastMining.generateTransparentBlockList();
  79. Block targetBlock = player.getTargetBlock(transparentBlocks, BlastMining.MAXIMUM_REMOTE_DETONATION_DISTANCE);
  80. if (targetBlock.getType() != Material.TNT || !SkillUtils.blockBreakSimulate(targetBlock, player, true) || !blastMiningCooldownOver()) {
  81. return;
  82. }
  83. TNTPrimed tnt = player.getWorld().spawn(targetBlock.getLocation(), TNTPrimed.class);
  84. SkillUtils.sendSkillMessage(player, AbilityType.BLAST_MINING.getAbilityPlayer(player));
  85. player.sendMessage(LocaleLoader.getString("Mining.Blast.Boom"));
  86. tnt.setMetadata(mcMMO.tntMetadataKey, new FixedMetadataValue(mcMMO.p, player.getName()));
  87. tnt.setFuseTicks(0);
  88. targetBlock.setData((byte) 0x0);
  89. targetBlock.setType(Material.AIR);
  90. getProfile().setSkillDATS(AbilityType.BLAST_MINING, System.currentTimeMillis());
  91. mcMMOPlayer.setAbilityInformed(AbilityType.BLAST_MINING, false);
  92. new AbilityCooldownTask(mcMMOPlayer, AbilityType.BLAST_MINING).runTaskLaterAsynchronously(mcMMO.p, AbilityType.BLAST_MINING.getCooldown() * Misc.TICK_CONVERSION_FACTOR);
  93. }
  94. /**
  95. * Handler for explosion drops and XP gain.
  96. *
  97. * @param event Event whose explosion is being processed
  98. */
  99. public void blastMiningDropProcessing(float yield, List<Block> blockList) {
  100. List<BlockState> ores = new ArrayList<BlockState>();
  101. List<BlockState> debris = new ArrayList<BlockState>();
  102. int xp = 0;
  103. float oreBonus = (float) (getOreBonus() / 100);
  104. float debrisReduction = (float) (getDebrisReduction() / 100);
  105. int dropMultiplier = getDropMultiplier();
  106. float debrisYield = yield - debrisReduction;
  107. for (Block block : blockList) {
  108. BlockState blockState = block.getState();
  109. if (BlockUtils.isOre(blockState)) {
  110. ores.add(blockState);
  111. }
  112. else {
  113. debris.add(blockState);
  114. }
  115. }
  116. for (BlockState blockState : ores) {
  117. if (Misc.getRandom().nextFloat() < (yield + oreBonus)) {
  118. if (!mcMMO.getPlaceStore().isTrue(blockState)) {
  119. xp += Mining.getBlockXp(blockState);
  120. }
  121. Misc.dropItem(blockState.getLocation(), blockState.getData().toItemStack(1)); // Initial block that would have been dropped
  122. if (!mcMMO.getPlaceStore().isTrue(blockState)) {
  123. for (int i = 1; i < dropMultiplier; i++) {
  124. Mining.handleSilkTouchDrops(blockState); // Bonus drops - should drop the block & not the items
  125. }
  126. }
  127. }
  128. }
  129. if (debrisYield > 0) {
  130. for (BlockState blockState : debris) {
  131. if (Misc.getRandom().nextFloat() < debrisYield) {
  132. Misc.dropItems(blockState.getLocation(), blockState.getBlock().getDrops());
  133. }
  134. }
  135. }
  136. applyXpGain(xp);
  137. }
  138. /**
  139. * Increases the blast radius of the explosion.
  140. *
  141. * @param event Event whose explosion radius is being changed
  142. */
  143. public float biggerBombs(float radius) {
  144. return (float) (radius + getBlastRadiusModifier());
  145. }
  146. public double processDemolitionsExpertise(double damage) {
  147. return damage * ((100.0D - getBlastDamageModifier()) / 100.0D);
  148. }
  149. /**
  150. * Gets the Blast Mining tier
  151. *
  152. * @return the Blast Mining tier
  153. */
  154. public int getBlastMiningTier() {
  155. int skillLevel = getSkillLevel();
  156. for (Tier tier : Tier.values()) {
  157. if (skillLevel >= tier.getLevel()) {
  158. return tier.toNumerical();
  159. }
  160. }
  161. return 0;
  162. }
  163. /**
  164. * Gets the Blast Mining tier
  165. *
  166. * @return the Blast Mining tier
  167. */
  168. public double getOreBonus() {
  169. int skillLevel = getSkillLevel();
  170. for (Tier tier : Tier.values()) {
  171. if (skillLevel >= tier.getLevel()) {
  172. return tier.getOreBonus();
  173. }
  174. }
  175. return 0;
  176. }
  177. /**
  178. * Gets the Blast Mining tier
  179. *
  180. * @return the Blast Mining tier
  181. */
  182. public double getDebrisReduction() {
  183. int skillLevel = getSkillLevel();
  184. for (Tier tier : Tier.values()) {
  185. if (skillLevel >= tier.getLevel()) {
  186. return tier.getDebrisReduction();
  187. }
  188. }
  189. return 0;
  190. }
  191. /**
  192. * Gets the Blast Mining tier
  193. *
  194. * @return the Blast Mining tier
  195. */
  196. public int getDropMultiplier() {
  197. int skillLevel = getSkillLevel();
  198. for (Tier tier : Tier.values()) {
  199. if (skillLevel >= tier.getLevel()) {
  200. return tier.getDropMultiplier();
  201. }
  202. }
  203. return 0;
  204. }
  205. /**
  206. * Gets the Blast Mining tier
  207. *
  208. * @return the Blast Mining tier
  209. */
  210. public double getBlastRadiusModifier() {
  211. int skillLevel = getSkillLevel();
  212. for (Tier tier : Tier.values()) {
  213. if (skillLevel >= tier.getLevel()) {
  214. return tier.getBlastRadiusModifier();
  215. }
  216. }
  217. return 0;
  218. }
  219. /**
  220. * Gets the Blast Mining tier
  221. *
  222. * @return the Blast Mining tier
  223. */
  224. public double getBlastDamageModifier() {
  225. int skillLevel = getSkillLevel();
  226. for (Tier tier : Tier.values()) {
  227. if (skillLevel >= tier.getLevel()) {
  228. return tier.getBlastDamageDecrease();
  229. }
  230. }
  231. return 0;
  232. }
  233. private boolean blastMiningCooldownOver() {
  234. Player player = getPlayer();
  235. PlayerProfile profile = getProfile();
  236. int timeRemaining = SkillUtils.calculateTimeLeft(profile.getSkillDATS(AbilityType.BLAST_MINING) * Misc.TIME_CONVERSION_FACTOR, AbilityType.BLAST_MINING.getCooldown(), player);
  237. if (timeRemaining > 0) {
  238. player.sendMessage(LocaleLoader.getString("Skills.TooTired", timeRemaining));
  239. return false;
  240. }
  241. return true;
  242. }
  243. }