diff --git a/src/main/java/com/gmail/nossr50/config/Config.java b/src/main/java/com/gmail/nossr50/config/Config.java index 8554d5f78..7420f7548 100644 --- a/src/main/java/com/gmail/nossr50/config/Config.java +++ b/src/main/java/com/gmail/nossr50/config/Config.java @@ -300,6 +300,10 @@ public class Config extends ConfigLoader { return disabled; } + /* AFK Leveling */ + public boolean getAcrobaticsAFKDisabled() { return config.getBoolean("Skills.Acrobatics.Prevent_AFK_Leveling", true); } + public boolean getHerbalismAFKDisabled() { return config.getBoolean("Skills.Herbalism.Prevent_AFK_Leveling", true); } + /* Arcane Forging */ public boolean getArcaneForgingDowngradeEnabled() { return config.getBoolean("Arcane_Forging.Downgrades.Enabled", true); } public int getArcaneForgingDowngradeChanceRank1() { return config.getInt("Arcane_Forging.Downgrades.Chance.Rank_1", 75); } diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java index a86fc23c4..21b9c3a2e 100644 --- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java @@ -78,11 +78,14 @@ public class BlockListener implements Listener { } } + /** * Monitor BlockPhysics events. * * @param event The event to monitor */ + // Disabled until a better patch can be applied. This does nothing but flag the wrong block. +/* @EventHandler(priority = EventPriority.MONITOR) public void onBlockPhysics(BlockPhysicsEvent event) { //TODO: Figure out how to REMOVE metadata from the location the sand/gravel fell from. @@ -96,6 +99,7 @@ public class BlockListener implements Listener { } } } +*/ /** * Monitor BlockPistonRetract events. diff --git a/src/main/java/com/gmail/nossr50/runnables/GreenThumbTimer.java b/src/main/java/com/gmail/nossr50/runnables/GreenThumbTimer.java index 4debdaf5d..9181ee516 100644 --- a/src/main/java/com/gmail/nossr50/runnables/GreenThumbTimer.java +++ b/src/main/java/com/gmail/nossr50/runnables/GreenThumbTimer.java @@ -11,33 +11,74 @@ import com.gmail.nossr50.datatypes.SkillType; public class GreenThumbTimer implements Runnable { private Block block; private PlayerProfile profile; + private Material type; - public GreenThumbTimer(Block block, PlayerProfile profile) { + public GreenThumbTimer(Block block, PlayerProfile profile, Material material) { this.block = block; this.profile = profile; + this.type = material; } @Override public void run() { - block.setType(Material.CROPS); + if(this.block.getType() != this.type) + this.block.setType(this.type); - //This replants the wheat at a certain stage in development based on Herbalism Skill - if (!profile.getAbilityMode(AbilityType.GREEN_TERRA)) { - if (profile.getSkillLevel(SkillType.HERBALISM) >= 600) { - block.setData(CropState.MEDIUM.getData()); - } - else if (profile.getSkillLevel(SkillType.HERBALISM) >= 400) { - block.setData(CropState.SMALL.getData()); - } - else if (profile.getSkillLevel(SkillType.HERBALISM) >= 200) { - block.setData(CropState.VERY_SMALL.getData()); + 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)) { + if (this.profile.getSkillLevel(SkillType.HERBALISM) >= 600) { + this.block.setData(CropState.MEDIUM.getData()); + } + else if (this.profile.getSkillLevel(SkillType.HERBALISM) >= 400) { + this.block.setData(CropState.SMALL.getData()); + } + else if (this.profile.getSkillLevel(SkillType.HERBALISM) >= 200) { + this.block.setData(CropState.VERY_SMALL.getData()); + } + else { + this.block.setData(CropState.GERMINATED.getData()); + } } else { - block.setData(CropState.GERMINATED.getData()); + this.block.setData(CropState.MEDIUM.getData()); } - } - else { - block.setData(CropState.MEDIUM.getData()); + break; + case NETHER_WARTS: + if (!this.profile.getAbilityMode(AbilityType.GREEN_TERRA)) { + if (this.profile.getSkillLevel(SkillType.HERBALISM) >= 600) { + this.block.setData((byte) 2); + } + else if (this.profile.getSkillLevel(SkillType.HERBALISM) >= 400) { + this.block.setData((byte) 1); + } + else { + this.block.setData((byte) 0); + } + } + else { + this.block.setData((byte) 2); + } + break; + case COCOA: + if (!this.profile.getAbilityMode(AbilityType.GREEN_TERRA)) { + if (this.profile.getSkillLevel(SkillType.HERBALISM) >= 600) { + this.block.setData((byte) ((this.block.getData() ^ ((byte) 0xc)) | ((byte) 4))); + } + else if (this.profile.getSkillLevel(SkillType.HERBALISM) >= 400) { + this.block.setData((byte) ((this.block.getData() ^ ((byte) 0xc)) | ((byte) 4))); + } + else { + this.block.setData((byte) (this.block.getData() ^ ((byte) 0xc))); + } + } + else { + this.block.setData((byte) ((this.block.getData() ^ ((byte) 0xc)) | ((byte) 4))); + } + break; } } } diff --git a/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java index 5361df9fa..241b042a6 100644 --- a/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java +++ b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java @@ -3,6 +3,7 @@ package com.gmail.nossr50.skills.acrobatics; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageEvent; +import com.gmail.nossr50.config.Config; import com.gmail.nossr50.datatypes.PlayerProfile; import com.gmail.nossr50.datatypes.SkillType; import com.gmail.nossr50.util.Permissions; @@ -33,6 +34,9 @@ public class AcrobaticsManager { return; } + if(Config.getInstance().getAcrobaticsAFKDisabled() && player.isInsideVehicle()) + return; + RollEventHandler eventHandler = new RollEventHandler(this, event); int randomChance = 1000; diff --git a/src/main/java/com/gmail/nossr50/skills/gathering/Herbalism.java b/src/main/java/com/gmail/nossr50/skills/gathering/Herbalism.java index 303cdad1c..73a5f61c8 100644 --- a/src/main/java/com/gmail/nossr50/skills/gathering/Herbalism.java +++ b/src/main/java/com/gmail/nossr50/skills/gathering/Herbalism.java @@ -80,6 +80,9 @@ public class Herbalism { * @param plugin mcMMO plugin instance */ public static void herbalismProcCheck(final Block block, Player player, BlockBreakEvent event, mcMMO plugin) { + if(player == null) + return; + final PlayerProfile profile = Users.getProfile(player); final int MAX_BONUS_LEVEL = 1000; @@ -149,6 +152,10 @@ public class Herbalism { if (data == (byte) 0x3) { mat = Material.NETHER_STALK; xp = Config.getInstance().getHerbalismXPNetherWart(); + + if (Permissions.getInstance().greenThumbNetherwart(player)) { + greenThumbWheat(block, player, event, plugin); + } } break; @@ -201,6 +208,11 @@ public class Herbalism { if ((((byte) data) & 0x8) == 0x8) { mat = Material.COCOA; xp = Config.getInstance().getHerbalismXPCocoa(); + + + if (Permissions.getInstance().greenThumbCocoa(player)) { + greenThumbWheat(block, player, event, plugin); + } } break; @@ -208,6 +220,11 @@ public class Herbalism { if (data == CropState.RIPE.getData()) { mat = Material.CARROT; xp = Config.getInstance().getHerbalismXPCarrot(); + + + if (Permissions.getInstance().greenThumbCarrots(player)) { + greenThumbWheat(block, player, event, plugin); + } } break; @@ -215,6 +232,10 @@ public class Herbalism { if (data == CropState.RIPE.getData()) { mat = Material.POTATO; xp = Config.getInstance().getHerbalismXPPotato(); + + if (Permissions.getInstance().greenThumbPotatoes(player)) { + greenThumbWheat(block, player, event, plugin); + } } break; @@ -363,6 +384,9 @@ public class Herbalism { } } + if(Config.getInstance().getHerbalismAFKDisabled() && player.isInsideVehicle()) + return; + Skills.xpProcessing(player, profile, SkillType.HERBALISM, xp); } @@ -380,8 +404,28 @@ public class Herbalism { PlayerProfile profile = Users.getProfile(player); int herbLevel = profile.getSkillLevel(SkillType.HERBALISM); PlayerInventory inventory = player.getInventory(); - boolean hasSeeds = inventory.contains(Material.SEEDS); + boolean hasSeeds = false; Location location = block.getLocation(); + Material type = block.getType(); + + switch(type) { + case CROPS: + hasSeeds = inventory.contains(Material.SEEDS); + break; + case COCOA: + // Broken: Requires an update to bukkit to enable seaching for variable-sized ItemStacks. + hasSeeds = inventory.contains(new ItemStack(Material.INK_SACK, 1, (short) 3), 1); + break; + case CARROT: + hasSeeds = inventory.contains(Material.CARROT_ITEM); + break; + case POTATO: + hasSeeds = inventory.contains(Material.POTATO_ITEM); + break; + case NETHER_WARTS: + hasSeeds = inventory.contains(Material.NETHER_STALK); + break; + } int randomChance = 1500; @@ -392,12 +436,35 @@ public class Herbalism { if (hasSeeds && profile.getAbilityMode(AbilityType.GREEN_TERRA) || hasSeeds && (herbLevel > MAX_BONUS_LEVEL || random.nextInt(randomChance) <= herbLevel)) { event.setCancelled(true); - Misc.dropItem(location, new ItemStack(Material.WHEAT)); - Misc.randomDropItems(location, new ItemStack(Material.SEEDS), 50, 3); + switch(type) { + case CROPS: + Misc.dropItem(location, new ItemStack(Material.WHEAT)); + Misc.randomDropItems(location, new ItemStack(Material.SEEDS), 50, 3); + inventory.removeItem(new ItemStack(Material.SEEDS)); + break; + case COCOA: + Misc.dropItem(location, new ItemStack(Material.INK_SACK, 3, (short) 3)); + inventory.removeItem(new ItemStack(Material.INK_SACK, 1, (short) 3)); + break; + case CARROT: + Misc.dropItem(location, new ItemStack(Material.CARROT_ITEM)); + Misc.randomDropItems(location, new ItemStack(Material.CARROT_ITEM), 50, 3); + inventory.removeItem(new ItemStack(Material.POTATO_ITEM)); + break; + case POTATO: + Misc.dropItem(location, new ItemStack(Material.POTATO_ITEM)); + Misc.randomDropItems(location, new ItemStack(Material.POTATO_ITEM), 50, 3); + Misc.randomDropItem(location, new ItemStack(Material.POISONOUS_POTATO), 2); + inventory.removeItem(new ItemStack(Material.POTATO_ITEM)); + break; + case NETHER_WARTS: + Misc.dropItem(location, new ItemStack(Material.NETHER_STALK, 2)); + Misc.randomDropItems(location, new ItemStack(Material.NETHER_STALK), 50, 2); + inventory.removeItem(new ItemStack(Material.NETHER_STALK)); + break; + } - plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new GreenThumbTimer(block, profile), 1); - - inventory.removeItem(new ItemStack(Material.SEEDS)); + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new GreenThumbTimer(block, profile, type), 1); player.updateInventory(); // Needed until replacement available } } diff --git a/src/main/java/com/gmail/nossr50/skills/gathering/WoodCutting.java b/src/main/java/com/gmail/nossr50/skills/gathering/WoodCutting.java index 60148c5b9..6a1e1ab29 100644 --- a/src/main/java/com/gmail/nossr50/skills/gathering/WoodCutting.java +++ b/src/main/java/com/gmail/nossr50/skills/gathering/WoodCutting.java @@ -184,7 +184,7 @@ public class WoodCutting { break; case JUNGLE: - xp += Config.getInstance().getWoodcuttingXPJungle() / 4; //Nerf XP from Jungle Trees when using Tree Feller + xp += Config.getInstance().getWoodcuttingXPJungle() / 2; //Nerf XP from Jungle Trees when using Tree Feller break; default: @@ -424,7 +424,15 @@ public class WoodCutting { xp = ModChecks.getCustomBlock(block).getXpGain(); } else { - TreeSpecies species = TreeSpecies.getByData(block.getData()); + byte type = block.getData(); + + if((type & 0x4) == 0x4) + type ^= 0x4; + + if((type & 0x8) == 0x8) + type ^= 0x8; + + TreeSpecies species = TreeSpecies.getByData(type); //Apparently species can be null in certain cases (custom server mods?) //https://github.com/mcMMO-Dev/mcMMO/issues/229 diff --git a/src/main/java/com/gmail/nossr50/util/Permissions.java b/src/main/java/com/gmail/nossr50/util/Permissions.java index 2d5f079bb..d72f4bbb8 100644 --- a/src/main/java/com/gmail/nossr50/util/Permissions.java +++ b/src/main/java/com/gmail/nossr50/util/Permissions.java @@ -264,6 +264,22 @@ public class Permissions { return player.hasPermission("mcmmo.ability.herbalism.greenthumbblocks"); } + public boolean greenThumbCarrots(Player player) { + return player.hasPermission("mcmmo.ability.herbalism.greenthumbcarrots"); + } + + public boolean greenThumbCocoa(Player player) { + return player.hasPermission("mcmmo.ability.herbalism.greenthumbcocoa"); + } + + public boolean greenThumbNetherwart(Player player) { + return player.hasPermission("mcmmo.ability.herbalism.greenthumbnetherwart"); + } + + public boolean greenThumbPotatoes(Player player) { + return player.hasPermission("mcmmo.ability.herbalism.greenthumbpotatoes"); + } + public boolean greenThumbWheat(Player player) { return player.hasPermission("mcmmo.ability.herbalism.greenthumbwheat"); } diff --git a/src/main/java/com/gmail/nossr50/util/Skills.java b/src/main/java/com/gmail/nossr50/util/Skills.java index 2084cbdb1..b90ccffba 100644 --- a/src/main/java/com/gmail/nossr50/util/Skills.java +++ b/src/main/java/com/gmail/nossr50/util/Skills.java @@ -80,6 +80,9 @@ public class Skills { * @param ability The ability to watch cooldowns for */ public static void watchCooldown(Player player, PlayerProfile profile, AbilityType ability) { + if(player == null || profile == null || ability == null) + return; + if (!profile.getAbilityInformed(ability) && cooldownOver(profile.getSkillDATS(ability) * TIME_CONVERSION_FACTOR, ability.getCooldown(), player)) { profile.setAbilityInformed(ability, true); player.sendMessage(ability.getAbilityRefresh()); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index d731a4e61..5fd0980d9 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -133,6 +133,7 @@ Skills: Acrobatics: Enabled_For_PVP: true Enabled_For_PVE: true + Prevent_AFK_Leveling: true Level_Cap: 0 Archery: Enabled_For_PVP: true @@ -149,6 +150,7 @@ Skills: Level_Cap: 0 Herbalism: Level_Cap: 0 + Prevent_AFK_Leveling: true Green_Thumb: Cobble_To_Mossy: true CobbleWall_To_MossyWall: true