2013-03-06 18:31:48 +01:00
package com.gmail.nossr50.skills.salvage ;
import java.util.Map ;
import java.util.Map.Entry ;
import org.bukkit.Location ;
import org.bukkit.Material ;
import org.bukkit.Sound ;
import org.bukkit.enchantments.Enchantment ;
import org.bukkit.entity.Player ;
import org.bukkit.inventory.ItemStack ;
import org.bukkit.inventory.meta.EnchantmentStorageMeta ;
2013-12-14 14:27:50 +01:00
import org.bukkit.material.MaterialData ;
2013-03-06 18:31:48 +01:00
2013-12-14 14:27:50 +01:00
import com.gmail.nossr50.mcMMO ;
import com.gmail.nossr50.config.Config ;
2013-03-06 18:31:48 +01:00
import com.gmail.nossr50.datatypes.player.McMMOPlayer ;
import com.gmail.nossr50.datatypes.skills.SkillType ;
import com.gmail.nossr50.locale.LocaleLoader ;
import com.gmail.nossr50.skills.SkillManager ;
import com.gmail.nossr50.skills.salvage.Salvage.Tier ;
2013-12-14 14:27:50 +01:00
import com.gmail.nossr50.skills.salvage.salvageables.Salvageable ;
2013-03-06 18:31:48 +01:00
import com.gmail.nossr50.util.Misc ;
import com.gmail.nossr50.util.Permissions ;
2013-12-14 14:27:50 +01:00
import com.gmail.nossr50.util.StringUtils ;
import com.gmail.nossr50.util.skills.SkillUtils ;
2013-03-06 18:31:48 +01:00
public class SalvageManager extends SkillManager {
private boolean placedAnvil ;
private int lastClick ;
public SalvageManager ( McMMOPlayer mcMMOPlayer ) {
super ( mcMMOPlayer , SkillType . SALVAGE ) ;
}
/ * *
* Handles notifications for placing an anvil .
* /
2013-12-14 14:27:50 +01:00
public void placedAnvilCheck ( ) {
2013-03-06 18:31:48 +01:00
Player player = getPlayer ( ) ;
2013-12-14 14:27:50 +01:00
if ( getPlacedAnvil ( ) ) {
2013-03-06 18:31:48 +01:00
return ;
}
2013-12-14 14:27:50 +01:00
if ( Config . getInstance ( ) . getSalvageAnvilMessagesEnabled ( ) ) {
player . sendMessage ( LocaleLoader . getString ( " Salvage.Listener.Anvil " ) ) ;
}
if ( Config . getInstance ( ) . getSalvageAnvilPlaceSoundsEnabled ( ) ) {
player . playSound ( player . getLocation ( ) , Sound . ANVIL_LAND , Misc . ANVIL_USE_VOLUME , Misc . ANVIL_USE_PITCH ) ;
}
2013-03-06 18:31:48 +01:00
2013-12-14 14:27:50 +01:00
togglePlacedAnvil ( ) ;
2013-03-06 18:31:48 +01:00
}
public void handleSalvage ( Location location , ItemStack item ) {
Player player = getPlayer ( ) ;
2013-12-14 14:27:50 +01:00
Salvageable salvageable = mcMMO . getSalvageableManager ( ) . getSalvageable ( item . getType ( ) ) ;
// Permissions checks on material and item types
if ( ! Permissions . salvageItemType ( player , salvageable . getSalvageItemType ( ) ) ) {
player . sendMessage ( LocaleLoader . getString ( " mcMMO.NoPermission " ) ) ;
return ;
}
if ( ! Permissions . salvageMaterialType ( player , salvageable . getSalvageMaterialType ( ) ) ) {
player . sendMessage ( LocaleLoader . getString ( " mcMMO.NoPermission " ) ) ;
return ;
}
int skillLevel = getSkillLevel ( ) ;
int minimumSalvageableLevel = salvageable . getMinimumLevel ( ) ;
// Level check
if ( skillLevel < minimumSalvageableLevel ) {
player . sendMessage ( LocaleLoader . getString ( " Salvage.Skills.Adept.Level " , minimumSalvageableLevel , StringUtils . getPrettyItemString ( item . getType ( ) ) ) ) ;
return ;
}
2013-03-06 18:31:48 +01:00
if ( item . getDurability ( ) ! = 0 & & ( getSkillLevel ( ) < Salvage . advancedSalvageUnlockLevel | | ! Permissions . advancedSalvage ( player ) ) ) {
2013-12-14 14:27:50 +01:00
player . sendMessage ( LocaleLoader . getString ( " Salvage.Skills.Adept.Damaged " ) ) ;
2013-03-06 18:31:48 +01:00
return ;
}
2013-12-14 14:27:50 +01:00
int salvageableAmount = Salvage . calculateSalvageableAmount ( item . getDurability ( ) , salvageable . getMaximumDurability ( ) , salvageable . getMaximumQuantity ( ) ) ;
2013-03-06 18:31:48 +01:00
if ( salvageableAmount = = 0 ) {
player . sendMessage ( LocaleLoader . getString ( " Salvage.Skills.TooDamaged " ) ) ;
return ;
}
2015-11-04 22:31:30 +01:00
salvageableAmount = Math . max ( ( int ) ( salvageableAmount * getMaxSalvagePercentage ( ) ) , 1 ) ; // Always get at least something back, if you're capable of salvaging it.
2013-03-06 18:31:48 +01:00
player . setItemInHand ( new ItemStack ( Material . AIR ) ) ;
location . add ( 0 , 1 , 0 ) ;
Map < Enchantment , Integer > enchants = item . getEnchantments ( ) ;
if ( ! enchants . isEmpty ( ) ) {
ItemStack enchantBook = arcaneSalvageCheck ( enchants ) ;
if ( enchantBook ! = null ) {
Misc . dropItem ( location , enchantBook ) ;
}
}
2014-06-18 11:44:21 +02:00
byte salvageMaterialMetadata = ( salvageable . getSalvageMaterialMetadata ( ) ! = ( byte ) - 1 ) ? salvageable . getSalvageMaterialMetadata ( ) : 0 ;
2013-12-14 14:27:50 +01:00
Misc . dropItems ( location , new MaterialData ( salvageable . getSalvageMaterial ( ) , salvageMaterialMetadata ) . toItemStack ( salvageableAmount ) , 1 ) ;
// BWONG BWONG BWONG - CLUNK!
if ( Config . getInstance ( ) . getSalvageAnvilUseSoundsEnabled ( ) ) {
player . playSound ( player . getLocation ( ) , Sound . ANVIL_USE , Misc . ANVIL_USE_VOLUME , Misc . ANVIL_USE_PITCH ) ;
player . playSound ( player . getLocation ( ) , Sound . ITEM_BREAK , 1 . 0F , 1 . 0F ) ;
}
player . sendMessage ( LocaleLoader . getString ( " Salvage.Skills.Success " ) ) ;
}
2013-03-06 18:31:48 +01:00
2013-12-14 14:27:50 +01:00
public double getMaxSalvagePercentage ( ) {
return Math . min ( ( ( ( Salvage . salvageMaxPercentage / Salvage . salvageMaxPercentageLevel ) * getSkillLevel ( ) ) / 100 . 0D ) , Salvage . salvageMaxPercentage / 100 . 0D ) ;
2013-03-06 18:31:48 +01:00
}
/ * *
* Gets the Arcane Salvage rank
*
* @return the current Arcane Salvage rank
* /
public int getArcaneSalvageRank ( ) {
int skillLevel = getSkillLevel ( ) ;
for ( Tier tier : Tier . values ( ) ) {
if ( skillLevel > = tier . getLevel ( ) ) {
return tier . toNumerical ( ) ;
}
}
return 0 ;
}
public double getExtractFullEnchantChance ( ) {
int skillLevel = getSkillLevel ( ) ;
for ( Tier tier : Tier . values ( ) ) {
if ( skillLevel > = tier . getLevel ( ) ) {
return tier . getExtractFullEnchantChance ( ) ;
}
}
return 0 ;
}
public double getExtractPartialEnchantChance ( ) {
int skillLevel = getSkillLevel ( ) ;
for ( Tier tier : Tier . values ( ) ) {
if ( skillLevel > = tier . getLevel ( ) ) {
return tier . getExtractPartialEnchantChance ( ) ;
}
}
return 0 ;
}
private ItemStack arcaneSalvageCheck ( Map < Enchantment , Integer > enchants ) {
Player player = getPlayer ( ) ;
if ( getArcaneSalvageRank ( ) = = 0 | | ! Permissions . arcaneSalvage ( player ) ) {
player . sendMessage ( LocaleLoader . getString ( " Salvage.Skills.ArcaneFailed " ) ) ;
return null ;
}
ItemStack book = new ItemStack ( Material . ENCHANTED_BOOK ) ;
EnchantmentStorageMeta enchantMeta = ( EnchantmentStorageMeta ) book . getItemMeta ( ) ;
boolean downgraded = false ;
for ( Entry < Enchantment , Integer > enchant : enchants . entrySet ( ) ) {
int successChance = Misc . getRandom ( ) . nextInt ( activationChance ) ;
if ( ! Salvage . arcaneSalvageEnchantLoss | | getExtractFullEnchantChance ( ) > successChance ) {
enchantMeta . addStoredEnchant ( enchant . getKey ( ) , enchant . getValue ( ) , true ) ;
}
else if ( enchant . getValue ( ) > 1 & & Salvage . arcaneSalvageDowngrades & & getExtractPartialEnchantChance ( ) > successChance ) {
enchantMeta . addStoredEnchant ( enchant . getKey ( ) , enchant . getValue ( ) - 1 , true ) ;
downgraded = true ;
}
else {
downgraded = true ;
}
}
Map < Enchantment , Integer > newEnchants = enchantMeta . getStoredEnchants ( ) ;
if ( newEnchants . isEmpty ( ) ) {
player . sendMessage ( LocaleLoader . getString ( " Salvage.Skills.ArcaneFailed " ) ) ;
return null ;
}
if ( downgraded | | newEnchants . size ( ) < enchants . size ( ) ) {
player . sendMessage ( LocaleLoader . getString ( " Salvage.Skills.ArcanePartial " ) ) ;
}
else {
player . sendMessage ( LocaleLoader . getString ( " Salvage.Skills.ArcaneSuccess " ) ) ;
}
book . setItemMeta ( enchantMeta ) ;
return book ;
}
2013-12-14 14:27:50 +01:00
/ * *
* Check if the player has tried to use an Anvil before .
* @param actualize
*
* @return true if the player has confirmed using an Anvil
2013-03-06 18:31:48 +01:00
* /
2013-12-14 14:27:50 +01:00
public boolean checkConfirmation ( boolean actualize ) {
Player player = getPlayer ( ) ;
long lastUse = getLastAnvilUse ( ) ;
2013-03-06 18:31:48 +01:00
2013-12-14 14:27:50 +01:00
if ( ! SkillUtils . cooldownExpired ( lastUse , 3 ) | | ! Config . getInstance ( ) . getSalvageConfirmRequired ( ) ) {
return true ;
2013-03-06 18:31:48 +01:00
}
2013-12-14 14:27:50 +01:00
if ( ! actualize ) {
return false ;
}
actualizeLastAnvilUse ( ) ;
player . sendMessage ( LocaleLoader . getString ( " Skills.ConfirmOrCancel " , LocaleLoader . getString ( " Salvage.Pretty.Name " ) ) ) ;
return false ;
2013-03-06 18:31:48 +01:00
}
2013-12-14 14:27:50 +01:00
/ *
* Salvage Anvil Placement
* /
public boolean getPlacedAnvil ( ) {
return placedAnvil ;
}
public void togglePlacedAnvil ( ) {
placedAnvil = ! placedAnvil ;
2013-03-06 18:31:48 +01:00
}
/ *
* Salvage Anvil Usage
* /
2013-12-14 14:27:50 +01:00
public int getLastAnvilUse ( ) {
return lastClick ;
2013-03-06 18:31:48 +01:00
}
2013-12-14 14:27:50 +01:00
public void setLastAnvilUse ( int value ) {
lastClick = value ;
2013-03-06 18:31:48 +01:00
}
2013-12-14 14:27:50 +01:00
public void actualizeLastAnvilUse ( ) {
lastClick = ( int ) ( System . currentTimeMillis ( ) / Misc . TIME_CONVERSION_FACTOR ) ;
2013-03-06 18:31:48 +01:00
}
}