2013-03-01 06:52:01 +01:00
|
|
|
package com.gmail.nossr50.skills.mining;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import org.bukkit.Material;
|
|
|
|
import org.bukkit.block.Block;
|
|
|
|
import org.bukkit.block.BlockState;
|
|
|
|
import org.bukkit.enchantments.Enchantment;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
import org.bukkit.entity.TNTPrimed;
|
2013-04-02 14:41:51 +02:00
|
|
|
import org.bukkit.metadata.FixedMetadataValue;
|
2013-03-01 06:52:01 +01:00
|
|
|
|
|
|
|
import com.gmail.nossr50.mcMMO;
|
2013-03-08 10:31:32 +01:00
|
|
|
import com.gmail.nossr50.config.Config;
|
2013-03-01 06:52:01 +01:00
|
|
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
|
|
|
import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
|
|
|
import com.gmail.nossr50.datatypes.skills.AbilityType;
|
|
|
|
import com.gmail.nossr50.datatypes.skills.SkillType;
|
|
|
|
import com.gmail.nossr50.locale.LocaleLoader;
|
2013-04-29 20:19:41 +02:00
|
|
|
import com.gmail.nossr50.runnables.skills.AbilityCooldownTask;
|
2013-03-01 06:52:01 +01:00
|
|
|
import com.gmail.nossr50.skills.SkillManager;
|
|
|
|
import com.gmail.nossr50.skills.mining.BlastMining.Tier;
|
|
|
|
import com.gmail.nossr50.util.BlockUtils;
|
|
|
|
import com.gmail.nossr50.util.Misc;
|
|
|
|
import com.gmail.nossr50.util.Permissions;
|
|
|
|
import com.gmail.nossr50.util.skills.SkillUtils;
|
|
|
|
|
2013-05-18 22:41:42 +02:00
|
|
|
public class MiningManager extends SkillManager {
|
2013-03-01 06:52:01 +01:00
|
|
|
public MiningManager(McMMOPlayer mcMMOPlayer) {
|
|
|
|
super(mcMMOPlayer, SkillType.MINING);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canUseDemolitionsExpertise() {
|
2013-03-04 15:40:03 +01:00
|
|
|
return getSkillLevel() >= BlastMining.Tier.FOUR.getLevel() && Permissions.demolitionsExpertise(getPlayer());
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canDetonate() {
|
|
|
|
Player player = getPlayer();
|
|
|
|
|
2013-03-04 15:40:03 +01:00
|
|
|
return canUseBlastMining() && player.isSneaking() && player.getItemInHand().getTypeId() == BlastMining.detonatorID && Permissions.remoteDetonation(player);
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canUseBlastMining() {
|
2013-03-04 15:40:03 +01:00
|
|
|
return getSkillLevel() >= BlastMining.Tier.ONE.getLevel();
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canUseBiggerBombs() {
|
2013-03-04 15:40:03 +01:00
|
|
|
return getSkillLevel() >= BlastMining.Tier.TWO.getLevel() && Permissions.biggerBombs(getPlayer());
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Process double drops & XP gain for Mining.
|
|
|
|
*
|
|
|
|
* @param blockState The {@link BlockState} to check ability activation for
|
|
|
|
*/
|
|
|
|
public void miningBlockCheck(BlockState blockState) {
|
|
|
|
Player player = getPlayer();
|
|
|
|
|
2013-03-08 14:49:07 +01:00
|
|
|
applyXpGain(Mining.getBlockXp(blockState));
|
|
|
|
|
2013-03-17 05:36:40 +01:00
|
|
|
if (!Permissions.doubleDrops(player, skill)) {
|
2013-03-08 10:31:32 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Material material = blockState.getType();
|
|
|
|
|
|
|
|
if (material != Material.GLOWING_REDSTONE_ORE && !Config.getInstance().getDoubleDropsEnabled(skill, material)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-03-08 13:26:43 +01:00
|
|
|
boolean silkTouch = player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH);
|
2013-03-08 10:33:20 +01:00
|
|
|
|
2013-03-08 10:31:32 +01:00
|
|
|
for (int i = mcMMOPlayer.getAbilityMode(skill.getAbility()) ? 2 : 1; i != 0; i--) {
|
|
|
|
if (SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Mining.doubleDropsMaxChance, Mining.doubleDropsMaxLevel)) {
|
2013-03-08 13:26:43 +01:00
|
|
|
if (silkTouch) {
|
2013-03-08 10:31:32 +01:00
|
|
|
Mining.handleSilkTouchDrops(blockState);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Mining.handleMiningDrops(blockState);
|
|
|
|
}
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Detonate TNT for Blast Mining
|
|
|
|
*/
|
|
|
|
public void remoteDetonation() {
|
|
|
|
Player player = getPlayer();
|
|
|
|
|
|
|
|
HashSet<Byte> transparentBlocks = BlastMining.generateTransparentBlockList();
|
|
|
|
Block targetBlock = player.getTargetBlock(transparentBlocks, BlastMining.MAXIMUM_REMOTE_DETONATION_DISTANCE);
|
|
|
|
|
|
|
|
if (targetBlock.getType() != Material.TNT || !SkillUtils.blockBreakSimulate(targetBlock, player, true) || !blastMiningCooldownOver()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TNTPrimed tnt = player.getWorld().spawn(targetBlock.getLocation(), TNTPrimed.class);
|
|
|
|
|
|
|
|
SkillUtils.sendSkillMessage(player, AbilityType.BLAST_MINING.getAbilityPlayer(player));
|
|
|
|
player.sendMessage(LocaleLoader.getString("Mining.Blast.Boom"));
|
|
|
|
|
2013-04-02 14:41:51 +02:00
|
|
|
tnt.setMetadata(mcMMO.tntMetadataKey, new FixedMetadataValue(mcMMO.p, player.getName()));
|
2013-03-01 06:52:01 +01:00
|
|
|
tnt.setFuseTicks(0);
|
|
|
|
targetBlock.setData((byte) 0x0);
|
|
|
|
targetBlock.setType(Material.AIR);
|
|
|
|
|
2013-03-03 17:06:05 +01:00
|
|
|
getProfile().setSkillDATS(AbilityType.BLAST_MINING, System.currentTimeMillis());
|
|
|
|
mcMMOPlayer.setAbilityInformed(AbilityType.BLAST_MINING, false);
|
2013-06-13 01:26:09 +02:00
|
|
|
new AbilityCooldownTask(mcMMOPlayer, AbilityType.BLAST_MINING).runTaskLaterAsynchronously(mcMMO.p, AbilityType.BLAST_MINING.getCooldown() * Misc.TICK_CONVERSION_FACTOR);
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handler for explosion drops and XP gain.
|
|
|
|
*
|
|
|
|
* @param event Event whose explosion is being processed
|
|
|
|
*/
|
|
|
|
public void blastMiningDropProcessing(float yield, List<Block> blockList) {
|
|
|
|
List<BlockState> ores = new ArrayList<BlockState>();
|
|
|
|
List<BlockState> debris = new ArrayList<BlockState>();
|
|
|
|
int xp = 0;
|
|
|
|
|
|
|
|
float oreBonus = (float) (getOreBonus() / 100);
|
|
|
|
float debrisReduction = (float) (getDebrisReduction() / 100);
|
|
|
|
int dropMultiplier = getDropMultiplier();
|
|
|
|
|
|
|
|
float debrisYield = yield - debrisReduction;
|
|
|
|
|
|
|
|
for (Block block : blockList) {
|
|
|
|
BlockState blockState = block.getState();
|
|
|
|
|
|
|
|
if (BlockUtils.isOre(blockState)) {
|
|
|
|
ores.add(blockState);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
debris.add(blockState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (BlockState blockState : ores) {
|
|
|
|
if (Misc.getRandom().nextFloat() < (yield + oreBonus)) {
|
2013-04-25 15:16:42 +02:00
|
|
|
if (!mcMMO.getPlaceStore().isTrue(blockState)) {
|
2013-03-01 06:52:01 +01:00
|
|
|
xp += Mining.getBlockXp(blockState);
|
|
|
|
}
|
|
|
|
|
2013-03-08 13:40:25 +01:00
|
|
|
Misc.dropItem(blockState.getLocation(), blockState.getData().toItemStack(1)); // Initial block that would have been dropped
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2013-04-25 15:16:42 +02:00
|
|
|
if (!mcMMO.getPlaceStore().isTrue(blockState)) {
|
2013-03-01 06:52:01 +01:00
|
|
|
for (int i = 1; i < dropMultiplier; i++) {
|
|
|
|
Mining.handleSilkTouchDrops(blockState); // Bonus drops - should drop the block & not the items
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (debrisYield > 0) {
|
|
|
|
for (BlockState blockState : debris) {
|
|
|
|
if (Misc.getRandom().nextFloat() < debrisYield) {
|
2013-05-15 16:23:09 +02:00
|
|
|
Misc.dropItems(blockState.getLocation(), blockState.getBlock().getDrops());
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
applyXpGain(xp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Increases the blast radius of the explosion.
|
|
|
|
*
|
|
|
|
* @param event Event whose explosion radius is being changed
|
|
|
|
*/
|
|
|
|
public float biggerBombs(float radius) {
|
|
|
|
return (float) (radius + getBlastRadiusModifier());
|
|
|
|
}
|
|
|
|
|
|
|
|
public int processDemolitionsExpertise(int damage) {
|
2013-03-11 02:30:35 +01:00
|
|
|
return (int) (damage * ((100.0D - getBlastDamageModifier()) / 100.0D));
|
2013-03-01 06:52:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the Blast Mining tier
|
|
|
|
*
|
|
|
|
* @return the Blast Mining tier
|
|
|
|
*/
|
|
|
|
public int getBlastMiningTier() {
|
|
|
|
int skillLevel = getSkillLevel();
|
|
|
|
|
|
|
|
for (Tier tier : Tier.values()) {
|
|
|
|
if (skillLevel >= tier.getLevel()) {
|
|
|
|
return tier.toNumerical();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the Blast Mining tier
|
|
|
|
*
|
|
|
|
* @return the Blast Mining tier
|
|
|
|
*/
|
|
|
|
public double getOreBonus() {
|
|
|
|
int skillLevel = getSkillLevel();
|
|
|
|
|
|
|
|
for (Tier tier : Tier.values()) {
|
|
|
|
if (skillLevel >= tier.getLevel()) {
|
|
|
|
return tier.getOreBonus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the Blast Mining tier
|
|
|
|
*
|
|
|
|
* @return the Blast Mining tier
|
|
|
|
*/
|
|
|
|
public double getDebrisReduction() {
|
|
|
|
int skillLevel = getSkillLevel();
|
|
|
|
|
|
|
|
for (Tier tier : Tier.values()) {
|
|
|
|
if (skillLevel >= tier.getLevel()) {
|
|
|
|
return tier.getDebrisReduction();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the Blast Mining tier
|
|
|
|
*
|
|
|
|
* @return the Blast Mining tier
|
|
|
|
*/
|
|
|
|
public int getDropMultiplier() {
|
|
|
|
int skillLevel = getSkillLevel();
|
|
|
|
|
|
|
|
for (Tier tier : Tier.values()) {
|
|
|
|
if (skillLevel >= tier.getLevel()) {
|
|
|
|
return tier.getDropMultiplier();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the Blast Mining tier
|
|
|
|
*
|
|
|
|
* @return the Blast Mining tier
|
|
|
|
*/
|
|
|
|
public double getBlastRadiusModifier() {
|
|
|
|
int skillLevel = getSkillLevel();
|
|
|
|
|
|
|
|
for (Tier tier : Tier.values()) {
|
|
|
|
if (skillLevel >= tier.getLevel()) {
|
|
|
|
return tier.getBlastRadiusModifier();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the Blast Mining tier
|
|
|
|
*
|
|
|
|
* @return the Blast Mining tier
|
|
|
|
*/
|
|
|
|
public double getBlastDamageModifier() {
|
|
|
|
int skillLevel = getSkillLevel();
|
|
|
|
|
|
|
|
for (Tier tier : Tier.values()) {
|
|
|
|
if (skillLevel >= tier.getLevel()) {
|
|
|
|
return tier.getBlastDamageDecrease();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean blastMiningCooldownOver() {
|
|
|
|
Player player = getPlayer();
|
|
|
|
PlayerProfile profile = getProfile();
|
2013-06-13 01:20:05 +02:00
|
|
|
int timeRemaining = SkillUtils.calculateTimeLeft(profile.getSkillDATS(AbilityType.BLAST_MINING) * Misc.TIME_CONVERSION_FACTOR, AbilityType.BLAST_MINING.getCooldown(), player);
|
2013-03-01 06:52:01 +01:00
|
|
|
|
2013-05-21 17:41:39 +02:00
|
|
|
if (timeRemaining > 0) {
|
|
|
|
player.sendMessage(LocaleLoader.getString("Skills.TooTired", timeRemaining));
|
2013-03-01 06:52:01 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|