Expanding McMMOItemSpawnEvent & Fixing a bug with Tree Feller drops

This commit is contained in:
nossr50 2020-11-02 13:51:43 -08:00
parent 9529bbf898
commit 65fba3e20e
18 changed files with 318 additions and 284 deletions

View File

@ -1,3 +1,14 @@
Version 2.1.152
Updated hu_HU locale (thanks andris)
Fixed a bug where Tree Feller would sometimes double drop blocks inappropriately
Added some code to prevent a possible NPE when spawning items in a world that got unloaded
(API) New ENUM ItemSpawnReason which gives context for why mcMMO is dropping an item
(API) McMMOItemSpawnEvent::getItemSpawnReason() was added
(API) Many instances of spawning items that didn't used to create and call an McMMOItemSpawnEvent now do
NOTES:
I really should stop letting my OCD compel me to rewrite code all the time.
Version 2.1.151 Version 2.1.151
Added new config for chat options named 'chat.yml' Added new config for chat options named 'chat.yml'
Added 'Chat.Channels.Party.Spies.Automatically_Enable_Spying' to chat.yml which when enabled will start users who have the chat spy permission in chat spying mode Added 'Chat.Channels.Party.Spies.Automatically_Enable_Spying' to chat.yml which when enabled will start users who have the chat spy permission in chat spying mode

View File

@ -0,0 +1,17 @@
package com.gmail.nossr50.api;
public enum ItemSpawnReason {
ARROW_RETRIEVAL_ACTIVATED, //Players sometimes can retrieve arrows instead of losing them when hitting a mob
EXCAVATION_TREASURE, //Any drops when excavation treasures activate fall under this
FISHING_EXTRA_FISH, //A config setting allows more fish to be found when fishing, the extra fish are part of this
FISHING_SHAKE_TREASURE, //When using a fishing rod on a mob and finding a treasure via Shake
HYLIAN_LUCK_TREASURE, //When finding a treasure in grass via hylian luck
BLAST_MINING_DEBRIS_NON_ORES, //The non-ore debris that are dropped from blast mining
BLAST_MINING_ORES, //The ore(s) which may include player placed ores being dropped from blast mining
BLAST_MINING_ORES_BONUS_DROP, //Any bonus ores that drop from a result of a players Mining skills
UNARMED_DISARMED_ITEM, //When you disarm an opponent and they drop their weapon
SALVAGE_ENCHANTMENT_BOOK, //When you salvage an enchanted item and get the enchantment back in book form
SALVAGE_MATERIALS, //When you salvage an item and get materials back
TREE_FELLER_DISPLACED_BLOCK,
BONUS_DROPS, //Can be from Mining, Woodcutting, Herbalism, etc
}

View File

