MiningManager.java 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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 (material != Material.GLOWING_REDSTONE_ORE && !Config.getInstance().getDoubleDropsEnabled(skill, material)) {
  56. return;
  57. }
  58. boolean silkTouch = player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH);
  59. for (int i = mcMMOPlayer.getAbilityMode(skill.getAbility()) ? 2 : 1; i != 0; i--) {
  60. if (SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Mining.doubleDropsMaxChance, Mining.doubleDropsMaxLevel)) {
  61. if (silkTouch) {
  62. Mining.handleSilkTouchDrops(blockState);
  63. }
  64. else {
  65. Mining.handleMiningDrops(blockState);
  66. }
  67. }
  68. }
  69. }
  70. /**
  71. * Detonate TNT for Blast Mining
  72. */
  73. public void remoteDetonation() {
  74. Player player = getPlayer();
  75. HashSet<Byte> transparentBlocks = BlastMining.generateTransparentBlockList();
  76. Block targetBlock = player.getTargetBlock(transparentBlocks, BlastMining.MAXIMUM_REMOTE_DETONATION_DISTANCE);
  77. if (targetBlock.getType() != Material.TNT || !SkillUtils.blockBreakSimulate(targetBlock, player, true) || !blastMiningCooldownOver()) {
  78. return;
  79. }
  80. TNTPrimed tnt = player.getWorld().spawn(targetBlock.getLocation(), TNTPrimed.class);
  81. SkillUtils.sendSkillMessage(player, AbilityType.BLAST_MINING.getAbilityPlayer(player));
  82. player.sendMessage(LocaleLoader.getString("Mining.Blast.Boom"));
  83. tnt.setMetadata(mcMMO.tntMetadataKey, new FixedMetadataValue(mcMMO.p, player.getName()));
  84. tnt.setFuseTicks(0);
  85. targetBlock.setData((byte) 0x0);
  86. targetBlock.setType(Material.AIR);
  87. getProfile().setSkillDATS(AbilityType.BLAST_MINING, System.currentTimeMillis());
  88. mcMMOPlayer.setAbilityInformed(AbilityType.BLAST_MINING, false);
  89. new AbilityCooldownTask(mcMMOPlayer, AbilityType.BLAST_MINING).runTaskLaterAsynchronously(mcMMO.p, AbilityType.BLAST_MINING.getCooldown() * 20);
  90. }
  91. /**
  92. * Handler for explosion drops and XP gain.
  93. *
  94. * @param event Event whose explosion is being processed
  95. */
  96. public void blastMiningDropProcessing(float yield, List<Block> blockList) {
  97. List<BlockState> ores = new ArrayList<BlockState>();
  98. List<BlockState> debris = new ArrayList<BlockState>();
  99. int xp = 0;
  100. float oreBonus = (float) (getOreBonus() / 100);
  101. float debrisReduction = (float) (getDebrisReduction() / 100);
  102. int dropMultiplier = getDropMultiplier();
  103. float debrisYield = yield - debrisReduction;
  104. for (Block block : blockList) {
  105. BlockState blockState = block.getState();
  106. if (BlockUtils.isOre(blockState)) {
  107. ores.add(blockState);
  108. }
  109. else {
  110. debris.add(blockState);
  111. }
  112. }
  113. for (BlockState blockState : ores) {
  114. if (Misc.getRandom().nextFloat() < (yield + oreBonus)) {
  115. if (!mcMMO.getPlaceStore().isTrue(blockState)) {
  116. xp += Mining.getBlockXp(blockState);
  117. }
  118. Misc.dropItem(blockState.getLocation(), blockState.getData().toItemStack(1)); // Initial block that would have been dropped
  119. if (!mcMMO.getPlaceStore().isTrue(blockState)) {
  120. for (int i = 1; i < dropMultiplier; i++) {
  121. Mining.handleSilkTouchDrops(blockState); // Bonus drops - should drop the block & not the items
  122. }
  123. }
  124. }
  125. }
  126. if (debrisYield > 0) {
  127. for (BlockState blockState : debris) {
  128. if (Misc.getRandom().nextFloat() < debrisYield) {
  129. Misc.dropItems(blockState.getLocation(), blockState.getBlock().getDrops());
  130. }
  131. }
  132. }
  133. applyXpGain(xp);
  134. }
  135. /**
  136. * Increases the blast radius of the explosion.
  137. *
  138. * @param event Event whose explosion radius is being changed
  139. */
  140. public float biggerBombs(float radius) {
  141. return (float) (radius + getBlastRadiusModifier());
  142. }
  143. public int processDemolitionsExpertise(int damage) {
  144. return (int) (damage * ((100.0D - getBlastDamageModifier()) / 100.0D));
  145. }
  146. /**
  147. * Gets the Blast Mining tier
  148. *
  149. * @return the Blast Mining tier
  150. */
  151. public int getBlastMiningTier() {
  152. int skillLevel = getSkillLevel();
  153. for (Tier tier : Tier.values()) {
  154. if (skillLevel >= tier.getLevel()) {
  155. return tier.toNumerical();
  156. }
  157. }
  158. return 0;
  159. }
  160. /**
  161. * Gets the Blast Mining tier
  162. *
  163. * @return the Blast Mining tier
  164. */
  165. public double getOreBonus() {
  166. int skillLevel = getSkillLevel();
  167. for (Tier tier : Tier.values()) {
  168. if (skillLevel >= tier.getLevel()) {
  169. return tier.getOreBonus();
  170. }
  171. }
  172. return 0;
  173. }
  174. /**
  175. * Gets the Blast Mining tier
  176. *
  177. * @return the Blast Mining tier
  178. */
  179. public double getDebrisReduction() {
  180. int skillLevel = getSkillLevel();
  181. for (Tier tier : Tier.values()) {
  182. if (skillLevel >= tier.getLevel()) {
  183. return tier.getDebrisReduction();
  184. }
  185. }
  186. return 0;
  187. }
  188. /**
  189. * Gets the Blast Mining tier
  190. *
  191. * @return the Blast Mining tier
  192. */
  193. public int getDropMultiplier() {
  194. int skillLevel = getSkillLevel();
  195. for (Tier tier : Tier.values()) {
  196. if (skillLevel >= tier.getLevel()) {
  197. return tier.getDropMultiplier();
  198. }
  199. }
  200. return 0;
  201. }
  202. /**
  203. * Gets the Blast Mining tier
  204. *
  205. * @return the Blast Mining tier
  206. */
  207. public double getBlastRadiusModifier() {
  208. int skillLevel = getSkillLevel();
  209. for (Tier tier : Tier.values()) {
  210. if (skillLevel >= tier.getLevel()) {
  211. return tier.getBlastRadiusModifier();
  212. }
  213. }
  214. return 0;
  215. }
  216. /**
  217. * Gets the Blast Mining tier
  218. *
  219. * @return the Blast Mining tier
  220. */
  221. public double getBlastDamageModifier() {
  222. int skillLevel = getSkillLevel();
  223. for (Tier tier : Tier.values()) {
  224. if (skillLevel >= tier.getLevel()) {
  225. return tier.getBlastDamageDecrease();
  226. }
  227. }
  228. return 0;
  229. }
  230. private boolean blastMiningCooldownOver() {
  231. Player player = getPlayer();
  232. PlayerProfile profile = getProfile();
  233. long oldTime = profile.getSkillDATS(AbilityType.BLAST_MINING) * Misc.TIME_CONVERSION_FACTOR;
  234. int cooldown = AbilityType.BLAST_MINING.getCooldown();
  235. if (!SkillUtils.cooldownOver(oldTime, cooldown, player)) {
  236. player.sendMessage(LocaleLoader.getString("Skills.TooTired", SkillUtils.calculateTimeLeft(oldTime, cooldown, player)));
  237. return false;
  238. }
  239. return true;
  240. }
  241. }