mcMMO/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java

323 lines
12 KiB
Java

package com.gmail.nossr50.skills.mining;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.skills.AbilityCooldownTask;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.*;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.random.RandomChanceUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Container;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
public class MiningManager extends SkillManager {
public MiningManager(McMMOPlayer mcMMOPlayer) {
super(mcMMOPlayer, PrimarySkillType.MINING);
}
public boolean canUseDemolitionsExpertise() {
if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_DEMOLITIONS_EXPERTISE))
return false;
return getSkillLevel() >= BlastMining.getDemolitionExpertUnlockLevel() && Permissions.demolitionsExpertise(getPlayer());
}
public boolean canDetonate() {
Player player = getPlayer();
return canUseBlastMining() && player.isSneaking()
&& (ItemUtils.isPickaxe(getPlayer().getInventory().getItemInMainHand()) || player.getInventory().getItemInMainHand().getType() == mcMMO.p.getGeneralConfig().getDetonatorItem())
&& Permissions.remoteDetonation(player);
}
public boolean canUseBlastMining() {
//Not checking permissions?
return RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_BLAST_MINING);
}
public boolean canUseBiggerBombs() {
if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_BIGGER_BOMBS))
return false;
return getSkillLevel() >= BlastMining.getBiggerBombsUnlockLevel() && Permissions.biggerBombs(getPlayer());
}
public boolean canDoubleDrop() {
return RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS);
}
/**
* 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();
applyXpGain(Mining.getBlockXp(blockState), XPGainReason.PVE);
if (!Permissions.isSubSkillEnabled(player, SubSkillType.MINING_DOUBLE_DROPS)) {
return;
}
if (mmoPlayer.getAbilityMode(skill.getAbility())) {
SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), mcMMO.p.getGeneralConfig().getAbilityToolDamage());
}
if(!mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.MINING, blockState.getType()) || !canDoubleDrop())
return;
boolean silkTouch = player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH);
if(silkTouch && !mcMMO.p.getAdvancedConfig().getDoubleDropSilkTouchEnabled())
return;
//TODO: Make this readable
if (RandomChanceUtil.checkRandomChanceExecutionSuccess(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS, true)) {
boolean useTriple = mmoPlayer.getAbilityMode(skill.getAbility()) && mcMMO.p.getAdvancedConfig().getAllowMiningTripleDrops();
BlockUtils.markDropsAsBonus(blockState, useTriple);
}
}
/**
* Detonate TNT for Blast Mining
*/
public void remoteDetonation() {
Player player = getPlayer();
Block targetBlock = player.getTargetBlock(BlockUtils.getTransparentBlocks(), BlastMining.MAXIMUM_REMOTE_DETONATION_DISTANCE);
//Blast mining cooldown check needs to be first so the player can be messaged
if (!blastMiningCooldownOver() || targetBlock.getType() != Material.TNT || !EventUtils.simulateBlockBreak(targetBlock, player, true)) {
return;
}
TNTPrimed tnt = player.getWorld().spawn(targetBlock.getLocation(), TNTPrimed.class);
//SkillUtils.sendSkillMessage(player, SuperAbilityType.BLAST_MINING.getAbilityPlayer(player));
NotificationManager.sendPlayerInformation(player, NotificationType.SUPER_ABILITY, "Mining.Blast.Boom");
//player.sendMessage(LocaleLoader.getString("Mining.Blast.Boom"));
tnt.setMetadata(mcMMO.tntMetadataKey, mmoPlayer.getPlayerMetadata());
tnt.setFuseTicks(0);
targetBlock.setType(Material.AIR);
mmoPlayer.setAbilityDATS(SuperAbilityType.BLAST_MINING, System.currentTimeMillis());
mmoPlayer.setAbilityInformed(SuperAbilityType.BLAST_MINING, false);
new AbilityCooldownTask(mmoPlayer, SuperAbilityType.BLAST_MINING).runTaskLater(mcMMO.p, SuperAbilityType.BLAST_MINING.getCooldown() * Misc.TICK_CONVERSION_FACTOR);
}
/**
* Handler for explosion drops and XP gain.
*
* @param yield The % of blocks to drop
* @param event The {@link EntityExplodeEvent}
*/
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
public void blastMiningDropProcessing(float yield, EntityExplodeEvent event) {
//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.getPlaceStore().isTrue(targetBlock)) {
if(BlockUtils.isOre(blockState)) {
ores.add(blockState);
} else {
notOres.add(blockState);
}
}
}
int xp = 0;
float oreBonus = (float) (getOreBonus() / 100);
//TODO: Pretty sure something is fucked with debrisReduction stuff
float debrisReduction = (float) (getDebrisReduction() / 100);
int dropMultiplier = getDropMultiplier();
float debrisYield = yield - debrisReduction;
//Drop "debris" based on skill modifiers
for(BlockState blockState : notOres) {
if(RandomUtils.nextFloat() < debrisYield) {
Misc.spawnItem(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 (RandomUtils.nextFloat() < (yield + oreBonus)) {
xp += Mining.getBlockXp(blockState);
Misc.spawnItem(Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_ORES); // Initial block that would have been dropped
if (!mcMMO.getPlaceStore().isTrue(blockState)) {
for (int i = 1; i < dropMultiplier; i++) {
// Bukkit.broadcastMessage("Bonus Drop on Ore: "+blockState.getType().toString());
Misc.spawnItem(Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_ORES_BONUS_DROP); // Initial block that would have been dropped
}
}
}
}
//Replace the event blocklist with the newYield list
event.setYield(0F);
// event.blockList().clear();
// event.blockList().addAll(notOres);
applyXpGain(xp, XPGainReason.PVE);
}
/**
* Increases the blast radius of the explosion.
*
* @param radius to modify
* @return modified radius
*/
public float biggerBombs(float radius) {
return (float) (radius + getBlastRadiusModifier());
}
public double processDemolitionsExpertise(double damage) {
return damage * ((100.0D - getBlastDamageModifier()) / 100.0D);
}
/**
* Gets the Blast Mining tier
*
* @return the Blast Mining tier
*/
public int getBlastMiningTier() {
return RankUtils.getRank(getPlayer(), SubSkillType.MINING_BLAST_MINING);
}
/**
* Gets the Blast Mining tier
*
* @return the Blast Mining tier
*/
public double getOreBonus() {
return getOreBonus(getBlastMiningTier());
}
public static double getOreBonus(int rank) {
return mcMMO.p.getAdvancedConfig().getOreBonus(rank);
}
public static double getDebrisReduction(int rank) {
return mcMMO.p.getAdvancedConfig().getDebrisReduction(rank);
}
/**
* Gets the Blast Mining tier
*
* @return the Blast Mining tier
*/
public double getDebrisReduction() {
return getDebrisReduction(getBlastMiningTier());
}
public static int getDropMultiplier(int rank) {
return mcMMO.p.getAdvancedConfig().getDropMultiplier(rank);
}
/**
* Gets the Blast Mining tier
*
* @return the Blast Mining tier
*/
public int getDropMultiplier() {
switch(getBlastMiningTier()) {
case 8:
case 7:
return 3;
case 6:
case 5:
case 4:
case 3:
return 2;
case 2:
case 1:
return 1;
default:
return 0;
}
}
/**
* Gets the Blast Mining tier
*
* @return the Blast Mining tier
*/
public double getBlastRadiusModifier() {
return BlastMining.getBlastRadiusModifier(getBlastMiningTier());
}
/**
* Gets the Blast Mining tier
*
* @return the Blast Mining tier
*/
public double getBlastDamageModifier() {
return BlastMining.getBlastDamageDecrease(getBlastMiningTier());
}
private boolean blastMiningCooldownOver() {
int timeRemaining = mmoPlayer.calculateTimeRemaining(SuperAbilityType.BLAST_MINING);
if (timeRemaining > 0) {
//getPlayer().sendMessage(LocaleLoader.getString("Skills.TooTired", timeRemaining));
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.ABILITY_COOLDOWN, "Skills.TooTired", String.valueOf(timeRemaining));
return false;
}
return true;
}
}