@ -226,7 +226,7 @@ public enum SuperAbilityType {
return BlockUtils.affectedBySuperBreaker(blockState); return BlockUtils.affectedBySuperBreaker(blockState);
case TREE_FELLER: case TREE_FELLER:
return BlockUtils.isLog(blockState); return BlockUtils.hasWoodcuttingXP(blockState);
default: default:
return false; return false;

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.events.items; package com.gmail.nossr50.events.items;
import com.gmail.nossr50.api.ItemSpawnReason;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.Event; import org.bukkit.event.Event;
@ -14,38 +15,49 @@ public class McMMOItemSpawnEvent extends Event implements Cancellable {
private Location location; private Location location;
private ItemStack itemStack; private ItemStack itemStack;
private boolean cancelled; private boolean cancelled;
private final ItemSpawnReason itemSpawnReason;
public McMMOItemSpawnEvent(Location location, ItemStack itemStack) { public McMMOItemSpawnEvent(@NotNull Location location, @NotNull ItemStack itemStack, @NotNull ItemSpawnReason itemSpawnReason) {
this.location = location; this.location = location;
this.itemStack = itemStack; this.itemStack = itemStack;
this.itemSpawnReason = itemSpawnReason;
this.cancelled = false; this.cancelled = false;
} }
/**
* The reason an item is being spawned by mcMMO
* @see ItemSpawnReason
* @return the item drop reason
*/
public ItemSpawnReason getItemSpawnReason() {
return itemSpawnReason;
}
/** /**
* @return Location where the item will be dropped * @return Location where the item will be dropped
*/ */
public Location getLocation() { public @NotNull Location getLocation() {
return location; return location;
} }
/** /**
* @param location Location where to drop the item * @param location Location where to drop the item
*/ */
public void setLocation(Location location) { public void setLocation(@NotNull Location location) {
this.location = location; this.location = location;
} }
/** /**
* @return ItemStack that will be dropped * @return ItemStack that will be dropped
*/ */
public ItemStack getItemStack() { public @NotNull ItemStack getItemStack() {
return itemStack; return itemStack;
} }
/** /**
* @param itemStack ItemStack to drop * @param itemStack ItemStack to drop
*/ */
public void setItemStack(ItemStack itemStack) { public void setItemStack(@NotNull ItemStack itemStack) {
this.itemStack = itemStack; this.itemStack = itemStack;
} }
@ -61,14 +73,14 @@ public class McMMOItemSpawnEvent extends Event implements Cancellable {
} }
/** Rest of file is required boilerplate for custom events **/ /** Rest of file is required boilerplate for custom events **/
private static final HandlerList handlers = new HandlerList(); private static final @NotNull HandlerList handlers = new HandlerList();
@Override @Override
public @NotNull HandlerList getHandlers() { public @NotNull HandlerList getHandlers() {
return handlers; return handlers;
} }
public static HandlerList getHandlerList() { public static @NotNull HandlerList getHandlerList() {
return handlers; return handlers;
} }
} }

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.listeners; package com.gmail.nossr50.listeners;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.HiddenConfig; import com.gmail.nossr50.config.HiddenConfig;
import com.gmail.nossr50.config.WorldBlacklist; import com.gmail.nossr50.config.WorldBlacklist;
@ -19,10 +20,7 @@ import com.gmail.nossr50.skills.mining.MiningManager;
import com.gmail.nossr50.skills.repair.Repair; import com.gmail.nossr50.skills.repair.Repair;
import com.gmail.nossr50.skills.salvage.Salvage; import com.gmail.nossr50.skills.salvage.Salvage;
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager; import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
import com.gmail.nossr50.util.BlockUtils; import com.gmail.nossr50.util.*;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillUtils; import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.util.sounds.SoundManager; import com.gmail.nossr50.util.sounds.SoundManager;
@ -98,7 +96,7 @@ public class BlockListener implements Listener {
int bonusCount = bonusDropMeta.asInt(); int bonusCount = bonusDropMeta.asInt();
for (int i = 0; i < bonusCount; i++) { for (int i = 0; i < bonusCount; i++) {
event.getBlock().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is); Misc.spawnItemNaturally(event.getBlockState().getLocation(), is, ItemSpawnReason.BONUS_DROPS);
} }
} }
} }
@ -356,13 +354,17 @@ public class BlockListener implements Listener {
} }
/* WOOD CUTTING */ /* WOOD CUTTING */
else if (BlockUtils.isLog(blockState) && ItemUtils.isAxe(heldItem) && PrimarySkillType.WOODCUTTING.getPermissions(player) && !mcMMO.getPlaceStore().isTrue(blockState)) { else if (BlockUtils.hasWoodcuttingXP(blockState) && ItemUtils.isAxe(heldItem) && PrimarySkillType.WOODCUTTING.getPermissions(player) && !mcMMO.getPlaceStore().isTrue(blockState)) {
WoodcuttingManager woodcuttingManager = mcMMOPlayer.getWoodcuttingManager(); WoodcuttingManager woodcuttingManager = mcMMOPlayer.getWoodcuttingManager();
if (woodcuttingManager.canUseTreeFeller(heldItem)) { if (woodcuttingManager.canUseTreeFeller(heldItem)) {
woodcuttingManager.processTreeFeller(blockState); woodcuttingManager.processTreeFeller(blockState);
} }
else { else {
woodcuttingManager.woodcuttingBlockCheck(blockState); //Check for XP
woodcuttingManager.processWoodcuttingBlockXP(blockState);
//Check for bonus drops
woodcuttingManager.processHarvestLumber(blockState);
} }
} }
@ -491,7 +493,7 @@ public class BlockListener implements Listener {
if (mcMMOPlayer.getToolPreparationMode(ToolType.HOE) && ItemUtils.isHoe(heldItem) && (BlockUtils.affectedByGreenTerra(blockState) || BlockUtils.canMakeMossy(blockState)) && Permissions.greenTerra(player)) { if (mcMMOPlayer.getToolPreparationMode(ToolType.HOE) && ItemUtils.isHoe(heldItem) && (BlockUtils.affectedByGreenTerra(blockState) || BlockUtils.canMakeMossy(blockState)) && Permissions.greenTerra(player)) {
mcMMOPlayer.checkAbilityActivation(PrimarySkillType.HERBALISM); mcMMOPlayer.checkAbilityActivation(PrimarySkillType.HERBALISM);
} }
else if (mcMMOPlayer.getToolPreparationMode(ToolType.AXE) && ItemUtils.isAxe(heldItem) && BlockUtils.isLog(blockState) && Permissions.treeFeller(player)) { else if (mcMMOPlayer.getToolPreparationMode(ToolType.AXE) && ItemUtils.isAxe(heldItem) && BlockUtils.hasWoodcuttingXP(blockState) && Permissions.treeFeller(player)) {
mcMMOPlayer.checkAbilityActivation(PrimarySkillType.WOODCUTTING); mcMMOPlayer.checkAbilityActivation(PrimarySkillType.WOODCUTTING);
} }
else if (mcMMOPlayer.getToolPreparationMode(ToolType.PICKAXE) && ItemUtils.isPickaxe(heldItem) && BlockUtils.affectedBySuperBreaker(blockState) && Permissions.superBreaker(player)) { else if (mcMMOPlayer.getToolPreparationMode(ToolType.PICKAXE) && ItemUtils.isPickaxe(heldItem) && BlockUtils.affectedBySuperBreaker(blockState) && Permissions.superBreaker(player)) {
@ -525,7 +527,7 @@ public class BlockListener implements Listener {
* *
* We don't need to check permissions here because they've already been checked for the ability to even activate. * We don't need to check permissions here because they've already been checked for the ability to even activate.
*/ */
if (mcMMOPlayer.getAbilityMode(SuperAbilityType.TREE_FELLER) && BlockUtils.isLog(blockState) && Config.getInstance().getTreeFellerSoundsEnabled()) { if (mcMMOPlayer.getAbilityMode(SuperAbilityType.TREE_FELLER) && BlockUtils.hasWoodcuttingXP(blockState) && Config.getInstance().getTreeFellerSoundsEnabled()) {
SoundManager.sendSound(player, blockState.getLocation(), SoundType.FIZZ); SoundManager.sendSound(player, blockState.getLocation(), SoundType.FIZZ);
} }
} }
@ -596,7 +598,7 @@ public class BlockListener implements Listener {
} }
} }
} }
else if (mcMMOPlayer.getWoodcuttingManager().canUseLeafBlower(heldItem) && BlockUtils.isLeaves(blockState) && EventUtils.simulateBlockBreak(block, player, true)) { else if (mcMMOPlayer.getWoodcuttingManager().canUseLeafBlower(heldItem) && BlockUtils.isNonWoodPartOfTree(blockState) && EventUtils.simulateBlockBreak(block, player, true)) {
event.setInstaBreak(true); event.setInstaBreak(true);
SoundManager.sendSound(player, block.getLocation(), SoundType.POP); SoundManager.sendSound(player, block.getLocation(), SoundType.POP);
} }

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.archery; package com.gmail.nossr50.skills.archery;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType;
@ -9,6 +10,7 @@ import org.bukkit.Material;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
@ -50,12 +52,12 @@ public class Archery {
* *
* @param livingEntity The entity hit by the arrows * @param livingEntity The entity hit by the arrows
*/ */
public static void arrowRetrievalCheck(LivingEntity livingEntity) { public static void arrowRetrievalCheck(@NotNull LivingEntity livingEntity) {
for (Iterator<TrackedEntity> entityIterator = trackedEntities.iterator(); entityIterator.hasNext();) { for (Iterator<TrackedEntity> entityIterator = trackedEntities.iterator(); entityIterator.hasNext();) {
TrackedEntity trackedEntity = entityIterator.next(); TrackedEntity trackedEntity = entityIterator.next();
if (trackedEntity.getID() == livingEntity.getUniqueId()) { if (trackedEntity.getID() == livingEntity.getUniqueId()) {
Misc.dropItems(livingEntity.getLocation(), new ItemStack(Material.ARROW), trackedEntity.getArrowCount()); Misc.spawnItems(livingEntity.getLocation(), new ItemStack(Material.ARROW), trackedEntity.getArrowCount(), ItemSpawnReason.ARROW_RETRIEVAL_ACTIVATED);
entityIterator.remove(); entityIterator.remove();
return; return;
} }

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.excavation; package com.gmail.nossr50.skills.excavation;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.experience.XPGainReason; import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@ -51,7 +52,7 @@ public class ExcavationManager extends SkillManager {
} }
xp += treasure.getXp(); xp += treasure.getXp();
Misc.dropItem(location, treasure.getDrop()); Misc.spawnItem(location, treasure.getDrop(), ItemSpawnReason.EXCAVATION_TREASURE);
} }
} }
} }

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.fishing; package com.gmail.nossr50.skills.fishing;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.experience.ExperienceConfig;
@ -318,7 +319,7 @@ public class FishingManager extends SkillManager {
} }
if (Config.getInstance().getFishingExtraFish()) { if (Config.getInstance().getFishingExtraFish()) {
Misc.dropItem(player.getEyeLocation(), fishingCatch.getItemStack()); Misc.spawnItem(player.getEyeLocation(), fishingCatch.getItemStack(), ItemSpawnReason.FISHING_EXTRA_FISH);
} }
fishingCatch.setItemStack(treasureDrop); fishingCatch.setItemStack(treasureDrop);
@ -426,7 +427,7 @@ public class FishingManager extends SkillManager {
return; return;
} }
Misc.dropItem(target.getLocation(), drop); Misc.spawnItem(target.getLocation(), drop, ItemSpawnReason.FISHING_SHAKE_TREASURE);
CombatUtils.dealDamage(target, Math.min(Math.max(target.getMaxHealth() / 4, 1), 10), EntityDamageEvent.DamageCause.CUSTOM, getPlayer()); // Make it so you can shake a mob no more than 4 times. CombatUtils.dealDamage(target, Math.min(Math.max(target.getMaxHealth() / 4, 1), 10), EntityDamageEvent.DamageCause.CUSTOM, getPlayer()); // Make it so you can shake a mob no more than 4 times.
applyXpGain(ExperienceConfig.getInstance().getFishingShakeXP(), XPGainReason.PVE); applyXpGain(ExperienceConfig.getInstance().getFishingShakeXP(), XPGainReason.PVE);
} }

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.herbalism; package com.gmail.nossr50.skills.herbalism;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.config.treasure.TreasureConfig; import com.gmail.nossr50.config.treasure.TreasureConfig;
@ -626,7 +627,7 @@ public class HerbalismManager extends SkillManager {
return false; return false;
} }
blockState.setType(Material.AIR); blockState.setType(Material.AIR);
Misc.dropItem(location, treasure.getDrop()); Misc.spawnItem(location, treasure.getDrop(), ItemSpawnReason.HYLIAN_LUCK_TREASURE);
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Herbalism.HylianLuck"); NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Herbalism.HylianLuck");
return true; return true;
} }

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.mining; package com.gmail.nossr50.skills.mining;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.experience.ExperienceConfig;
@ -188,7 +189,7 @@ public class MiningManager extends SkillManager {
//Drop "debris" based on skill modifiers //Drop "debris" based on skill modifiers
for(BlockState blockState : notOres) { for(BlockState blockState : notOres) {
if(RandomUtils.nextFloat() < debrisYield) { if(RandomUtils.nextFloat() < debrisYield) {
Misc.dropItem(Misc.getBlockCenter(blockState), new ItemStack(blockState.getType())); // Initial block that would have been dropped Misc.spawnItem(Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_DEBRIS_NON_ORES); // Initial block that would have been dropped
} }
} }
@ -196,12 +197,12 @@ public class MiningManager extends SkillManager {
if (RandomUtils.nextFloat() < (yield + oreBonus)) { if (RandomUtils.nextFloat() < (yield + oreBonus)) {
xp += Mining.getBlockXp(blockState); xp += Mining.getBlockXp(blockState);
Misc.dropItem(Misc.getBlockCenter(blockState), new ItemStack(blockState.getType())); // Initial block that would have been dropped 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)) { if (!mcMMO.getPlaceStore().isTrue(blockState)) {
for (int i = 1; i < dropMultiplier; i++) { for (int i = 1; i < dropMultiplier; i++) {
// Bukkit.broadcastMessage("Bonus Drop on Ore: "+blockState.getType().toString()); // Bukkit.broadcastMessage("Bonus Drop on Ore: "+blockState.getType().toString());
Misc.dropItem(Misc.getBlockCenter(blockState), new ItemStack(blockState.getType())); // Initial block that would have been dropped Misc.spawnItem(Misc.getBlockCenter(blockState), new ItemStack(blockState.getType()), ItemSpawnReason.BLAST_MINING_ORES_BONUS_DROP); // Initial block that would have been dropped
} }
} }
} }

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.salvage; package com.gmail.nossr50.skills.salvage;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.experience.ExperienceConfig;
@ -159,10 +160,10 @@ public class SalvageManager extends SkillManager {
anvilLoc.add(0, .1, 0); anvilLoc.add(0, .1, 0);
if (enchantBook != null) { if (enchantBook != null) {
Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), enchantBook, vectorSpeed); Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), enchantBook, vectorSpeed, ItemSpawnReason.SALVAGE_ENCHANTMENT_BOOK);
} }
Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), salvageResults, vectorSpeed); Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), salvageResults, vectorSpeed, ItemSpawnReason.SALVAGE_MATERIALS);
// BWONG BWONG BWONG - CLUNK! // BWONG BWONG BWONG - CLUNK!
if (Config.getInstance().getSalvageAnvilUseSoundsEnabled()) { if (Config.getInstance().getSalvageAnvilUseSoundsEnabled()) {

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.unarmed; package com.gmail.nossr50.skills.unarmed;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType; import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@ -109,7 +110,7 @@ public class UnarmedManager extends SkillManager {
if(UserManager.getPlayer(defender) == null) if(UserManager.getPlayer(defender) == null)
return; return;
Item item = Misc.dropItem(defender.getLocation(), defender.getInventory().getItemInMainHand()); Item item = Misc.spawnItem(defender.getLocation(), defender.getInventory().getItemInMainHand(), ItemSpawnReason.UNARMED_DISARMED_ITEM);
if (item != null && AdvancedConfig.getInstance().getDisarmProtected()) { if (item != null && AdvancedConfig.getInstance().getDisarmProtected()) {
item.setMetadata(mcMMO.disarmedItemKey, UserManager.getPlayer(defender).getPlayerMetadata()); item.setMetadata(mcMMO.disarmedItemKey, UserManager.getPlayer(defender).getPlayerMetadata());

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.woodcutting; package com.gmail.nossr50.skills.woodcutting;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.experience.XPGainReason; import com.gmail.nossr50.datatypes.experience.XPGainReason;
@ -27,6 +28,7 @@ import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -65,10 +67,11 @@ public class WoodcuttingManager extends SkillManager {
&& ItemUtils.isAxe(heldItem); && ItemUtils.isAxe(heldItem);
} }
private boolean canGetDoubleDrops() { private boolean checkHarvestLumberActivation(@NotNull Material material) {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER) return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RankUtils.hasReachedRank(1, getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER) && RankUtils.hasReachedRank(1, getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.WOODCUTTING_HARVEST_LUMBER, getPlayer()); && RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.WOODCUTTING_HARVEST_LUMBER, getPlayer())
&& Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, material);
} }
/** /**
@ -76,20 +79,14 @@ public class WoodcuttingManager extends SkillManager {
* *
* @param blockState Block being broken * @param blockState Block being broken
*/ */
public void woodcuttingBlockCheck(BlockState blockState) { public void processHarvestLumber(@NotNull BlockState blockState) {
if (checkHarvestLumberActivation(blockState.getType())) {
spawnHarvestLumberBonusDrops(blockState);
}
}
public void processWoodcuttingBlockXP(@NotNull BlockState blockState) {
int xp = getExperienceFromLog(blockState); int xp = getExperienceFromLog(blockState);
switch (blockState.getType()) {
case BROWN_MUSHROOM_BLOCK:
case RED_MUSHROOM_BLOCK:
break;
default:
if (canGetDoubleDrops()) {
checkForDoubleDrop(blockState);
}
}
applyXpGain(xp, XPGainReason.PVE); applyXpGain(xp, XPGainReason.PVE);
} }
@ -206,7 +203,7 @@ public class WoodcuttingManager extends SkillManager {
* @param player the player holding the item * @param player the player holding the item
* @return True if the tool can sustain the durability loss * @return True if the tool can sustain the durability loss
*/ */
private static boolean handleDurabilityLoss(Set<BlockState> treeFellerBlocks, ItemStack inHand, Player player) { private static boolean handleDurabilityLoss(@NotNull Set<BlockState> treeFellerBlocks, @NotNull ItemStack inHand, @NotNull Player player) {
//Treat the NBT tag for unbreakable and the durability enchant differently //Treat the NBT tag for unbreakable and the durability enchant differently
ItemMeta meta = inHand.getItemMeta(); ItemMeta meta = inHand.getItemMeta();
@ -218,7 +215,7 @@ public class WoodcuttingManager extends SkillManager {
Material type = inHand.getType(); Material type = inHand.getType();
for (BlockState blockState : treeFellerBlocks) { for (BlockState blockState : treeFellerBlocks) {
if (BlockUtils.isLog(blockState)) { if (BlockUtils.hasWoodcuttingXP(blockState)) {
durabilityLoss += Config.getInstance().getAbilityToolDamage(); durabilityLoss += Config.getInstance().getAbilityToolDamage();
} }
} }
@ -249,7 +246,7 @@ public class WoodcuttingManager extends SkillManager {
* @return true if and only if the given blockState was a Log not already * @return true if and only if the given blockState was a Log not already
* in treeFellerBlocks. * in treeFellerBlocks.
*/ */
private boolean processTreeFellerTargetBlock(BlockState blockState, List<BlockState> futureCenterBlocks, Set<BlockState> treeFellerBlocks) { private boolean processTreeFellerTargetBlock(@NotNull BlockState blockState, @NotNull List<BlockState> futureCenterBlocks, @NotNull Set<BlockState> treeFellerBlocks) {
if (treeFellerBlocks.contains(blockState) || mcMMO.getPlaceStore().isTrue(blockState)) { if (treeFellerBlocks.contains(blockState) || mcMMO.getPlaceStore().isTrue(blockState)) {
return false; return false;
} }
@ -259,12 +256,12 @@ public class WoodcuttingManager extends SkillManager {
treeFellerReachedThreshold = true; treeFellerReachedThreshold = true;
} }
if (BlockUtils.isLog(blockState)) { if (BlockUtils.hasWoodcuttingXP(blockState)) {
treeFellerBlocks.add(blockState); treeFellerBlocks.add(blockState);
futureCenterBlocks.add(blockState); futureCenterBlocks.add(blockState);
return true; return true;
} }
else if (BlockUtils.isLeaves(blockState)) { else if (BlockUtils.isNonWoodPartOfTree(blockState)) {
treeFellerBlocks.add(blockState); treeFellerBlocks.add(blockState);
return false; return false;
} }
@ -276,7 +273,7 @@ public class WoodcuttingManager extends SkillManager {
* *
* @param treeFellerBlocks List of blocks to be dropped * @param treeFellerBlocks List of blocks to be dropped
*/ */
private void dropTreeFellerLootFromBlocks(Set<BlockState> treeFellerBlocks) { private void dropTreeFellerLootFromBlocks(@NotNull Set<BlockState> treeFellerBlocks) {
Player player = getPlayer(); Player player = getPlayer();
int xp = 0; int xp = 0;
int processedLogCount = 0; int processedLogCount = 0;
@ -289,25 +286,22 @@ public class WoodcuttingManager extends SkillManager {
break; // TODO: Shouldn't we use continue instead? break; // TODO: Shouldn't we use continue instead?
} }
Material material = blockState.getType(); /*
* Handle Drops & XP
*/
//TODO: Update this to drop the correct items/blocks via NMS if (BlockUtils.hasWoodcuttingXP(blockState)) {
if (material == Material.BROWN_MUSHROOM_BLOCK || material == Material.RED_MUSHROOM_BLOCK) { //Add XP
xp += processTreeFellerXPGains(blockState, processedLogCount); xp += processTreeFellerXPGains(blockState, processedLogCount);
Misc.dropItems(Misc.getBlockCenter(blockState), block.getDrops());
} else if (mcMMO.getModManager().isCustomLeaf(blockState)) { //Drop displaced block
Misc.dropItems(Misc.getBlockCenter(blockState), block.getDrops()); Misc.spawnItemsFromCollection(Misc.getBlockCenter(blockState), block.getDrops(), ItemSpawnReason.TREE_FELLER_DISPLACED_BLOCK);
} else {
if (BlockUtils.isLog(blockState)) { //Bonus Drops / Harvest lumber checks
if (canGetDoubleDrops()) { processHarvestLumber(blockState);
checkForDoubleDrop(blockState); } else if (BlockUtils.isNonWoodPartOfTree(blockState)) {
} //Drop displaced non-woodcutting XP blocks
xp += processTreeFellerXPGains(blockState, processedLogCount); Misc.spawnItemsFromCollection(Misc.getBlockCenter(blockState), block.getDrops(), ItemSpawnReason.TREE_FELLER_DISPLACED_BLOCK, 1);
Misc.dropItems(Misc.getBlockCenter(blockState), block.getDrops());
}
if (BlockUtils.isLeaves(blockState)) {
Misc.dropItems(Misc.getBlockCenter(blockState), block.getDrops());
}
} }
blockState.setType(Material.AIR); blockState.setType(Material.AIR);
@ -367,13 +361,11 @@ public class WoodcuttingManager extends SkillManager {
} }
/** /**
* Checks for double drops * Spawns harvest lumber bonus drops
* *
* @param blockState Block being broken * @param blockState Block being broken
*/ */
protected static void checkForDoubleDrop(BlockState blockState) { protected static void spawnHarvestLumberBonusDrops(@NotNull BlockState blockState) {
if (Config.getInstance().getWoodcuttingDoubleDropsEnabled(blockState.getBlockData())) { Misc.spawnItemsFromCollection(Misc.getBlockCenter(blockState), blockState.getBlock().getDrops(), ItemSpawnReason.BONUS_DROPS);
Misc.dropItems(Misc.getBlockCenter(blockState), blockState.getBlock().getDrops());
}
} }
} }

View File

@ -66,7 +66,7 @@ public final class BlockUtils {
* @return true if the block awards XP, false otherwise * @return true if the block awards XP, false otherwise
*/ */
public static boolean shouldBeWatched(BlockState blockState) { public static boolean shouldBeWatched(BlockState blockState) {
return affectedByGigaDrillBreaker(blockState) || affectedByGreenTerra(blockState) || affectedBySuperBreaker(blockState) || isLog(blockState) return affectedByGigaDrillBreaker(blockState) || affectedByGreenTerra(blockState) || affectedBySuperBreaker(blockState) || hasWoodcuttingXP(blockState)
|| Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.MINING, blockState.getType()) || Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.MINING, blockState.getType())
|| Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.EXCAVATION, blockState.getType()) || Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.EXCAVATION, blockState.getType())
|| Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, blockState.getType()) || Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, blockState.getType())
@ -165,10 +165,8 @@ public final class BlockUtils {
* @param blockState The {@link BlockState} of the block to check * @param blockState The {@link BlockState} of the block to check
* @return true if the block is a log, false otherwise * @return true if the block is a log, false otherwise
*/ */
public static boolean isLog(BlockState blockState) { public static boolean hasWoodcuttingXP(BlockState blockState) {
if (ExperienceConfig.getInstance().doesBlockGiveSkillXP(PrimarySkillType.WOODCUTTING, blockState.getBlockData())) return ExperienceConfig.getInstance().doesBlockGiveSkillXP(PrimarySkillType.WOODCUTTING, blockState.getBlockData());
return true;
return mcMMO.getModManager().isCustomLog(blockState);
} }
/** /**
@ -177,8 +175,8 @@ public final class BlockUtils {
* @param blockState The {@link BlockState} of the block to check * @param blockState The {@link BlockState} of the block to check
* @return true if the block is a leaf, false otherwise * @return true if the block is a leaf, false otherwise
*/ */
public static boolean isLeaves(BlockState blockState) { public static boolean isNonWoodPartOfTree(BlockState blockState) {
return mcMMO.getMaterialMapStore().isLeavesWhiteListed(blockState.getType()); return mcMMO.getMaterialMapStore().isTreeFellerDestructible(blockState.getType());
} }
/** /**

View File

@ -46,6 +46,7 @@ import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -73,7 +74,7 @@ public final class EventUtils {
* @param event The {@link Event} in question * @param event The {@link Event} in question
* @return Whether this {@link Event} has been faked by mcMMO and should not be processed normally. * @return Whether this {@link Event} has been faked by mcMMO and should not be processed normally.
*/ */
public static boolean isFakeEvent(Event event) { public static boolean isFakeEvent(@NotNull Event event) {
return event instanceof FakeEvent; return event instanceof FakeEvent;
} }
@ -84,7 +85,7 @@ public final class EventUtils {
* @param event this event * @param event this event
* @return true if damage is NOT from an unnatural mcMMO skill (such as bleed DOTs) * @return true if damage is NOT from an unnatural mcMMO skill (such as bleed DOTs)
*/ */
public static boolean isDamageFromMcMMOComplexBehaviour(Event event) { public static boolean isDamageFromMcMMOComplexBehaviour(@NotNull Event event) {
return event instanceof FakeEntityDamageEvent; return event instanceof FakeEntityDamageEvent;
} }
@ -94,7 +95,7 @@ public final class EventUtils {
* @param entity target entity * @param entity target entity
* @return the associated McMMOPlayer for this entity * @return the associated McMMOPlayer for this entity
*/ */
public static McMMOPlayer getMcMMOPlayer(Entity entity) public static McMMOPlayer getMcMMOPlayer(@NotNull Entity entity)
{ {
return UserManager.getPlayer((Player)entity); return UserManager.getPlayer((Player)entity);
} }
@ -112,7 +113,7 @@ public final class EventUtils {
* @param entityDamageEvent * @param entityDamageEvent
* @return * @return
*/ */
public static boolean isRealPlayerDamaged(EntityDamageEvent entityDamageEvent) public static boolean isRealPlayerDamaged(@NotNull EntityDamageEvent entityDamageEvent)
{ {
//Make sure the damage is above 0 //Make sure the damage is above 0
double damage = entityDamageEvent.getFinalDamage(); double damage = entityDamageEvent.getFinalDamage();
@ -167,14 +168,14 @@ public final class EventUtils {
* Others * Others
*/ */
public static McMMOPlayerAbilityActivateEvent callPlayerAbilityActivateEvent(Player player, PrimarySkillType skill) { public static @NotNull McMMOPlayerAbilityActivateEvent callPlayerAbilityActivateEvent(@NotNull Player player, @NotNull PrimarySkillType skill) {
McMMOPlayerAbilityActivateEvent event = new McMMOPlayerAbilityActivateEvent(player, skill); McMMOPlayerAbilityActivateEvent event = new McMMOPlayerAbilityActivateEvent(player, skill);
mcMMO.p.getServer().getPluginManager().callEvent(event); mcMMO.p.getServer().getPluginManager().callEvent(event);
return event; return event;
} }
public static McMMOPlayerProfileLoadEvent callPlayerProfileLoadEvent(Player player, PlayerProfile profile){ public static @NotNull McMMOPlayerProfileLoadEvent callPlayerProfileLoadEvent(@NotNull Player player, @NotNull PlayerProfile profile){
McMMOPlayerProfileLoadEvent event = new McMMOPlayerProfileLoadEvent(player, profile); McMMOPlayerProfileLoadEvent event = new McMMOPlayerProfileLoadEvent(player, profile);
mcMMO.p.getServer().getPluginManager().callEvent(event); mcMMO.p.getServer().getPluginManager().callEvent(event);

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.util; package com.gmail.nossr50.util;
import org.bukkit.Material; import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -15,46 +16,46 @@ import java.util.Locale;
*/ */
public class MaterialMapStore { public class MaterialMapStore {
private final HashSet<String> abilityBlackList; private final @NotNull HashSet<String> abilityBlackList;
private final HashSet<String> toolBlackList; private final @NotNull HashSet<String> toolBlackList;
private final HashSet<String> mossyWhiteList; private final @NotNull HashSet<String> mossyWhiteList;
private final HashSet<String> leavesWhiteList; private final @NotNull HashSet<String> treeFellerDestructibleWhiteList;
private final HashSet<String> herbalismAbilityBlackList; private final @NotNull HashSet<String> herbalismAbilityBlackList;
private final HashSet<String> blockCrackerWhiteList; private final @NotNull HashSet<String> blockCrackerWhiteList;
private final HashSet<String> canMakeShroomyWhiteList; private final @NotNull HashSet<String> canMakeShroomyWhiteList;
private final HashSet<String> multiBlockPlant; private final @NotNull HashSet<String> multiBlockPlant;
private final HashSet<String> foodItemWhiteList; private final @NotNull HashSet<String> foodItemWhiteList;
private final HashSet<String> glassBlocks; private final @NotNull HashSet<String> glassBlocks;
private final HashSet<String> netheriteArmor; private final @NotNull HashSet<String> netheriteArmor;
private final HashSet<String> netheriteTools; private final @NotNull HashSet<String> netheriteTools;
private final HashSet<String> woodTools; private final @NotNull HashSet<String> woodTools;
private final HashSet<String> stoneTools; private final @NotNull HashSet<String> stoneTools;
private final HashSet<String> leatherArmor; private final @NotNull HashSet<String> leatherArmor;
private final HashSet<String> ironArmor; private final @NotNull HashSet<String> ironArmor;
private final HashSet<String> ironTools; private final @NotNull HashSet<String> ironTools;
private final HashSet<String> stringTools; private final @NotNull HashSet<String> stringTools;
private final HashSet<String> goldArmor; private final @NotNull HashSet<String> goldArmor;
private final HashSet<String> goldTools; private final @NotNull HashSet<String> goldTools;
private final HashSet<String> chainmailArmor; private final @NotNull HashSet<String> chainmailArmor;
private final HashSet<String> diamondArmor; private final @NotNull HashSet<String> diamondArmor;
private final HashSet<String> diamondTools; private final @NotNull HashSet<String> diamondTools;
private final HashSet<String> armors; private final @NotNull HashSet<String> armors;
private final HashSet<String> swords; private final @NotNull HashSet<String> swords;
private final HashSet<String> axes; private final @NotNull HashSet<String> axes;
private final HashSet<String> hoes; private final @NotNull HashSet<String> hoes;
private final HashSet<String> shovels; private final @NotNull HashSet<String> shovels;
private final HashSet<String> pickAxes; private final @NotNull HashSet<String> pickAxes;
private final HashSet<String> tridents; private final @NotNull HashSet<String> tridents;
private final HashSet<String> bows; private final @NotNull HashSet<String> bows;
private final HashSet<String> tools; private final @NotNull HashSet<String> tools;
private final HashSet<String> enchantables; private final @NotNull HashSet<String> enchantables;
private final HashSet<String> ores; private final @NotNull HashSet<String> ores;
private final HashMap<String, Integer> tierValue; private final @NotNull HashMap<String, Integer> tierValue;
public MaterialMapStore() public MaterialMapStore()
@ -62,7 +63,7 @@ public class MaterialMapStore {
abilityBlackList = new HashSet<>(); abilityBlackList = new HashSet<>();
toolBlackList = new HashSet<>(); toolBlackList = new HashSet<>();
mossyWhiteList = new HashSet<>(); mossyWhiteList = new HashSet<>();
leavesWhiteList = new HashSet<>(); treeFellerDestructibleWhiteList = new HashSet<>();
herbalismAbilityBlackList = new HashSet<>(); herbalismAbilityBlackList = new HashSet<>();
blockCrackerWhiteList = new HashSet<>(); blockCrackerWhiteList = new HashSet<>();
canMakeShroomyWhiteList = new HashSet<>(); canMakeShroomyWhiteList = new HashSet<>();
@ -104,52 +105,12 @@ public class MaterialMapStore {
fillVanillaMaterialRegisters(); fillVanillaMaterialRegisters();
} }
public boolean isMultiBlockPlant(Material material)
{
return multiBlockPlant.contains(material.getKey().getKey());
}
public boolean isAbilityActivationBlackListed(Material material)
{
return abilityBlackList.contains(material.getKey().getKey());
}
public boolean isToolActivationBlackListed(Material material)
{
return toolBlackList.contains(material.getKey().getKey());
}
public boolean isMossyWhiteListed(Material material)
{
return mossyWhiteList.contains(material.getKey().getKey());
}
public boolean isLeavesWhiteListed(Material material)
{
return leavesWhiteList.contains(material.getKey().getKey());
}
public boolean isHerbalismAbilityWhiteListed(Material material)
{
return herbalismAbilityBlackList.contains(material.getKey().getKey());
}
public boolean isBlockCrackerWhiteListed(Material material)
{
return blockCrackerWhiteList.contains(material.getKey().getKey());
}
public boolean isShroomyWhiteListed(Material material)
{
return canMakeShroomyWhiteList.contains(material.getKey().getKey());
}
private void fillVanillaMaterialRegisters() private void fillVanillaMaterialRegisters()
{ {
fillAbilityBlackList(); fillAbilityBlackList();
fillToolBlackList(); fillToolBlackList();
fillMossyWhiteList(); fillMossyWhiteList();
fillLeavesWhiteList(); fillTreeFellerDestructibleWhiteList();
fillHerbalismAbilityBlackList(); fillHerbalismAbilityBlackList();
fillBlockCrackerWhiteList(); fillBlockCrackerWhiteList();
fillShroomyWhiteList(); fillShroomyWhiteList();
@ -164,6 +125,46 @@ public class MaterialMapStore {
fillTierMap(); fillTierMap();
} }
public boolean isMultiBlockPlant(@NotNull Material material)
{
return multiBlockPlant.contains(material.getKey().getKey());
}
public boolean isAbilityActivationBlackListed(@NotNull Material material)
{
return abilityBlackList.contains(material.getKey().getKey());
}
public boolean isToolActivationBlackListed(@NotNull Material material)
{
return toolBlackList.contains(material.getKey().getKey());
}
public boolean isMossyWhiteListed(@NotNull Material material)
{
return mossyWhiteList.contains(material.getKey().getKey());
}
public boolean isTreeFellerDestructible(@NotNull Material material)
{
return treeFellerDestructibleWhiteList.contains(material.getKey().getKey());
}
public boolean isHerbalismAbilityWhiteListed(@NotNull Material material)
{
return herbalismAbilityBlackList.contains(material.getKey().getKey());
}
public boolean isBlockCrackerWhiteListed(@NotNull Material material)
{
return blockCrackerWhiteList.contains(material.getKey().getKey());
}
public boolean isShroomyWhiteListed(@NotNull Material material)
{
return canMakeShroomyWhiteList.contains(material.getKey().getKey());
}
private void fillTierMap() { private void fillTierMap() {
for(String id : leatherArmor) { for(String id : leatherArmor) {
tierValue.put(id, 1); tierValue.put(id, 1);
@ -418,26 +419,7 @@ public class MaterialMapStore {
ironTools.add("iron_shovel"); ironTools.add("iron_shovel");
//Used for repair, remove in 2.2 //Used for repair, remove in 2.2
//TODO: Remove in 2.2 //TODO: Remove in config update
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
//TODO: Remove in 2.2
ironTools.add("bucket"); ironTools.add("bucket");
ironTools.add("flint_and_steel"); ironTools.add("flint_and_steel");
ironTools.add("shears"); ironTools.add("shears");
@ -555,7 +537,7 @@ public class MaterialMapStore {
* @param material target material * @param material target material
* @return true if it is used for armor * @return true if it is used for armor
*/ */
public boolean isArmor(Material material) { public boolean isArmor(@NotNull Material material) {
return isArmor(material.getKey().getKey()); return isArmor(material.getKey().getKey());
} }
@ -564,207 +546,196 @@ public class MaterialMapStore {
* @param id target item id * @param id target item id
* @return true if the item id matches armor * @return true if the item id matches armor
*/ */
public boolean isArmor(String id) { public boolean isArmor(@NotNull String id) {
return armors.contains(id); return armors.contains(id);
} }
public boolean isTool(Material material) { public boolean isTool(@NotNull Material material) {
return isTool(material.getKey().getKey()); return isTool(material.getKey().getKey());
} }
public boolean isTool(String id) { public boolean isTool(@NotNull String id) {
return tools.contains(id); return tools.contains(id);
} }
public boolean isEnchantable(Material material) { public boolean isEnchantable(@NotNull Material material) {
return isEnchantable(material.getKey().getKey()); return isEnchantable(material.getKey().getKey());
} }
public boolean isEnchantable(String id) { public boolean isEnchantable(@NotNull String id) {
return enchantables.contains(id); return enchantables.contains(id);
} }
public boolean isOre(Material material) { public boolean isOre(@NotNull Material material) {
return isOre(material.getKey().getKey()); return isOre(material.getKey().getKey());
} }
public boolean isOre(String id) { public boolean isOre(@NotNull String id) {
return ores.contains(id); return ores.contains(id);
} }
public boolean isBow(Material material) { public boolean isBow(@NotNull Material material) {
return isBow(material.getKey().getKey()); return isBow(material.getKey().getKey());
} }
public boolean isBow(String id) { public boolean isBow(@NotNull String id) {
return bows.contains(id); return bows.contains(id);
} }
public boolean isLeatherArmor(Material material) { public boolean isLeatherArmor(@NotNull Material material) {
return isLeatherArmor(material.getKey().getKey()); return isLeatherArmor(material.getKey().getKey());
} }
public boolean isLeatherArmor(String id) { public boolean isLeatherArmor(@NotNull String id) {
return leatherArmor.contains(id); return leatherArmor.contains(id);
} }
public boolean isIronArmor(Material material) { public boolean isIronArmor(@NotNull Material material) {
return isIronArmor(material.getKey().getKey()); return isIronArmor(material.getKey().getKey());
} }
public boolean isIronArmor(String id) { public boolean isIronArmor(@NotNull String id) {
return ironArmor.contains(id); return ironArmor.contains(id);
} }
public boolean isGoldArmor(Material material) { public boolean isGoldArmor(@NotNull Material material) {
return isGoldArmor(material.getKey().getKey()); return isGoldArmor(material.getKey().getKey());
} }
public boolean isGoldArmor(String id) { public boolean isGoldArmor(@NotNull String id) {
return goldArmor.contains(id); return goldArmor.contains(id);
} }
public boolean isDiamondArmor(Material material) { public boolean isDiamondArmor(@NotNull Material material) {
return isDiamondArmor(material.getKey().getKey()); return isDiamondArmor(material.getKey().getKey());
} }
public boolean isDiamondArmor(String id) { public boolean isDiamondArmor(@NotNull String id) {
return diamondArmor.contains(id); return diamondArmor.contains(id);
} }
public boolean isChainmailArmor(Material material) { public boolean isChainmailArmor(@NotNull Material material) {
return isChainmailArmor(material.getKey().getKey()); return isChainmailArmor(material.getKey().getKey());
} }
public boolean isChainmailArmor(String id) { public boolean isChainmailArmor(@NotNull String id) {
return chainmailArmor.contains(id); return chainmailArmor.contains(id);
} }
public boolean isNetheriteArmor(Material material) { public boolean isNetheriteArmor(@NotNull Material material) {
return isNetheriteArmor(material.getKey().getKey()); return isNetheriteArmor(material.getKey().getKey());
} }
public boolean isNetheriteArmor(String id) { public boolean isNetheriteArmor(@NotNull String id) {
return netheriteArmor.contains(id); return netheriteArmor.contains(id);
} }
public boolean isWoodTool(Material material) { public boolean isWoodTool(@NotNull Material material) {
return isWoodTool(material.getKey().getKey()); return isWoodTool(material.getKey().getKey());
} }
public boolean isWoodTool(String id) { public boolean isWoodTool(@NotNull String id) {
return woodTools.contains(id); return woodTools.contains(id);
} }
public boolean isStoneTool(Material material) { public boolean isStoneTool(@NotNull Material material) {
return isStoneTool(material.getKey().getKey()); return isStoneTool(material.getKey().getKey());
} }
public boolean isStoneTool(String id) { public boolean isStoneTool(@NotNull String id) {
return stoneTools.contains(id); return stoneTools.contains(id);
} }
public boolean isIronTool(Material material) { public boolean isIronTool(@NotNull Material material) {
return isIronTool(material.getKey().getKey()); return isIronTool(material.getKey().getKey());
} }
public boolean isIronTool(String id) { public boolean isIronTool(@NotNull String id) {
return ironTools.contains(id); return ironTools.contains(id);
} }
public boolean isGoldTool(Material material) { public boolean isGoldTool(@NotNull Material material) {
return isGoldTool(material.getKey().getKey()); return isGoldTool(material.getKey().getKey());
} }
public boolean isGoldTool(String id) { public boolean isGoldTool(@NotNull String id) {
return goldTools.contains(id); return goldTools.contains(id);
} }
public boolean isDiamondTool(Material material) { public boolean isDiamondTool(@NotNull Material material) {
return isDiamondTool(material.getKey().getKey()); return isDiamondTool(material.getKey().getKey());
} }
public boolean isDiamondTool(String id) { public boolean isDiamondTool(@NotNull String id) {
return diamondTools.contains(id); return diamondTools.contains(id);
} }
public boolean isSword(Material material) { public boolean isSword(@NotNull Material material) {
return isSword(material.getKey().getKey()); return isSword(material.getKey().getKey());
} }
public boolean isSword(String id) { public boolean isSword(@NotNull String id) {
return swords.contains(id); return swords.contains(id);
} }
public boolean isAxe(Material material) { public boolean isAxe(@NotNull Material material) {
return isAxe(material.getKey().getKey()); return isAxe(material.getKey().getKey());
} }
public boolean isAxe(String id) { public boolean isAxe(@NotNull String id) {
return axes.contains(id); return axes.contains(id);
} }
public boolean isPickAxe(Material material) { public boolean isPickAxe(@NotNull Material material) {
return isPickAxe(material.getKey().getKey()); return isPickAxe(material.getKey().getKey());
} }
public boolean isPickAxe(String id) { public boolean isPickAxe(@NotNull String id) {
return pickAxes.contains(id); return pickAxes.contains(id);
} }
public boolean isShovel(Material material) { public boolean isShovel(@NotNull Material material) {
return isShovel(material.getKey().getKey()); return isShovel(material.getKey().getKey());
} }
public boolean isShovel(String id) { public boolean isShovel(@NotNull String id) {
return shovels.contains(id); return shovels.contains(id);
} }
public boolean isHoe(Material material) { public boolean isHoe(@NotNull Material material) {
return isHoe(material.getKey().getKey()); return isHoe(material.getKey().getKey());
} }
public boolean isHoe(String id) { public boolean isHoe(@NotNull String id) {
return hoes.contains(id); return hoes.contains(id);
} }
public boolean isNetheriteTool(Material material) { public boolean isNetheriteTool(@NotNull Material material) {
return isNetheriteTool(material.getKey().getKey()); return isNetheriteTool(material.getKey().getKey());
} }
public boolean isNetheriteTool(String id) { public boolean isNetheriteTool(@NotNull String id) {
return netheriteTools.contains(id); return netheriteTools.contains(id);
} }
public boolean isStringTool(Material material) { public boolean isStringTool(@NotNull Material material) {
return isStringTool(material.getKey().getKey()); return isStringTool(material.getKey().getKey());
} }
public boolean isStringTool(String id) { public boolean isStringTool(@NotNull String id) {
return stringTools.contains(id); return stringTools.contains(id);
} }
public boolean isGlass(Material material) { public boolean isGlass(@NotNull Material material) {
return glassBlocks.contains(material.getKey().getKey()); return glassBlocks.contains(material.getKey().getKey());
} }
public boolean isFood(Material material) { public boolean isFood(@NotNull Material material) {
return foodItemWhiteList.contains(material.getKey().getKey()); return foodItemWhiteList.contains(material.getKey().getKey());
} }
private void fillMultiBlockPlantSet() private void fillMultiBlockPlantSet()
{ {
//Single Block Plants
// plantBlockSet.add("melon");
// plantBlockSet.add("pumpkin");
// plantBlockSet.add("potatoes");
// plantBlockSet.add("carrots");
// plantBlockSet.add("beetroots");
// plantBlockSet.add("nether_wart");
// plantBlockSet.add("grass");
// plantBlockSet.add("fern");
// plantBlockSet.add("large_fern");
//Multi-Block Plants //Multi-Block Plants
multiBlockPlant.add("cactus"); multiBlockPlant.add("cactus");
multiBlockPlant.add("chorus_plant"); multiBlockPlant.add("chorus_plant");
@ -802,16 +773,18 @@ public class MaterialMapStore {
herbalismAbilityBlackList.add("farmland"); herbalismAbilityBlackList.add("farmland");
} }
private void fillLeavesWhiteList() private void fillTreeFellerDestructibleWhiteList()
{ {
leavesWhiteList.add("oak_leaves"); treeFellerDestructibleWhiteList.add("oak_leaves");
leavesWhiteList.add("acacia_leaves"); treeFellerDestructibleWhiteList.add("acacia_leaves");
leavesWhiteList.add("birch_leaves"); treeFellerDestructibleWhiteList.add("birch_leaves");
leavesWhiteList.add("dark_oak_leaves"); treeFellerDestructibleWhiteList.add("dark_oak_leaves");
leavesWhiteList.add("jungle_leaves"); treeFellerDestructibleWhiteList.add("jungle_leaves");
leavesWhiteList.add("spruce_leaves"); treeFellerDestructibleWhiteList.add("spruce_leaves");
leavesWhiteList.add("nether_wart_block"); treeFellerDestructibleWhiteList.add("nether_wart_block");
leavesWhiteList.add("warped_wart_block"); treeFellerDestructibleWhiteList.add("warped_wart_block");
treeFellerDestructibleWhiteList.add("brown_mushroom_block");
treeFellerDestructibleWhiteList.add("red_mushroom_block");
} }
private void fillMossyWhiteList() private void fillMossyWhiteList()
@ -1090,24 +1063,24 @@ public class MaterialMapStore {
toolBlackList.add("respawn_anchor"); toolBlackList.add("respawn_anchor");
} }
public HashSet<String> getNetheriteArmor() { public @NotNull HashSet<String> getNetheriteArmor() {
return netheriteArmor; return netheriteArmor;
} }
public HashSet<String> getNetheriteTools() { public @NotNull HashSet<String> getNetheriteTools() {
return netheriteTools; return netheriteTools;
} }
public int getTier(Material material) { public int getTier(@NotNull Material material) {
return getTier(material.getKey().getKey()); return getTier(material.getKey().getKey());
} }
public int getTier(String id) { public int getTier(@NotNull String id) {
return tierValue.getOrDefault(id, 1); //1 for unknown items return tierValue.getOrDefault(id, 1); //1 for unknown items
} }
private void addToHashSet(String string, HashSet<String> stringHashSet) private void addToHashSet(@NotNull String string, @NotNull HashSet<String> stringHashSet)
{ {
stringHashSet.add(string.toLowerCase(Locale.ENGLISH)); stringHashSet.add(string.toLowerCase(Locale.ENGLISH));
} }

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.util; package com.gmail.nossr50.util;
import com.gmail.nossr50.api.ItemSpawnReason;
import com.gmail.nossr50.events.items.McMMOItemSpawnEvent; import com.gmail.nossr50.events.items.McMMOItemSpawnEvent;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask; import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
@ -11,6 +12,8 @@ import org.bukkit.block.BlockState;
import org.bukkit.entity.*; import org.bukkit.entity.*;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.Locale; import java.util.Locale;
@ -18,7 +21,7 @@ import java.util.Random;
import java.util.Set; import java.util.Set;
public final class Misc { public final class Misc {
private static final Random random = new Random(); private static final @NotNull Random random = new Random();
public static final int TIME_CONVERSION_FACTOR = 1000; public static final int TIME_CONVERSION_FACTOR = 1000;
public static final int TICK_CONVERSION_FACTOR = 20; public static final int TICK_CONVERSION_FACTOR = 20;
@ -37,7 +40,7 @@ public final class Misc {
public static final float LEVELUP_PITCH = 0.5F; // Reduced to differentiate between vanilla level-up public static final float LEVELUP_PITCH = 0.5F; // Reduced to differentiate between vanilla level-up
public static final float LEVELUP_VOLUME = 0.75F * Config.getInstance().getMasterVolume(); // Use max volume always*/ public static final float LEVELUP_VOLUME = 0.75F * Config.getInstance().getMasterVolume(); // Use max volume always*/
public static final Set<String> modNames = ImmutableSet.of("LOTR", "BUILDCRAFT", "ENDERIO", "ENHANCEDBIOMES", "IC2", "METALLURGY", "FORESTRY", "GALACTICRAFT", "RAILCRAFT", "TWILIGHTFOREST", "THAUMCRAFT", "GRAVESTONEMOD", "GROWTHCRAFT", "ARCTICMOBS", "DEMONMOBS", "INFERNOMOBS", "SWAMPMOBS", "MARICULTURE", "MINESTRAPPOLATION"); public static final @NotNull Set<String> modNames = ImmutableSet.of("LOTR", "BUILDCRAFT", "ENDERIO", "ENHANCEDBIOMES", "IC2", "METALLURGY", "FORESTRY", "GALACTICRAFT", "RAILCRAFT", "TWILIGHTFOREST", "THAUMCRAFT", "GRAVESTONEMOD", "GROWTHCRAFT", "ARCTICMOBS", "DEMONMOBS", "INFERNOMOBS", "SWAMPMOBS", "MARICULTURE", "MINESTRAPPOLATION");
private Misc() {} private Misc() {}
@ -54,7 +57,7 @@ public final class Misc {
* @param entity target entity * @param entity target entity
* @return true if the entity is not a Villager and is not a "NPC" * @return true if the entity is not a Villager and is not a "NPC"
*/ */
public static boolean isNPCEntityExcludingVillagers(Entity entity) { public static boolean isNPCEntityExcludingVillagers(@NotNull Entity entity) {
return (!isVillager(entity) return (!isVillager(entity)
&& isNPCIncludingVillagers(entity)); //Compatibility with some mod.. && isNPCIncludingVillagers(entity)); //Compatibility with some mod..
} }
@ -73,7 +76,7 @@ public final class Misc {
return entityType.equalsIgnoreCase("wandering_trader") || entity instanceof Villager; return entityType.equalsIgnoreCase("wandering_trader") || entity instanceof Villager;
} }
public static boolean isNPCIncludingVillagers(Entity entity) { public static boolean isNPCIncludingVillagers(@Nullable Entity entity) {
return (entity == null return (entity == null
|| (hasNPCMetadataTag(entity)) || (hasNPCMetadataTag(entity))
|| (isNPCClassType(entity)) || (isNPCClassType(entity))
@ -88,7 +91,7 @@ public final class Misc {
* @param maxDistance The max distance apart * @param maxDistance The max distance apart
* @return true if the distance between {@code first} and {@code second} is less than {@code maxDistance}, false otherwise * @return true if the distance between {@code first} and {@code second} is less than {@code maxDistance}, false otherwise
*/ */
public static boolean isNear(Location first, Location second, double maxDistance) { public static boolean isNear(@NotNull Location first, @NotNull Location second, double maxDistance) {
return (first.getWorld() == second.getWorld()) && (first.distanceSquared(second) < (maxDistance * maxDistance) || maxDistance == 0); return (first.getWorld() == second.getWorld()) && (first.distanceSquared(second) < (maxDistance * maxDistance) || maxDistance == 0);
} }
@ -102,9 +105,25 @@ public final class Misc {
return blockState.getLocation().add(0.5, 0.5, 0.5); return blockState.getLocation().add(0.5, 0.5, 0.5);
} }
public static void dropItems(Location location, Collection<ItemStack> drops) { public static void spawnItemsFromCollection(@NotNull Location location, @NotNull Collection<ItemStack> drops, @NotNull ItemSpawnReason itemSpawnReason) {
for (ItemStack drop : drops) { for (ItemStack drop : drops) {
dropItem(location, drop); spawnItem(location, drop, itemSpawnReason);
}
}
/**
* Drops only the first n items in a collection
* Size should always be a positive integer above 0
*
* @param location target drop location
* @param drops collection to iterate over
* @param sizeLimit the number of drops to process
*/
public static void spawnItemsFromCollection(@NotNull Location location, @NotNull Collection<ItemStack> drops, @NotNull ItemSpawnReason itemSpawnReason, int sizeLimit) {
ItemStack[] arrayDrops = drops.toArray(new ItemStack[0]);
for(int i = 0; i < sizeLimit-1; i++) {
spawnItem(location, arrayDrops[i], itemSpawnReason);
} }
} }
@ -115,9 +134,9 @@ public final class Misc {
* @param is The items to drop * @param is The items to drop
* @param quantity The amount of items to drop * @param quantity The amount of items to drop
*/ */
public static void dropItems(Location location, ItemStack is, int quantity) { public static void spawnItems(@NotNull Location location, @NotNull ItemStack is, int quantity, @NotNull ItemSpawnReason itemSpawnReason) {
for (int i = 0; i < quantity; i++) { for (int i = 0; i < quantity; i++) {
dropItem(location, is); spawnItem(location, is, itemSpawnReason);
} }
} }
@ -126,15 +145,16 @@ public final class Misc {
* *
* @param location The location to drop the item at * @param location The location to drop the item at
* @param itemStack The item to drop * @param itemStack The item to drop
* @param itemSpawnReason the reason for the item drop
* @return Dropped Item entity or null if invalid or cancelled * @return Dropped Item entity or null if invalid or cancelled
*/ */
public static Item dropItem(Location location, ItemStack itemStack) { public static @Nullable Item spawnItem(@NotNull Location location, @NotNull ItemStack itemStack, @NotNull ItemSpawnReason itemSpawnReason) {
if (itemStack.getType() == Material.AIR) { if (itemStack.getType() == Material.AIR || location.getWorld() == null) {
return null; return null;
} }
// We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event. // We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event.
McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(location, itemStack); McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(location, itemStack, itemSpawnReason);
mcMMO.p.getServer().getPluginManager().callEvent(event); mcMMO.p.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
@ -149,22 +169,23 @@ public final class Misc {
* *
* @param location The location to drop the item at * @param location The location to drop the item at
* @param itemStack The item to drop * @param itemStack The item to drop
* @param itemSpawnReason the reason for the item drop
* @return Dropped Item entity or null if invalid or cancelled * @return Dropped Item entity or null if invalid or cancelled
*/ */
public static Item dropItem(Location location, ItemStack itemStack, int count) { public static @Nullable Item spawnItemNaturally(@NotNull Location location, @NotNull ItemStack itemStack, @NotNull ItemSpawnReason itemSpawnReason) {
if (itemStack.getType() == Material.AIR) { if (itemStack.getType() == Material.AIR || location.getWorld() == null) {
return null; return null;
} }
// We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event. // We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event.
McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(location, itemStack); McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(location, itemStack, itemSpawnReason);
mcMMO.p.getServer().getPluginManager().callEvent(event); mcMMO.p.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return null; return null;
} }
return location.getWorld().dropItem(location, itemStack); return location.getWorld().dropItemNaturally(location, itemStack);
} }
/** /**
@ -175,9 +196,9 @@ public final class Misc {
* @param speed the speed that the item should travel * @param speed the speed that the item should travel
* @param quantity The amount of items to drop * @param quantity The amount of items to drop
*/ */
public static void spawnItemsTowardsLocation(Location fromLocation, Location toLocation, ItemStack is, int quantity, double speed) { public static void spawnItemsTowardsLocation(@NotNull Location fromLocation, @NotNull Location toLocation, @NotNull ItemStack is, int quantity, double speed, @NotNull ItemSpawnReason itemSpawnReason) {
for (int i = 0; i < quantity; i++) { for (int i = 0; i < quantity; i++) {
spawnItemTowardsLocation(fromLocation, toLocation, is, speed); spawnItemTowardsLocation(fromLocation, toLocation, is, speed, itemSpawnReason);
} }
} }
@ -191,7 +212,7 @@ public final class Misc {
* @param speed the speed that the item should travel * @param speed the speed that the item should travel
* @return Dropped Item entity or null if invalid or cancelled * @return Dropped Item entity or null if invalid or cancelled
*/ */
public static Item spawnItemTowardsLocation(Location fromLocation, Location toLocation, ItemStack itemToSpawn, double speed) { public static @Nullable Item spawnItemTowardsLocation(@NotNull Location fromLocation, @NotNull Location toLocation, @NotNull ItemStack itemToSpawn, double speed, @NotNull ItemSpawnReason itemSpawnReason) {
if (itemToSpawn.getType() == Material.AIR) { if (itemToSpawn.getType() == Material.AIR) {
return null; return null;
} }
@ -201,12 +222,15 @@ public final class Misc {
Location spawnLocation = fromLocation.clone(); Location spawnLocation = fromLocation.clone();
Location targetLocation = toLocation.clone(); Location targetLocation = toLocation.clone();
if(spawnLocation.getWorld() == null)
return null;
// We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event. // We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event.
McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(spawnLocation, clonedItem); McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(spawnLocation, clonedItem, itemSpawnReason);
mcMMO.p.getServer().getPluginManager().callEvent(event); mcMMO.p.getServer().getPluginManager().callEvent(event);
//Something cancelled the event so back out //Something cancelled the event so back out
if (event.isCancelled() || event.getItemStack() == null) { if (event.isCancelled()) {
return null; return null;
} }
@ -224,7 +248,7 @@ public final class Misc {
return spawnedItem; return spawnedItem;
} }
public static void profileCleanup(String playerName) { public static void profileCleanup(@NotNull String playerName) {
Player player = mcMMO.p.getServer().getPlayerExact(playerName); Player player = mcMMO.p.getServer().getPlayerExact(playerName);
if (player != null) { if (player != null) {
@ -239,7 +263,7 @@ public final class Misc {
} }
} }
public static String getModName(String materialName) { public static String getModName(@NotNull String materialName) {
for (String mod : modNames) { for (String mod : modNames) {
if (materialName.contains(mod)) { if (materialName.contains(mod)) {
return mod; return mod;
@ -258,7 +282,7 @@ public final class Misc {
/** /**
* Gets a random location near the specified location * Gets a random location near the specified location
*/ */
public static Location getLocationOffset(Location location, double strength) { public static Location getLocationOffset(@NotNull Location location, double strength) {
double blockX = location.getBlockX(); double blockX = location.getBlockX();
double blockZ = location.getBlockZ(); double blockZ = location.getBlockZ();
@ -272,7 +296,7 @@ public final class Misc {
return new Location(location.getWorld(), blockX, location.getY(), blockZ); return new Location(location.getWorld(), blockX, location.getY(), blockZ);
} }
public static Random getRandom() { public static @NotNull Random getRandom() {
return random; return random;
} }
} }

View File

@ -136,10 +136,6 @@ public class ModManager {
return Config.getInstance().getBlockModsEnabled() && customLogs.contains(state.getType()); return Config.getInstance().getBlockModsEnabled() && customLogs.contains(state.getType());
} }
public boolean isCustomLeaf(BlockState state) {
return Config.getInstance().getBlockModsEnabled() && customLeaves.contains(state.getType());
}
public boolean isCustomAbilityBlock(BlockState state) { public boolean isCustomAbilityBlock(BlockState state) {
return Config.getInstance().getBlockModsEnabled() && customAbilityBlocks.contains(state.getType()); return Config.getInstance().getBlockModsEnabled() && customAbilityBlocks.contains(state.getType());
} }