Change from using Block to BlockState in many locations

Convert Herbalism ability to use BlockState instead of Block.
Move all block checks back to BlockChecks.
Don't need this if we're using BlockState
Convert Excavation to BlockState. We don't need to return booleans here
because we never edit the block state.Switch ModCheck.getCustomBlock to use BlockState
More work on the conversion to BlockState
More conversion to BlockState
Better way to handle mining drops, I believe.
Remove useless imports.
A test of making the diff look nicer
BlockChecks diff cleanup
Herbalism diff cleanup
Gotta update the block states here.
Moar blockstate.
Little more blockState stuff.
Even more blockstate.
This commit is contained in:
NuclearW
2013-02-22 11:23:46 -05:00
parent 513a9212e4
commit d052d7a3ce
24 changed files with 994 additions and 1037 deletions

View File

@ -4,8 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import com.gmail.nossr50.config.Config;
@ -17,67 +16,34 @@ import com.gmail.nossr50.skills.utilities.PerksUtils;
import com.gmail.nossr50.skills.utilities.SkillType;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Users;
public class Excavation {
/**
* Check to see if treasures were found.
* Process treasure drops & XP gain for Excavation.
*
* @param block The block to check
* @param mcMMOPlayer The player who broke the block
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
*/
public static void excavationProcCheck(Block block, McMMOPlayer mcMMOPlayer) {
Material material = block.getType();
int xp = Config.getInstance().getXp(SkillType.EXCAVATION, material);
public static void excavationBlockCheck(BlockState blockState, Player player) {
McMMOPlayer mcMMOPlayer = Users.getPlayer(player);
int xp = Config.getInstance().getXp(SkillType.EXCAVATION, blockState.getType());
if (xp == 0 && ModChecks.isCustomExcavationBlock(block)) {
xp = ModChecks.getCustomBlock(block).getXpGain();
if (xp == 0 && ModChecks.isCustomExcavationBlock(blockState)) {
xp = ModChecks.getCustomBlock(blockState).getXpGain();
}
Player player = mcMMOPlayer.getPlayer();
List<ExcavationTreasure> treasures = new ArrayList<ExcavationTreasure>();
if (Permissions.excavationTreasureHunter(player)) {
switch (material) {
case DIRT:
treasures = TreasuresConfig.getInstance().excavationFromDirt;
break;
List<ExcavationTreasure> treasures = getTreasures(blockState);
case GRASS:
treasures = TreasuresConfig.getInstance().excavationFromGrass;
break;
if (!treasures.isEmpty()) {
int skillLevel = mcMMOPlayer.getProfile().getSkillLevel(SkillType.EXCAVATION);
int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.EXCAVATION);
Location location = blockState.getLocation();
case SAND:
treasures = TreasuresConfig.getInstance().excavationFromSand;
break;
case GRAVEL:
treasures = TreasuresConfig.getInstance().excavationFromGravel;
break;
case CLAY:
treasures = TreasuresConfig.getInstance().excavationFromClay;
break;
case MYCEL:
treasures = TreasuresConfig.getInstance().excavationFromMycel;
break;
case SOUL_SAND:
treasures = TreasuresConfig.getInstance().excavationFromSoulSand;
break;
default:
break;
}
Location location = block.getLocation();
for (ExcavationTreasure treasure : treasures) {
if (mcMMOPlayer.getProfile().getSkillLevel(SkillType.EXCAVATION) >= treasure.getDropLevel()) {
int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.EXCAVATION);
if (Misc.getRandom().nextDouble() * activationChance <= treasure.getDropChance()) {
for (ExcavationTreasure treasure : treasures) {
if (skillLevel >= treasure.getDropLevel() && Misc.getRandom().nextDouble() * activationChance <= treasure.getDropChance()) {
xp += treasure.getXp();
Misc.dropItem(location, treasure.getDrop());
}
@ -89,13 +55,47 @@ public class Excavation {
}
/**
* Handle triple drops from Giga Drill Breaker.
* Process the Giga Drill Breaker ability.
*
* @param mcMMOPlayer The player using the ability
* @param block The block to check
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
*/
public static void gigaDrillBreaker(McMMOPlayer mcMMOPlayer, Block block) {
Excavation.excavationProcCheck(block, mcMMOPlayer);
Excavation.excavationProcCheck(block, mcMMOPlayer);
public static void gigaDrillBreaker(BlockState blockState, Player player) {
Excavation.excavationBlockCheck(blockState, player);
Excavation.excavationBlockCheck(blockState, player);
}
}
/**
* Get the list of possible {@link ExcavationTreasure|ExcavationTreasures} obtained from a given block.
*
* @param blockState The {@link BlockState} of the block to check.
* @return the list of treasures that could be found
*/
private static List<ExcavationTreasure> getTreasures(BlockState blockState) {
switch (blockState.getType()) {
case DIRT:
return TreasuresConfig.getInstance().excavationFromDirt;
case GRASS:
return TreasuresConfig.getInstance().excavationFromGrass;
case SAND:
return TreasuresConfig.getInstance().excavationFromSand;
case GRAVEL:
return TreasuresConfig.getInstance().excavationFromGravel;
case CLAY:
return TreasuresConfig.getInstance().excavationFromClay;
case MYCEL:
return TreasuresConfig.getInstance().excavationFromMycel;
case SOUL_SAND:
return TreasuresConfig.getInstance().excavationFromSoulSand;
default:
return new ArrayList<ExcavationTreasure>();
}
}
}

View File

@ -1,86 +0,0 @@
package com.gmail.nossr50.skills.herbalism;
import org.bukkit.CropState;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.material.CocoaPlant;
import org.bukkit.material.CocoaPlant.CocoaPlantSize;
import com.gmail.nossr50.datatypes.PlayerProfile;
import com.gmail.nossr50.skills.utilities.AbilityType;
import com.gmail.nossr50.skills.utilities.SkillType;
public class GreenThumbTimer implements Runnable {
private Block block;
private PlayerProfile profile;
private Material type;
public GreenThumbTimer(Block block, PlayerProfile profile, Material material) {
this.block = block;
this.profile = profile;
this.type = material;
}
@Override
public void run() {
this.block.setType(this.type);
int skillLevel = this.profile.getSkillLevel(SkillType.HERBALISM);
int greenThumbStage = skillLevel / Herbalism.greenThumbStageChangeLevel;
if (greenThumbStage > 4) {
greenThumbStage = 4;
}
switch(this.type) {
case CROPS:
case CARROT:
case POTATO:
//This replants the wheat at a certain stage in development based on Herbalism Skill
if (!this.profile.getAbilityMode(AbilityType.GREEN_TERRA)) {
this.block.setData((byte) greenThumbStage);
}
else {
this.block.setData(CropState.MEDIUM.getData());
}
break;
case NETHER_WARTS:
if (!this.profile.getAbilityMode(AbilityType.GREEN_TERRA)) {
if (greenThumbStage == 3) {
this.block.setData((byte) 0x2);
}
else if (greenThumbStage == 2) {
this.block.setData((byte) 0x1);
}
else {
this.block.setData((byte) 0x0);
}
}
else {
this.block.setData((byte) 0x2);
}
break;
case COCOA:
CocoaPlant plant = (CocoaPlant) block.getState().getData();
if (!this.profile.getAbilityMode(AbilityType.GREEN_TERRA)) {
if (greenThumbStage == 3) {
plant.setSize(CocoaPlantSize.MEDIUM);
}
else if (greenThumbStage == 2) {
plant.setSize(CocoaPlantSize.MEDIUM);
}
else {
plant.setSize(CocoaPlantSize.SMALL);
}
}
else {
plant.setSize(CocoaPlantSize.MEDIUM);
}
block.setData(plant.getData());
break;
default:
break;
}
}
}

View File

@ -3,29 +3,29 @@ package com.gmail.nossr50.skills.herbalism;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.DyeColor;
import org.bukkit.CropState;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.material.CocoaPlant;
import org.bukkit.material.CocoaPlant.CocoaPlantSize;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.TreasuresConfig;
import com.gmail.nossr50.datatypes.McMMOPlayer;
import com.gmail.nossr50.datatypes.PlayerProfile;
import com.gmail.nossr50.datatypes.treasure.HylianTreasure;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mods.ModChecks;
import com.gmail.nossr50.mods.datatypes.CustomBlock;
import com.gmail.nossr50.skills.utilities.AbilityType;
import com.gmail.nossr50.skills.utilities.PerksUtils;
import com.gmail.nossr50.skills.utilities.SkillTools;
import com.gmail.nossr50.skills.utilities.SkillType;
import com.gmail.nossr50.util.Misc;
@ -65,63 +65,87 @@ public class Herbalism {
}
/**
* Activate the Green Terra ability.
* Process the Green Terra ability.
*
* @param player The player activating the ability
* @param block The block to be changed by Green Terra
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
* @return true if the ability was successful, false otherwise
*/
public static void greenTerra(Player player, Block block) {
PlayerInventory inventory = player.getInventory();
boolean hasSeeds = inventory.contains(Material.SEEDS);
public static boolean processGreenTerra(BlockState blockState, Player player) {
PlayerInventory playerInventory = player.getInventory();
ItemStack seed = new ItemStack(Material.SEEDS);
if (!hasSeeds) {
if (!playerInventory.containsAtLeast(seed, 1)) {
player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTe.NeedMore"));
return;
return false;
}
inventory.removeItem(new ItemStack(Material.SEEDS));
player.updateInventory(); // Needed until replacement available
greenTerraConvert(player, block);
playerInventory.removeItem(seed);
player.updateInventory(); // Needed until replacement available
return convertGreenTerraBlocks(blockState, player);
}
public static void greenTerraConvert(Player player, Block block) {
if (SkillTools.blockBreakSimulate(block, player, false)) {
Material type = block.getType();
/**
* Convert blocks affected by the Green Thumb & Green Terra abilities.
*
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
* @return true if the ability was successful, false otherwise
*/
private static boolean convertGreenTerraBlocks(BlockState blockState, Player player) {
Material blockType = blockState.getType();
if (!Permissions.greenThumbBlock(player, type)) {
return;
}
if (!Permissions.greenThumbBlock(player, blockType)) {
return false;
}
switch (type) {
case SMOOTH_BRICK:
block.setData((byte) 0x1);
return;
switch (blockType) {
case COBBLE_WALL:
case SMOOTH_BRICK:
blockState.setRawData((byte) 0x1);
return true;
case DIRT:
block.setType(Material.GRASS);
return;
case DIRT:
blockState.setType(Material.GRASS);
return true;
case COBBLESTONE:
block.setType(Material.MOSSY_COBBLESTONE);
return;
case COBBLESTONE:
blockState.setType(Material.MOSSY_COBBLESTONE);
return true;
case COBBLE_WALL:
block.setData((byte) 0x1);
return;
default:
return;
}
default:
return false;
}
}
private static int calculateCatciAndSugarDrops(Block block) {
Material blockType = block.getType();
/**
* Calculate the drop amounts for cacti & sugar cane based on the blocks above them.
*
* @param blockState The {@link BlockState} of the bottom block of the plant
* @return the number of bonus drops to award from the blocks in this plant
*/
private static int calculateCatciAndSugarDrops(BlockState blockState) {
Block block = blockState.getBlock();
Material blockType = blockState.getType();
int dropAmount = 0;
for (int y = 0; y <= 2; y++) {
// Handle the original block
if (!mcMMO.placeStore.isTrue(blockState)) {
dropAmount++;
}
// Handle the two blocks above it - cacti & sugar cane can only grow 3 high naturally
for (int y = 1; y < 3; y++) {
Block relativeBlock = block.getRelative(BlockFace.UP, y);
if (relativeBlock.getType() == blockType && !mcMMO.placeStore.isTrue(relativeBlock)) {
Material relativeBlockType = relativeBlock.getType();
// If the first one is air, so is the next one
if (relativeBlockType == Material.AIR) {
break;
}
if (relativeBlockType == blockType && !mcMMO.placeStore.isTrue(relativeBlock)) {
dropAmount++;
}
}
@ -130,23 +154,18 @@ public class Herbalism {
}
/**
* Check for extra Herbalism drops.
* Process double drops & XP gain for Herbalism.
*
* @param block The block to check for extra drops
* @param mcMMOPlayer The player getting extra drops
* @param event The event to use for Green Thumb
* @param plugin mcMMO plugin instance
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
* @return true if the ability was successful, false otherwise
*/
public static void herbalismProcCheck(final Block block, McMMOPlayer mcMMOPlayer, mcMMO plugin) {
Player player = mcMMOPlayer.getPlayer();
public static boolean herbalismBlockCheck(BlockState blockState, Player player) {
if (Config.getInstance().getHerbalismAFKDisabled() && player.isInsideVehicle()) {
return;
return false;
}
PlayerProfile profile = mcMMOPlayer.getProfile();
int herbLevel = profile.getSkillLevel(SkillType.HERBALISM);
Material blockType = block.getType();
Material blockType = blockState.getType();
HerbalismBlock herbalismBlock = HerbalismBlock.getHerbalismBlock(blockType);
CustomBlock customBlock = null;
@ -154,199 +173,226 @@ public class Herbalism {
int xp = 0;
int dropAmount = 1;
ItemStack dropItem = null;
boolean update = false;
if (herbalismBlock != null) {
if (blockType == Material.CACTUS || blockType == Material.SUGAR_CANE_BLOCK) {
dropItem = herbalismBlock.getDropItem();
dropAmount = calculateCatciAndSugarDrops(block);
dropAmount = calculateCatciAndSugarDrops(blockState);
xp = herbalismBlock.getXpGain() * dropAmount;
}
else if (herbalismBlock.hasGreenThumbPermission(player)){
dropItem = herbalismBlock.getDropItem();
xp = herbalismBlock.getXpGain();
greenThumbWheat(block, player, plugin);
update = processGreenThumbPlants(blockState, player);
}
else {
if (!mcMMO.placeStore.isTrue(block)) {
if (!mcMMO.placeStore.isTrue(blockState)) {
dropItem = herbalismBlock.getDropItem();
xp = herbalismBlock.getXpGain();
}
}
}
else {
customBlock = ModChecks.getCustomBlock(block);
customBlock = ModChecks.getCustomBlock(blockState);
dropItem = customBlock.getItemDrop();
xp = customBlock.getXpGain();
}
if (Permissions.doubleDrops(player, SkillType.HERBALISM)) {
int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.HERBALISM);
double chance = (doubleDropsMaxChance / doubleDropsMaxLevel) * SkillTools.skillCheck(herbLevel, doubleDropsMaxLevel);
if (Permissions.doubleDrops(player, SkillType.HERBALISM) && SkillTools.activationSuccessful(player, SkillType.HERBALISM, doubleDropsMaxChance, doubleDropsMaxLevel)) {
Location location = blockState.getLocation();
if (chance > Misc.getRandom().nextInt(activationChance)) {
Location location = block.getLocation();
if (dropItem != null && herbalismBlock != null && herbalismBlock.canDoubleDrop()) {
Misc.dropItems(location, dropItem, dropAmount);
}
else if (customBlock != null){
int minimumDropAmount = customBlock.getMinimumDropAmount();
int maximumDropAmount = customBlock.getMaximumDropAmount();
if (dropItem != null && herbalismBlock != null && herbalismBlock.canDoubleDrop()) {
Misc.dropItems(location, dropItem, dropAmount);
if (minimumDropAmount != maximumDropAmount) {
Misc.randomDropItems(location, dropItem, maximumDropAmount - minimumDropAmount);
}
else if (customBlock != null){
int minimumDropAmount = customBlock.getMinimumDropAmount();
int maximumDropAmount = customBlock.getMaximumDropAmount();
if (minimumDropAmount != maximumDropAmount) {
Misc.randomDropItems(location, dropItem, maximumDropAmount - minimumDropAmount);
}
Misc.dropItems(location, dropItem, minimumDropAmount);
}
Misc.dropItems(location, dropItem, minimumDropAmount);
}
}
mcMMOPlayer.beginXpGain(SkillType.HERBALISM, xp);
Users.getPlayer(player).beginXpGain(SkillType.HERBALISM, xp);
return update;
}
/**
* Apply the Green Thumb ability to crops.
* Convert plants affected by the Green Terra ability.
*
* @param block The block to apply the ability to
* @param player The player using the ability
* @param event The event triggering the ability
* @param plugin mcMMO plugin instance
* @param blockState The {@link BlockState} to check ability activation for
* @return true if the ability was successful, false otherwise
*/
private static void greenThumbWheat(Block block, Player player, mcMMO plugin) {
PlayerProfile profile = Users.getPlayer(player).getProfile();
int herbLevel = profile.getSkillLevel(SkillType.HERBALISM);
PlayerInventory inventory = player.getInventory();
boolean hasSeeds = false;
Material type = block.getType();
switch(type) {
private static boolean convertGreenTerraPlants(BlockState blockState) {
switch (blockState.getType()) {
case CROPS:
hasSeeds = inventory.contains(Material.SEEDS);
break;
case COCOA:
hasSeeds = inventory.containsAtLeast(new ItemStack(Material.INK_SACK, 1, DyeColor.BROWN.getDyeData()), 1);
break;
case CARROT:
hasSeeds = inventory.contains(Material.CARROT_ITEM);
break;
case POTATO:
hasSeeds = inventory.contains(Material.POTATO_ITEM);
break;
blockState.setRawData(CropState.MEDIUM.getData());
return true;
case NETHER_WARTS:
hasSeeds = inventory.contains(Material.NETHER_STALK);
break;
blockState.setRawData((byte) 0x2);
return true;
case COCOA:
CocoaPlant plant = (CocoaPlant) blockState.getData();
plant.setSize(CocoaPlantSize.MEDIUM);
blockState.setData(plant);
return true;
default:
break;
}
if (!hasSeeds) {
return;
}
int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.HERBALISM);
float chance = (float) (greenThumbMaxChance / greenThumbMaxLevel * herbLevel);
if (chance > greenThumbMaxChance) {
chance = (float) greenThumbMaxChance;
}
if (profile.getAbilityMode(AbilityType.GREEN_TERRA) || chance > Misc.getRandom().nextInt(activationChance)) {
switch(type) {
case CROPS:
inventory.removeItem(new ItemStack(Material.SEEDS));
break;
case COCOA:
inventory.removeItem(new ItemStack(Material.INK_SACK, 1, DyeColor.BROWN.getDyeData()));
break;
case CARROT:
inventory.removeItem(new ItemStack(Material.CARROT_ITEM));
break;
case POTATO:
inventory.removeItem(new ItemStack(Material.POTATO_ITEM));
break;
case NETHER_WARTS:
inventory.removeItem(new ItemStack(Material.NETHER_STALK));
break;
default:
break;
}
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new GreenThumbTimer(block, profile, type), 0);
player.updateInventory(); // Needed until replacement available
return false;
}
}
/**
* Apply the Green Thumb ability to blocks.
* Process the Green Thumb ability for blocks.
*
* @param is The item in the player's hand
* @param player The player activating the ability
* @param block The block being used in the ability
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
* @return true if the ability was successful, false otherwise
*/
public static void greenThumbBlocks(ItemStack is, Player player, Block block) {
PlayerProfile profile = Users.getPlayer(player).getProfile();
int skillLevel = profile.getSkillLevel(SkillType.HERBALISM);
int seeds = is.getAmount();
player.setItemInHand(new ItemStack(Material.SEEDS, seeds - 1));
int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.HERBALISM);
float chance = (float) ((greenThumbMaxChance / greenThumbMaxLevel) * skillLevel);
if (chance > greenThumbMaxChance) chance = (float) greenThumbMaxChance;
if (chance > Misc.getRandom().nextInt(activationChance)) {
greenTerraConvert(player, block);
}
else {
public static boolean processGreenThumbBlocks(BlockState blockState, Player player) {
if (!SkillTools.activationSuccessful(player, SkillType.HERBALISM, greenThumbMaxChance, greenThumbMaxLevel)) {
player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTh.Fail"));
return false;
}
return convertGreenTerraBlocks(blockState, player);
}
/**
* Convert plants affected by the Green Thumb ability.
*
* @param blockState The {@link BlockState} to check ability activation for
* @param skillLevel The player's Herbalism skill level
* @return true if the ability was successful, false otherwise
*/
private static boolean convertGreenThumbPlants(BlockState blockState, int skillLevel) {
int greenThumbStage = Math.min(skillLevel, greenThumbStageMaxLevel) / 4;
switch(blockState.getType()) {
case CROPS:
case CARROT:
case POTATO:
blockState.setRawData((byte) greenThumbStage);
return true;
case NETHER_WARTS:
if (greenThumbStage > 2) {
blockState.setRawData((byte) 0x2);
}
else if (greenThumbStage == 2) {
blockState.setRawData((byte) 0x1);
}
else {
blockState.setRawData((byte) 0x0);
}
return true;
case COCOA:
CocoaPlant plant = (CocoaPlant) blockState.getData();
if (greenThumbStage > 1) {
plant.setSize(CocoaPlantSize.MEDIUM);
}
else {
plant.setSize(CocoaPlantSize.SMALL);
}
blockState.setData(plant);
return true;
default:
return false;
}
}
public static void hylianLuck(Block block, Player player, BlockBreakEvent event) {
int skillLevel = Users.getPlayer(player).getProfile().getSkillLevel(SkillType.HERBALISM);
/**
* Process the Green Thumb ability for plants.
*
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
* @return true if the ability was successful, false otherwise
*/
private static boolean processGreenThumbPlants(BlockState blockState, Player player) {
PlayerInventory playerInventory = player.getInventory();
ItemStack seed = HerbalismBlock.getHerbalismBlock(blockState.getType()).getDropItem();
double chance = (hylianLuckMaxChance / hylianLuckMaxLevel) * SkillTools.skillCheck(skillLevel, hylianLuckMaxLevel);
int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.HERBALISM);
if (chance > Misc.getRandom().nextInt(activationChance)) {
List<HylianTreasure> treasures = new ArrayList<HylianTreasure>();
switch (block.getType()) {
case DEAD_BUSH:
case LONG_GRASS:
case SAPLING:
treasures = TreasuresConfig.getInstance().hylianFromBushes;
break;
case RED_ROSE:
case YELLOW_FLOWER:
if (mcMMO.placeStore.isTrue(block)) {
mcMMO.placeStore.setFalse(block);
return;
}
treasures = TreasuresConfig.getInstance().hylianFromFlowers;
break;
case FLOWER_POT:
treasures = TreasuresConfig.getInstance().hylianFromPots;
break;
default:
return;
}
if (treasures.isEmpty()) {
return;
}
event.setCancelled(true);
event.getBlock().setType(Material.AIR);
Misc.dropItem(block.getLocation(), treasures.get(Misc.getRandom().nextInt(treasures.size())).getDrop());
player.sendMessage(LocaleLoader.getString("Herbalism.HylianLuck"));
if (!playerInventory.containsAtLeast(seed, 1)) {
return false;
}
PlayerProfile playerProfile = Users.getPlayer(player).getProfile();
if (playerProfile.getAbilityMode(AbilityType.GREEN_TERRA)) {
playerInventory.removeItem(seed);
player.updateInventory(); // Needed until replacement available
return convertGreenTerraPlants(blockState);
}
else if (SkillTools.activationSuccessful(player, SkillType.HERBALISM, greenThumbMaxChance, greenThumbMaxLevel)) {
playerInventory.removeItem(seed);
player.updateInventory(); // Needed until replacement available
return convertGreenThumbPlants(blockState, playerProfile.getSkillLevel(SkillType.HERBALISM));
}
return false;
}
/**
* Process the Hylian Luck ability.
*
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
* @return true if the ability was successful, false otherwise
*/
public static boolean processHylianLuck(BlockState blockState, Player player) {
if (!SkillTools.activationSuccessful(player, SkillType.HERBALISM, hylianLuckMaxChance, hylianLuckMaxLevel)) {
return false;
}
List<HylianTreasure> treasures = new ArrayList<HylianTreasure>();
switch (blockState.getType()) {
case DEAD_BUSH:
case LONG_GRASS:
case SAPLING:
treasures = TreasuresConfig.getInstance().hylianFromBushes;
break;
case RED_ROSE:
case YELLOW_FLOWER:
if (mcMMO.placeStore.isTrue(blockState)) {
mcMMO.placeStore.setFalse(blockState);
return false;
}
treasures = TreasuresConfig.getInstance().hylianFromFlowers;
break;
case FLOWER_POT:
treasures = TreasuresConfig.getInstance().hylianFromPots;
break;
default:
return false;
}
if (treasures.isEmpty()) {
return false;
}
blockState.setRawData((byte) 0x0);
blockState.setType(Material.AIR);
Misc.dropItem(blockState.getLocation(), treasures.get(Misc.getRandom().nextInt(treasures.size())).getDrop());
player.sendMessage(LocaleLoader.getString("Herbalism.HylianLuck"));
return true;
}
}

View File

@ -6,11 +6,11 @@ import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.McMMOPlayer;
import com.gmail.nossr50.util.BlockChecks;
import com.gmail.nossr50.util.Misc;
@ -20,9 +20,9 @@ public class BlastMiningDropEventHandler {
private EntityExplodeEvent event;
private float yield;
private List<Block> blocks;
private List<Block> ores = new ArrayList<Block>();
private List<Block> debris = new ArrayList<Block>();
private List<Block> droppedOres = new ArrayList<Block>();
private List<BlockState> ores = new ArrayList<BlockState>();
private List<BlockState> debris = new ArrayList<BlockState>();
private List<BlockState> droppedOres = new ArrayList<BlockState>();
private float oreBonus;
private float debrisReduction;
private int dropMultiplier;
@ -38,38 +38,35 @@ public class BlastMiningDropEventHandler {
protected void sortExplosionBlocks() {
for (Block block : blocks) {
if (BlockChecks.isOre(block)) {
ores.add(block);
BlockState blockState = block.getState();
if (BlockChecks.isOre(blockState)) {
ores.add(blockState);
}
else {
debris.add(block);
debris.add(blockState);
}
}
}
protected void processXPGain() {
McMMOPlayer mcMMOPlayer = manager.getMcMMOPlayer();
for (Block block : droppedOres) {
if (!mcMMO.placeStore.isTrue(block)) {
Mining.miningXP(mcMMOPlayer, block, block.getType());
for (BlockState blockState : droppedOres) {
if (!mcMMO.placeStore.isTrue(blockState)) {
Mining.awardMiningXp(blockState, manager.getMcMMOPlayer().getPlayer());
}
}
}
protected void processDroppedBlocks() {
for (Block block : ores) {
Location location = block.getLocation();
Material type = block.getType();
for (BlockState blockState : ores) {
if (Misc.getRandom().nextFloat() < (yield + oreBonus)) {
droppedOres.add(block);
Mining.miningDrops(block, location, type);
droppedOres.add(blockState);
Mining.handleMiningDrops(blockState);
if (!mcMMO.placeStore.isTrue(block)) {
if (!mcMMO.placeStore.isTrue(blockState)) {
for (int i = 1 ; i < dropMultiplier ; i++) {
droppedOres.add(block);
Mining.miningDrops(block, location, type);
droppedOres.add(blockState);
Mining.handleMiningDrops(blockState);
}
}
}
@ -78,9 +75,9 @@ public class BlastMiningDropEventHandler {
float debrisYield = yield - debrisReduction;
if (debrisYield > 0) {
for (Block block : debris) {
Location location = block.getLocation();
Material type = block.getType();
for (BlockState blockState : debris) {
Location location = blockState.getLocation();
Material type = blockState.getType();
if (Misc.getRandom().nextFloat() < debrisYield) {
Misc.dropItem(location, new ItemStack(type));

View File

@ -1,19 +1,21 @@
package com.gmail.nossr50.skills.mining;
import org.bukkit.CoalType;
import org.bukkit.DyeColor;
import org.bukkit.Location;
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.inventory.ItemStack;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.McMMOPlayer;
import com.gmail.nossr50.mods.ModChecks;
import com.gmail.nossr50.mods.datatypes.CustomBlock;
import com.gmail.nossr50.skills.utilities.SkillTools;
import com.gmail.nossr50.skills.utilities.SkillType;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Users;
public class Mining {
private static AdvancedConfig advancedConfig = AdvancedConfig.getInstance();
@ -21,44 +23,58 @@ public class Mining {
public static int doubleDropsMaxLevel = advancedConfig.getMiningDoubleDropMaxLevel();
public static double doubleDropsMaxChance = advancedConfig.getMiningDoubleDropChance();
public static final int DIAMOND_TOOL_TIER = 4;
public static final int IRON_TOOL_TIER = 3;
public static final int STONE_TOOL_TIER = 2;
/**
* Process double drops & XP gain for Mining.
*
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
*/
public static void miningBlockCheck(BlockState blockState, Player player) {
awardMiningXp(blockState, player);
if (Permissions.doubleDrops(player, SkillType.MINING) && SkillTools.activationSuccessful(player, SkillType.MINING, doubleDropsMaxChance, doubleDropsMaxLevel)) {
if (player.getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)) {
handleSilkTouchDrops(blockState);
}
else {
handleMiningDrops(blockState);
}
}
}
/**
* Award XP for Mining blocks.
* Award XP gain for Mining.
*
* @param mcMMOPlayer The player to award XP to
* @param block The block to award XP for
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
*/
protected static void miningXP(McMMOPlayer mcMMOPlayer, Block block, Material type) {
int xp = Config.getInstance().getXp(SkillType.MINING, type);
protected static void awardMiningXp(BlockState blockState, Player player) {
Material blockType = blockState.getType();
int xp = Config.getInstance().getXp(SkillType.MINING, blockType);
if (type == Material.GLOWING_REDSTONE_ORE) {
if (blockType == Material.GLOWING_REDSTONE_ORE) {
xp = Config.getInstance().getXp(SkillType.MINING, Material.REDSTONE_ORE);
}
else if (xp == 0 && ModChecks.isCustomMiningBlock(block)) {
xp = ModChecks.getCustomBlock(block).getXpGain();
else if (xp == 0 && ModChecks.isCustomMiningBlock(blockState)) {
xp = ModChecks.getCustomBlock(blockState).getXpGain();
}
mcMMOPlayer.beginXpGain(SkillType.MINING, xp);
Users.getPlayer(player).beginXpGain(SkillType.MINING, xp);
}
/**
* Handle double drops when using Silk Touch.
*
* @param block The block to process drops for
* @param location The location of the block
* @param type The material type of the block
* @param blockState The {@link BlockState} to check ability activation for
*/
protected static void silkTouchDrops(Block block, Location location, Material type) {
ItemStack item = new ItemStack(type);
protected static void handleSilkTouchDrops(BlockState blockState) {
Material blockType = blockState.getType();
if (type != Material.GLOWING_REDSTONE_ORE && !Config.getInstance().getDoubleDropsEnabled(SkillType.MINING, type)) {
if (blockType != Material.GLOWING_REDSTONE_ORE && !Config.getInstance().getDoubleDropsEnabled(SkillType.MINING, blockType)) {
return;
}
switch (type) {
switch (blockType) {
case ENDER_STONE:
case GOLD_ORE:
case IRON_ORE:
@ -66,14 +82,14 @@ public class Mining {
case NETHERRACK:
case OBSIDIAN:
case SANDSTONE:
miningDrops(block, location, type);
break;
handleMiningDrops(blockState);
return;
case GLOWING_REDSTONE_ORE:
if (Config.getInstance().getDoubleDropsEnabled(SkillType.MINING, Material.REDSTONE_ORE)) {
Misc.dropItem(location, item);
Misc.dropItem(blockState.getLocation(), new ItemStack(Material.REDSTONE_ORE));
}
break;
return;
case COAL_ORE:
case DIAMOND_ORE:
@ -82,75 +98,39 @@ public class Mining {
case LAPIS_ORE:
case STONE:
case EMERALD_ORE:
Misc.dropItem(location, item);
break;
Misc.dropItem(blockState.getLocation(), new ItemStack(blockType));
return;
default:
if (ModChecks.isCustomMiningBlock(block)) {
ItemStack dropItem = new ItemStack(block.getTypeId(), 1, block.getData());
Misc.dropItem(location, dropItem);
if (ModChecks.isCustomMiningBlock(blockState)) {
Misc.dropItem(blockState.getLocation(), blockState.getData().toItemStack());
}
break;
return;
}
}
/**
* Drop items from Mining & Blast Mining skills.
* Handle double drops from Mining & Blast Mining.
*
* @param block The block to process drops for
* @param location The location of the block
* @param type The material type of the block
* @param blockState The {@link BlockState} to check ability activation for
*/
protected static void miningDrops(Block block, Location location, Material type) {
if (type != Material.GLOWING_REDSTONE_ORE && !Config.getInstance().getDoubleDropsEnabled(SkillType.MINING, type)) {
protected static void handleMiningDrops(BlockState blockState) {
Material blockType = blockState.getType();
if (blockType != Material.GLOWING_REDSTONE_ORE && !Config.getInstance().getDoubleDropsEnabled(SkillType.MINING, blockType)) {
return;
}
ItemStack item = new ItemStack(type);
Location location = blockState.getLocation();
ItemStack dropItem;
switch (type) {
switch (blockType) {
case COAL_ORE:
item = new ItemStack(Material.COAL, 1, CoalType.COAL.getData());
Misc.dropItem(location, item);
break;
case DIAMOND_ORE:
item = new ItemStack(Material.DIAMOND);
Misc.dropItem(location, item);
break;
case EMERALD_ORE:
item = new ItemStack(Material.EMERALD);
Misc.dropItem(location, item);
break;
case GLOWING_REDSTONE_ORE:
case REDSTONE_ORE:
if (Config.getInstance().getDoubleDropsEnabled(SkillType.MINING, Material.REDSTONE_ORE)) {
item = new ItemStack(Material.REDSTONE);
Misc.dropItems(location, item, 4);
Misc.randomDropItem(location, item, 50);
}
break;
case GLOWSTONE:
item = new ItemStack(Material.GLOWSTONE_DUST);
Misc.dropItems(location, item, 2);
Misc.randomDropItems(location, item, 2);
break;
case LAPIS_ORE:
item = new ItemStack(Material.INK_SACK, 1, DyeColor.BLUE.getDyeData());
Misc.dropItems(location, item, 4);
Misc.randomDropItems(location, item, 4);
break;
case STONE:
item = new ItemStack(Material.COBBLESTONE);
Misc.dropItem(location, item);
break;
case ENDER_STONE:
case GOLD_ORE:
case IRON_ORE:
@ -158,26 +138,36 @@ public class Mining {
case NETHERRACK:
case OBSIDIAN:
case SANDSTONE:
Misc.dropItem(location, item);
break;
for (ItemStack drop : blockState.getBlock().getDrops()) {
Misc.dropItem(location, drop);
}
return;
case GLOWING_REDSTONE_ORE:
case REDSTONE_ORE:
if (Config.getInstance().getDoubleDropsEnabled(SkillType.MINING, Material.REDSTONE_ORE)) {
for (ItemStack drop : blockState.getBlock().getDrops()) {
Misc.dropItem(location, drop);
}
}
return;
default:
if (ModChecks.isCustomMiningBlock(block)) {
CustomBlock customBlock = ModChecks.getCustomBlock(block);
if (ModChecks.isCustomMiningBlock(blockState)) {
CustomBlock customBlock = ModChecks.getCustomBlock(blockState);
int minimumDropAmount = customBlock.getMinimumDropAmount();
int maximumDropAmount = customBlock.getMaximumDropAmount();
item = ModChecks.getCustomBlock(block).getItemDrop();
dropItem = customBlock.getItemDrop();
if (minimumDropAmount != maximumDropAmount) {
Misc.dropItems(location, item, minimumDropAmount);
Misc.randomDropItems(location, item, maximumDropAmount - minimumDropAmount);
Misc.dropItems(location, dropItem, minimumDropAmount);
Misc.randomDropItems(location, dropItem, maximumDropAmount - minimumDropAmount);
}
else {
Misc.dropItems(location, item, minimumDropAmount);
Misc.dropItems(location, dropItem, minimumDropAmount);
}
}
break;
return;
}
}
}

View File

@ -1,45 +0,0 @@
package com.gmail.nossr50.skills.mining;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import com.gmail.nossr50.skills.utilities.SkillTools;
public class MiningBlockEventHandler {
private MiningManager manager;
private Block block;
private Location blockLocation;
private Material blockType;
protected int skillModifier;
protected MiningBlockEventHandler(MiningManager manager, Block block) {
this.manager = manager;
this.block = block;
this.blockLocation = block.getLocation();
this.blockType = block.getType();
calculateSkillModifier();
}
private void calculateSkillModifier() {
this.skillModifier = SkillTools.skillCheck(manager.getSkillLevel(), Mining.doubleDropsMaxLevel);
}
/**
* Process Mining block drops.
*/
protected void processDrops() {
if (manager.getMcMMOPlayer().getPlayer().getItemInHand().containsEnchantment(Enchantment.SILK_TOUCH)) {
Mining.silkTouchDrops(block, blockLocation, blockType);
}
else {
Mining.miningDrops(block, blockLocation, blockType);
}
}
protected void processXPGain() {
Mining.miningXP(manager.getMcMMOPlayer(), block, blockType);
}
}

View File

@ -1,7 +1,6 @@
package com.gmail.nossr50.skills.mining;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.ExplosionPrimeEvent;
@ -12,7 +11,6 @@ import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.skills.utilities.SkillTools;
import com.gmail.nossr50.skills.utilities.SkillType;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
public class MiningManager extends SkillManager{
public MiningManager (McMMOPlayer mcMMOPlayer) {
@ -102,24 +100,4 @@ public class MiningManager extends SkillManager{
eventHandler.calculateRadiusIncrease();
eventHandler.modifyBlastRadius();
}
/**
* Process Mining block drops.
*
* @param block The block being broken
*/
public void miningBlockCheck(Block block) {
MiningBlockEventHandler eventHandler = new MiningBlockEventHandler(this, block);
eventHandler.processXPGain();
if (!Permissions.doubleDrops(mcMMOPlayer.getPlayer(), skill)) {
return;
}
float chance = ((float) Mining.doubleDropsMaxChance / Mining.doubleDropsMaxLevel) * eventHandler.skillModifier;
if (chance > Misc.getRandom().nextInt(activationChance)) {
eventHandler.processDrops();
}
}
}

View File

@ -1,68 +0,0 @@
package com.gmail.nossr50.skills.smelting;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.datatypes.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.mining.Mining;
import com.gmail.nossr50.skills.utilities.SkillTools;
import com.gmail.nossr50.skills.utilities.SkillType;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
public class FluxMiningEventHandler {
private SmeltingManager manager;
private BlockBreakEvent event;
private Block block;
protected FluxMiningEventHandler(SmeltingManager manager, BlockBreakEvent event) {
this.manager = manager;
this.event = event;
this.block = event.getBlock();
}
protected void processDrops() {
ItemStack item = null;
switch (block.getType()) {
case IRON_ORE:
item = new ItemStack(Material.IRON_INGOT);
break;
case GOLD_ORE:
item = new ItemStack(Material.GOLD_INGOT);
break;
default:
break;
}
if (item == null) {
return;
}
Location location = block.getLocation();
Misc.dropItem(location, item);
McMMOPlayer mcMMOPlayer = manager.getMcMMOPlayer();
if (Permissions.doubleDrops(mcMMOPlayer.getPlayer(), manager.getSkill())) {
int chance = (int) ((Mining.doubleDropsMaxChance / Mining.doubleDropsMaxLevel) * (SkillTools.skillCheck(mcMMOPlayer.getProfile().getSkillLevel(SkillType.MINING), Mining.doubleDropsMaxLevel)));
Misc.randomDropItem(location, item, chance);
}
}
protected void eventCancellationAndProcessing() {
event.setCancelled(true);
block.setType(Material.AIR);
}
protected void sendAbilityMessage() {
manager.getMcMMOPlayer().getPlayer().sendMessage(LocaleLoader.getString("Smelting.FluxMining.Success"));
}
}

View File

@ -1,6 +1,18 @@
package com.gmail.nossr50.skills.smelting;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.mining.Mining;
import com.gmail.nossr50.skills.utilities.SkillTools;
import com.gmail.nossr50.skills.utilities.SkillType;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
public class Smelting {
public static int burnModifierMaxLevel = AdvancedConfig.getInstance().getBurnModifierMaxLevel();
@ -23,4 +35,49 @@ public class Smelting {
public static int vanillaXPBoostRank3Multiplier = AdvancedConfig.getInstance().getSmeltingVanillaXPBoostRank3Multiplier();
public static int vanillaXPBoostRank4Multiplier = AdvancedConfig.getInstance().getSmeltingVanillaXPBoostRank4Multiplier();
public static int vanillaXPBoostRank5Multiplier = AdvancedConfig.getInstance().getSmeltingVanillaXPBoostRank5Multiplier();
/**
* Process the Flux Mining ability.
*
* @param blockState The {@link BlockState} to check ability activation for
* @param player The {@link Player} using this ability
* @return true if the ability was successful, false otherwise
*/
public static boolean processFluxMining(BlockState blockState, Player player) {
if (SkillTools.unlockLevelReached(player, SkillType.SMELTING, fluxMiningUnlockLevel) && SkillTools.activationSuccessful(player, SkillType.SMELTING, fluxMiningChance)) {
ItemStack item = null;
switch (blockState.getType()) {
case IRON_ORE:
item = new ItemStack(Material.IRON_INGOT);
break;
case GOLD_ORE:
item = new ItemStack(Material.GOLD_INGOT);
break;
default:
break;
}
if (item == null) {
return false;
}
Location location = blockState.getLocation();
Misc.dropItem(location, item);
if (Permissions.doubleDrops(player, SkillType.SMELTING) && SkillTools.activationSuccessful(player, SkillType.SMELTING, Mining.doubleDropsMaxChance, Mining.doubleDropsMaxLevel)) {
Misc.dropItem(location, item);
}
blockState.setRawData((byte) 0x0);
blockState.setType(Material.AIR);
player.sendMessage(LocaleLoader.getString("Smelting.FluxMining.Success"));
return true;
}
return false;
}
}

View File

@ -1,7 +1,6 @@
package com.gmail.nossr50.skills.smelting;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.inventory.FurnaceBurnEvent;
import org.bukkit.event.inventory.FurnaceExtractEvent;
import org.bukkit.event.inventory.FurnaceSmeltEvent;
@ -60,19 +59,6 @@ public class SmeltingManager extends SkillManager {
}
}
public void fluxMining(BlockBreakEvent event) {
if (skillLevel < Smelting.fluxMiningUnlockLevel) {
return;
}
if (Smelting.fluxMiningChance > Misc.getRandom().nextInt(activationChance)) {
FluxMiningEventHandler eventHandler = new FluxMiningEventHandler(this, event);
eventHandler.processDrops();
eventHandler.eventCancellationAndProcessing();
eventHandler.sendAbilityMessage();
}
}
public void vanillaXPBoost(FurnaceExtractEvent event) {
if (skillLevel < Smelting.vanillaXPBoostRank1Level || !Permissions.vanillaXpBoost(mcMMOPlayer.getPlayer(), skill)) {
return;

View File

@ -1,7 +1,7 @@
package com.gmail.nossr50.skills.unarmed;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import com.gmail.nossr50.config.AdvancedConfig;
@ -25,20 +25,22 @@ public class Unarmed {
public static double berserkDamageModifier = 1.5;
public static void blockCracker(Player player, Block block) {
if (SkillTools.blockBreakSimulate(block, player, false)) {
Material type = block.getType();
public static boolean blockCracker(Player player, BlockState blockState) {
if (SkillTools.blockBreakSimulate(blockState.getBlock(), player, false)) {
Material type = blockState.getType();
switch (type) {
case SMOOTH_BRICK:
if (blockCrackerSmoothBrick && block.getData() == 0x0) {
block.setData((byte) 0x2);
if (blockCrackerSmoothBrick && blockState.getRawData() == (byte) 0x0) {
blockState.setRawData((byte) 0x2);
}
return;
return true;
default:
return;
return false;
}
}
return false;
}
}

View File

@ -1,7 +1,7 @@
package com.gmail.nossr50.skills.utilities;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import com.gmail.nossr50.config.Config;
@ -181,28 +181,28 @@ public enum AbilityType {
/**
* Check if a block is affected by this ability.
*
* @param block the block to check
* @param blockState the block to check
* @return true if the block is affected by this ability, false otherwise
*/
public boolean blockCheck(Block block) {
public boolean blockCheck(BlockState blockState) {
switch (this) {
case BERSERK:
return (BlockChecks.canBeGigaDrillBroken(block) || block.getType() == Material.SNOW);
return (BlockChecks.affectedByGigaDrillBreaker(blockState) || blockState.getType() == Material.SNOW);
case GIGA_DRILL_BREAKER:
return BlockChecks.canBeGigaDrillBroken(block);
return BlockChecks.affectedByGigaDrillBreaker(blockState);
case GREEN_TERRA:
return BlockChecks.canMakeMossy(block);
return BlockChecks.canMakeMossy(blockState);
case LEAF_BLOWER:
return block.getType() == Material.LEAVES;
return BlockChecks.isLeaves(blockState);
case SUPER_BREAKER:
return BlockChecks.canBeSuperBroken(block);
return BlockChecks.affectedBySuperBreaker(blockState);
case TREE_FELLER:
return block.getType() == Material.LOG;
return BlockChecks.isLog(blockState);
default:
return false;

View File

@ -426,10 +426,8 @@ public class SkillTools {
switch (ability) {
case BERSERK:
case GIGA_DRILL_BREAKER:
case SUPER_BREAKER:
case LEAF_BLOWER:
if (!ability.blockCheck(block)) {
if (!ability.blockCheck(block.getState())) {
activate = false;
break;
}
@ -440,8 +438,10 @@ public class SkillTools {
}
break;
case GIGA_DRILL_BREAKER:
case SUPER_BREAKER:
case GREEN_TERRA:
if (!ability.blockCheck(block)) {
if (!ability.blockCheck(block.getState())) {
activate = false;
break;
}
@ -480,7 +480,7 @@ public class SkillTools {
}
public static void handleAbilitySpeedIncrease(Player player) {
if (HiddenConfig.getInstance().useEnchantmentBuffs()) {
if (HiddenConfig.getInstance().useEnchantmentBuffs()) {
ItemStack heldItem = player.getItemInHand();
if (heldItem == null || heldItem.getType() == Material.AIR ) {
@ -583,15 +583,13 @@ public class SkillTools {
* @return true if the event wasn't cancelled, false otherwise
*/
public static boolean blockBreakSimulate(Block block, Player player, Boolean shouldArmSwing) {
PluginManager pluginManger = mcMMO.p.getServer().getPluginManager();
//Support for NoCheat
if (shouldArmSwing) {
FakePlayerAnimationEvent armswing = new FakePlayerAnimationEvent(player);
mcMMO.p.getServer().getPluginManager().callEvent(armswing);
pluginManger.callEvent(new FakePlayerAnimationEvent(player));
}
PluginManager pluginManger = mcMMO.p.getServer().getPluginManager();
FakeBlockDamageEvent damageEvent = new FakeBlockDamageEvent(player, block, player.getItemInHand(), true);
pluginManger.callEvent(damageEvent);
@ -604,4 +602,20 @@ public class SkillTools {
return false;
}
public static boolean activationSuccessful(Player player, SkillType skill, double maxChance, int maxLevel) {
int skillLevel = Users.getPlayer(player).getProfile().getSkillLevel(skill);
int activationChance = PerksUtils.handleLuckyPerks(player, skill);
double chance = (maxChance / maxLevel) * Math.min(skillLevel, maxLevel);
return chance > Misc.getRandom().nextInt(activationChance);
}
public static boolean activationSuccessful(Player player, SkillType skill, double chance) {
return chance > Misc.getRandom().nextInt(PerksUtils.handleLuckyPerks(player, skill));
}
public static boolean unlockLevelReached(Player player, SkillType skill, int unlockLevel) {
return Users.getPlayer(player).getProfile().getSkillLevel(skill) > unlockLevel;
}
}

View File

@ -6,13 +6,14 @@ import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Tree;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.datatypes.McMMOPlayer;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mods.ModChecks;
import com.gmail.nossr50.mods.datatypes.CustomBlock;
@ -22,6 +23,7 @@ import com.gmail.nossr50.skills.utilities.SkillType;
import com.gmail.nossr50.skills.woodcutting.Woodcutting.ExperienceGainMethod;
import com.gmail.nossr50.util.BlockChecks;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Users;
public final class TreeFeller {
private static boolean treeFellerReachedThreshold = false;
@ -32,26 +34,24 @@ public final class TreeFeller {
* Begins Tree Feller
*
* @param mcMMOPlayer Player using Tree Feller
* @param block Block being broken
* @param blockState Block being broken
*/
public static void process(McMMOPlayer mcMMOPlayer, Block block) {
List<Block> treeFellerBlocks = new ArrayList<Block>();
protected static void process(BlockState blockState, Player player) {
List<BlockState> treeFellerBlocks = new ArrayList<BlockState>();
processRecursively(block, treeFellerBlocks);
processRecursively(blockState, treeFellerBlocks);
// If the player is trying to break to many block
// If the player is trying to break too many blocks
if (treeFellerReachedThreshold) {
treeFellerReachedThreshold = false;
mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFellerThreshold"));
player.sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFellerThreshold"));
return;
}
Player player = mcMMOPlayer.getPlayer();
// If the tool can't sustain the durability loss
if (!handleDurabilityLoss(treeFellerBlocks, player.getItemInHand())) {
mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFeller.Splinter"));
player.sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFeller.Splinter"));
int health = player.getHealth();
@ -62,28 +62,28 @@ public final class TreeFeller {
return;
}
dropBlocks(treeFellerBlocks, mcMMOPlayer);
dropBlocks(treeFellerBlocks, player);
}
/**
* Processes Tree Feller
*
* @param block Block being checked
* @param blockState Block being checked
* @param treeFellerBlocks List of blocks to be removed
*/
private static void processRecursively(Block block, List<Block> treeFellerBlocks) {
if (!BlockChecks.isLog(block)) {
private static void processRecursively(BlockState blockState, List<BlockState> treeFellerBlocks) {
if (!BlockChecks.isLog(blockState)) {
return;
}
List<Block> futureCenterBlocks = new ArrayList<Block>();
World world = block.getWorld();
List<BlockState> futureCenterBlocks = new ArrayList<BlockState>();
World world = blockState.getWorld();
// Handle the blocks around 'block'
for (int y = 0 ; y <= 1 ; y++) {
for (int x = -1 ; x <= 1 ; x++) {
for (int z = -1 ; z <= 1 ; z++) {
Block nextBlock = world.getBlockAt(block.getLocation().add(x, y, z));
for (int y = 0; y <= 1; y++) {
for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
BlockState nextBlock = world.getBlockAt(blockState.getLocation().add(x, y, z)).getState();
handleBlock(nextBlock, futureCenterBlocks, treeFellerBlocks);
@ -95,12 +95,12 @@ public final class TreeFeller {
}
// Recursive call for each log found
for (Block futurCenterBlock : futureCenterBlocks) {
for (BlockState futureCenterBlock : futureCenterBlocks) {
if (treeFellerReachedThreshold) {
return;
}
processRecursively(futurCenterBlock, treeFellerBlocks);
processRecursively(futureCenterBlock, treeFellerBlocks);
}
}
@ -108,23 +108,23 @@ public final class TreeFeller {
* Handle a block addition to the list of blocks to be removed
* and to the list of blocks used for future recursive calls of 'processRecursively()'
*
* @param block Block to be added
* @param blockState Block to be added
* @param futureCenterBlocks List of blocks that will be used to call 'processRecursively()'
* @param treeFellerBlocks List of blocks to be removed
*/
private static void handleBlock(Block block, List<Block> futureCenterBlocks, List<Block> treeFellerBlocks) {
if (!BlockChecks.treeFellerCompatible(block) || mcMMO.placeStore.isTrue(block) || treeFellerBlocks.contains(block)) {
private static void handleBlock(BlockState blockState, List<BlockState> futureCenterBlocks, List<BlockState> treeFellerBlocks) {
if (!BlockChecks.affectedByTreeFeller(blockState) || mcMMO.placeStore.isTrue(blockState) || treeFellerBlocks.contains(blockState)) {
return;
}
treeFellerBlocks.add(block);
treeFellerBlocks.add(blockState);
if (treeFellerBlocks.size() > Woodcutting.CONFIG.getTreeFellerThreshold()) {
if (treeFellerBlocks.size() > Config.getInstance().getTreeFellerThreshold()) {
treeFellerReachedThreshold = true;
return;
}
futureCenterBlocks.add(block);
futureCenterBlocks.add(blockState);
}
/**
@ -134,15 +134,15 @@ public final class TreeFeller {
* @param inHand tool being used
* @return True if the tool can sustain the durability loss
*/
private static boolean handleDurabilityLoss(List<Block> treeFellerBlocks, ItemStack inHand) {
private static boolean handleDurabilityLoss(List<BlockState> treeFellerBlocks, ItemStack inHand) {
Material inHandMaterial = inHand.getType();
if (inHandMaterial != Material.AIR) {
short durabilityLoss = 0;
int unbreakingLevel = inHand.getEnchantmentLevel(Enchantment.DURABILITY);
for (Block block : treeFellerBlocks) {
if (BlockChecks.isLog(block) && Misc.getRandom().nextInt(unbreakingLevel + 1) == 0) {
for (BlockState blockState : treeFellerBlocks) {
if (BlockChecks.isLog(blockState) && Misc.getRandom().nextInt(unbreakingLevel + 1) == 0) {
durabilityLoss += SkillTools.toolDurabilityLoss;
}
}
@ -165,87 +165,74 @@ public final class TreeFeller {
* Handles the dropping of blocks
*
* @param treeFellerBlocks List of blocks to be dropped
* @param mcMMOPlayer Player using the ability
* @param player Player using the ability
*/
private static void dropBlocks(List<Block> treeFellerBlocks, McMMOPlayer mcMMOPlayer) {
private static void dropBlocks(List<BlockState> treeFellerBlocks, Player player) {
int xp = 0;
for (Block block : treeFellerBlocks) {
if (!SkillTools.blockBreakSimulate(block, mcMMOPlayer.getPlayer(), true)) {
for (BlockState blockState : treeFellerBlocks) {
if (!SkillTools.blockBreakSimulate(blockState.getBlock(), player, true)) {
break; // TODO: Shouldn't we use continue instead?
}
Material material = block.getType();
Material material = blockState.getType();
switch (material) {
case HUGE_MUSHROOM_1:
case HUGE_MUSHROOM_2:
try {
xp += Woodcutting.getExperienceFromLog(block, ExperienceGainMethod.TREE_FELLER);
}
catch (IllegalArgumentException exception) {
break;
}
xp += Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.TREE_FELLER);
// Stems have a block data value of 15 and should not drop mushrooms
// 0-2 mushrooms drop when you break a block
if (block.getData() == (byte) 15) {
break;
}
if (material == Material.HUGE_MUSHROOM_1) {
Misc.randomDropItems(block.getLocation(), new ItemStack(Material.BROWN_MUSHROOM), 2);
}
else {
Misc.randomDropItems(block.getLocation(), new ItemStack(Material.RED_MUSHROOM), 2);
for (ItemStack drop : blockState.getBlock().getDrops()) {
Misc.dropItem(blockState.getLocation(), drop);
}
break;
case LOG:
Woodcutting.checkForDoubleDrop(mcMMOPlayer, block);
try {
xp += Woodcutting.getExperienceFromLog(block, ExperienceGainMethod.TREE_FELLER);
}
catch (IllegalArgumentException exception) {
break;
}
Misc.dropItem(block.getLocation(), new ItemStack(Material.LOG, 1, Woodcutting.extractLogItemData(block.getData())));
break;
case LEAVES:
Misc.randomDropItem(block.getLocation(), new ItemStack(Material.SAPLING, 1, Woodcutting.extractLogItemData(block.getData())), 10);
break;
default:
if (ModChecks.isCustomLogBlock(block)) {
Woodcutting.checkForDoubleDrop(mcMMOPlayer, block);
CustomBlock customBlock = ModChecks.getCustomBlock(block);
xp = customBlock.getXpGain();
int minimumDropAmount = customBlock.getMinimumDropAmount();
int maximumDropAmount = customBlock.getMaximumDropAmount();
Location location = block.getLocation();
ItemStack item = customBlock.getItemDrop();;
Misc.dropItems(location, item, minimumDropAmount);
if (minimumDropAmount < maximumDropAmount) {
Misc.randomDropItems(location, item, maximumDropAmount - minimumDropAmount);
}
}
else if (ModChecks.isCustomLeafBlock(block)) {
CustomBlock customBlock = ModChecks.getCustomBlock(block);
Misc.randomDropItem(block.getLocation(), customBlock.getItemDrop(), 10);
}
break;
}
block.setData((byte) 0);
block.setType(Material.AIR);
if (ModChecks.isCustomLogBlock(blockState)) {
Woodcutting.checkForDoubleDrop(player, blockState);
CustomBlock customBlock = ModChecks.getCustomBlock(blockState);
xp = customBlock.getXpGain();
int minimumDropAmount = customBlock.getMinimumDropAmount();
int maximumDropAmount = customBlock.getMaximumDropAmount();
Location location = blockState.getLocation();
ItemStack item = customBlock.getItemDrop();;
Misc.dropItems(location, item, minimumDropAmount);
if (minimumDropAmount < maximumDropAmount) {
Misc.randomDropItems(location, item, maximumDropAmount - minimumDropAmount);
}
}
else if (ModChecks.isCustomLeafBlock(blockState)) {
Misc.randomDropItem(blockState.getLocation(), ModChecks.getCustomBlock(blockState).getItemDrop(), 10);
}
Tree tree = (Tree) blockState.getData();
switch (material) {
case LOG:
Woodcutting.checkForDoubleDrop(player, blockState);
xp += Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.TREE_FELLER);
Misc.dropItem(blockState.getLocation(), new ItemStack(Material.LOG, 1, tree.getSpecies().getData()));
break;
case LEAVES:
Misc.randomDropItem(blockState.getLocation(), new ItemStack(Material.SAPLING, 1, tree.getSpecies().getData()), 10);
break;
default:
break;
}
blockState.setRawData((byte) 0x0);
blockState.setType(Material.AIR);
blockState.update();
}
mcMMOPlayer.beginXpGain(SkillType.WOODCUTTING, xp);
Users.getPlayer(player).beginXpGain(SkillType.WOODCUTTING, xp);
}
}

View File

@ -1,29 +1,27 @@
package com.gmail.nossr50.skills.woodcutting;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.TreeSpecies;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Tree;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.McMMOPlayer;
import com.gmail.nossr50.events.fake.FakePlayerAnimationEvent;
import com.gmail.nossr50.mods.ModChecks;
import com.gmail.nossr50.mods.datatypes.CustomBlock;
import com.gmail.nossr50.skills.utilities.PerksUtils;
import com.gmail.nossr50.skills.utilities.SkillTools;
import com.gmail.nossr50.skills.utilities.SkillType;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.Users;
public final class Woodcutting {
static final AdvancedConfig ADVANCED_CONFIG = AdvancedConfig.getInstance();
static final Config CONFIG = Config.getInstance();
public static double doubleDropsMaxChance = AdvancedConfig.getInstance().getWoodcuttingDoubleDropChance();
public static int doubleDropsMaxLevel = AdvancedConfig.getInstance().getWoodcuttingDoubleDropMaxLevel();
protected enum ExperienceGainMethod {
DEFAULT,
@ -38,8 +36,8 @@ public final class Woodcutting {
* @param mcMMOPlayer Player using the ability
* @param block Block being broken
*/
public static void beginTreeFeller(McMMOPlayer mcMMOPlayer, Block block) {
TreeFeller.process(mcMMOPlayer, block);
public static void beginTreeFeller(BlockState blockState, Player player) {
TreeFeller.process(blockState, player);
}
/**
@ -48,10 +46,9 @@ public final class Woodcutting {
* @param player Player using the ability
* @param block Block being broken
*/
public static void beginLeafBlower(Player player, Block block) {
public static void beginLeafBlower(Player player, BlockState blockState) {
mcMMO.p.getServer().getPluginManager().callEvent(new FakePlayerAnimationEvent(player));
player.playSound(block.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.POP_PITCH);
player.playSound(blockState.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.POP_PITCH);
}
/**
@ -60,75 +57,61 @@ public final class Woodcutting {
* @param mcMMOPlayer Player breaking the block
* @param block Block being broken
*/
public static void beginWoodcutting(McMMOPlayer mcMMOPlayer, Block block) {
int xp = 0;
if (Config.getInstance().getBlockModsEnabled() && ModChecks.isCustomLogBlock(block)) {
xp = ModChecks.getCustomBlock(block).getXpGain();
}
else {
try {
xp = getExperienceFromLog(block, ExperienceGainMethod.DEFAULT);
}
catch (IllegalArgumentException exception) {
return;
}
}
Player player = mcMMOPlayer.getPlayer();
public static void beginWoodcutting(Player player, BlockState blockState) {
int xp = getExperienceFromLog(blockState, ExperienceGainMethod.DEFAULT);
if (Permissions.doubleDrops(player, SkillType.WOODCUTTING)) {
checkForDoubleDrop(mcMMOPlayer, block);
checkForDoubleDrop(player, blockState);
}
mcMMOPlayer.beginXpGain(SkillType.WOODCUTTING, xp);
Users.getPlayer(player).beginXpGain(SkillType.WOODCUTTING, xp);
}
/**
* Retrieves the experience reward from a log
*
* @param log Log being broken
* @param blockState Log being broken
* @param experienceGainMethod How the log is being broken
* @return Amount of experience
* @throws IllegalArgumentException if 'log' is invalid
*/
protected static int getExperienceFromLog(Block log, ExperienceGainMethod experienceGainMethod) {
protected static int getExperienceFromLog(BlockState blockState, ExperienceGainMethod experienceGainMethod) {
// Mushrooms aren't trees so we could never get species data from them
switch (log.getType()) {
switch (blockState.getType()) {
case HUGE_MUSHROOM_1:
return Config.getInstance().getWoodcuttingXPHugeBrownMushroom();
case HUGE_MUSHROOM_2:
return Config.getInstance().getWoodcuttingXPHugeRedMushroom();
default:
break;
}
TreeSpecies logType = TreeSpecies.getByData(extractLogItemData(log.getData()));
// Apparently species can be null in certain cases (custom server mods?)
// https://github.com/mcMMO-Dev/mcMMO/issues/229
if (logType == null) {
throw new IllegalArgumentException();
if (ModChecks.isCustomLogBlock(blockState)) {
return ModChecks.getCustomBlock(blockState).getXpGain();
}
switch (logType) {
switch (((Tree) blockState.getData()).getSpecies()) {
case GENERIC:
return Config.getInstance().getWoodcuttingXPOak();
case REDWOOD:
return Config.getInstance().getWoodcuttingXPSpruce();
case BIRCH:
return Config.getInstance().getWoodcuttingXPBirch();
case JUNGLE:
int xp = Config.getInstance().getWoodcuttingXPJungle();
switch (experienceGainMethod) {
case TREE_FELLER:
return (int) (xp * 0.5);
default:
return xp;
if (experienceGainMethod == ExperienceGainMethod.TREE_FELLER) {
xp *= 0.5;
}
return xp;
default:
throw new IllegalArgumentException();
return 0;
}
}
@ -136,28 +119,18 @@ public final class Woodcutting {
* Checks for double drops
*
* @param mcMMOPlayer Player breaking the block
* @param block Block being broken
* @param blockState Block being broken
*/
protected static void checkForDoubleDrop(McMMOPlayer mcMMOPlayer, Block block) {
Player player = mcMMOPlayer.getPlayer();
double configDoubleDropChance = ADVANCED_CONFIG.getWoodcuttingDoubleDropChance();
int configDoubleDropMaxLevel = ADVANCED_CONFIG.getWoodcuttingDoubleDropMaxLevel();
int probability = (int) ((configDoubleDropChance / configDoubleDropMaxLevel) * Users.getPlayer(player).getProfile().getSkillLevel(SkillType.WOODCUTTING));
int activationChance = PerksUtils.handleLuckyPerks(player, SkillType.WOODCUTTING);
if (probability > configDoubleDropChance) {
probability = (int) configDoubleDropChance;
}
if (probability <= Misc.getRandom().nextInt(activationChance)) {
protected static void checkForDoubleDrop(Player player, BlockState blockState) {
if (!SkillTools.activationSuccessful(player, SkillType.WOODCUTTING, doubleDropsMaxChance, doubleDropsMaxLevel)) {
return;
}
if (Config.getInstance().getBlockModsEnabled() && ModChecks.isCustomLogBlock(block)) {
CustomBlock customBlock = ModChecks.getCustomBlock(block);
if (ModChecks.isCustomLogBlock(blockState)) {
CustomBlock customBlock = ModChecks.getCustomBlock(blockState);
int minimumDropAmount = customBlock.getMinimumDropAmount();
int maximumDropAmount = customBlock.getMaximumDropAmount();
Location location = block.getLocation();
Location location = blockState.getLocation();
ItemStack item = customBlock.getItemDrop();
Misc.dropItems(location, item, minimumDropAmount);
@ -167,44 +140,37 @@ public final class Woodcutting {
}
}
else {
byte itemData = extractLogItemData(block.getData());
Location location = block.getLocation();
ItemStack item = new ItemStack(Material.LOG, 1, itemData);
Location location = blockState.getLocation();
ItemStack item = blockState.getData().toItemStack();
switch (TreeSpecies.getByData(itemData)) {
switch (((Tree) blockState.getData()).getSpecies()) {
case GENERIC:
if (Config.getInstance().getOakDoubleDropsEnabled()) {
Misc.dropItem(location, item);
}
break;
return;
case REDWOOD:
if (Config.getInstance().getSpruceDoubleDropsEnabled()) {
Misc.dropItem(location, item);
}
break;
return;
case BIRCH:
if (Config.getInstance().getBirchDoubleDropsEnabled()) {
Misc.dropItem(location, item);
}
break;
return;
case JUNGLE:
if (Config.getInstance().getJungleDoubleDropsEnabled()) {
Misc.dropItem(location, item);
}
break;
return;
default:
break;
return;
}
}
}
/**
* Extracts the log type from the block data (i.e. removes rotation)
*
* @param data Original block data
* @return Extracted log type
*/
protected static byte extractLogItemData(byte data) {
return (byte) (data & 0x3);
}
}

View File

@ -29,8 +29,7 @@ public class WoodcuttingCommand extends SkillCommand {
treeFellerLengthEndurance = treeFellerStrings[1];
//DOUBLE DROPS
AdvancedConfig advancedConfig = AdvancedConfig.getInstance();
String[] doubleDropStrings = calculateAbilityDisplayValues(advancedConfig.getWoodcuttingDoubleDropMaxLevel(), advancedConfig.getWoodcuttingDoubleDropChance());
String[] doubleDropStrings = calculateAbilityDisplayValues(Woodcutting.doubleDropsMaxLevel, Woodcutting.doubleDropsMaxChance);
doubleDropChance = doubleDropStrings[0];
doubleDropChanceLucky = doubleDropStrings[1];
}