diff --git a/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java b/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java index 38bc76d..b220c49 100644 --- a/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java @@ -87,20 +87,6 @@ public class BlockEventHandler implements Listener PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); Block block = breakEvent.getBlock(); - //optimization: breaking blocks directly underneath your last successfully broken block is always* safe - //*not when the new block was claimed after the last break - //*not in siege mode, where some types of claimed blocks may be broken - Location blockLocation = block.getLocation(); - Location lastBreakLocation = playerData.lastSuccessfulBreak; - if(lastBreakLocation != null && - !GriefPrevention.instance.siegeEnabledForWorld(block.getWorld()) && - blockLocation.getBlockX() == lastBreakLocation.getBlockX() && - blockLocation.getBlockZ() == lastBreakLocation.getBlockZ() && - blockLocation.getBlockY() <= lastBreakLocation.getBlockY()) - { - return; - } - //make sure the player is allowed to break at the location String noBuildReason = GriefPrevention.instance.allowBreak(player, block.getLocation()); if(noBuildReason != null) @@ -110,9 +96,6 @@ public class BlockEventHandler implements Listener return; } - //make a note of any successful breaks - playerData.lastSuccessfulBreak = block.getLocation(); - //FEATURE: automatically clean up hanging treetops //if it's a log if(block.getType() == Material.LOG && GriefPrevention.instance.config_trees_removeFloatingTreetops) @@ -167,7 +150,7 @@ public class BlockEventHandler implements Listener { Player player = placeEvent.getPlayer(); Block block = placeEvent.getBlock(); - + //FEATURE: limit fire placement, to prevent PvP-by-fire //if placed block is fire and pvp is off, apply rules for proximity to other players @@ -191,7 +174,7 @@ public class BlockEventHandler implements Listener if(!GriefPrevention.instance.claimsEnabledForWorld(placeEvent.getBlock().getWorld())) return; //make sure the player is allowed to build at the location - String noBuildReason = GriefPrevention.instance.allowBuild(player, block.getLocation()); + String noBuildReason = GriefPrevention.instance.allowBuild(player, block.getLocation(), block.getType()); if(noBuildReason != null) { GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); @@ -247,7 +230,7 @@ public class BlockEventHandler implements Listener } //if the player has permission for the claim and he's placing UNDER the claim - if(block.getY() <= claim.lesserBoundaryCorner.getBlockY() && claim.allowBuild(player) == null) + if(block.getY() <= claim.lesserBoundaryCorner.getBlockY() && claim.allowBuild(player, block.getType()) == null) { //extend the claim downward this.dataStore.extendClaim(claim, claim.getLesserBoundaryCorner().getBlockY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance); diff --git a/src/me/ryanhamshire/GriefPrevention/Claim.java b/src/me/ryanhamshire/GriefPrevention/Claim.java index 6e5511a..a7958db 100644 --- a/src/me/ryanhamshire/GriefPrevention/Claim.java +++ b/src/me/ryanhamshire/GriefPrevention/Claim.java @@ -311,14 +311,27 @@ public class Claim //permission inheritance for subdivisions if(this.parent != null) - return this.parent.allowBuild(player); + return this.parent.allowEdit(player); //error message if all else fails return GriefPrevention.instance.dataStore.getMessage(Messages.OnlyOwnersModifyClaims, this.getOwnerName()); } + private List placeableFarmingBlocksList = Arrays.asList( + Material.PUMPKIN_STEM, + Material.CROPS, + Material.MELON_STEM, + Material.CARROT, + Material.POTATO, + Material.NETHER_STALK); + + private boolean placeableForFarming(Material material) + { + return this.placeableFarmingBlocksList.contains(material); + } + //build permission check - public String allowBuild(Player player) + public String allowBuild(Player player, Material material) { //if we don't know who's asking, always say no (i've been told some mods can make this happen somehow) if(player == null) return ""; @@ -357,13 +370,24 @@ public class Claim //subdivision permission inheritance if(this.parent != null) - return this.parent.allowBuild(player); + return this.parent.allowBuild(player, material); //failure message for all other cases String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildPermission, this.getOwnerName()); if(player.hasPermission("griefprevention.ignoreclaims")) reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement); - return reason; + + //allow for farming with /containertrust permission + if(reason != null && this.allowContainers(player) == null) + { + //do allow for farming, if player has /containertrust permission + if(this.placeableForFarming(material)) + { + return null; + } + } + + return reason; } private boolean hasExplicitPermission(Player player, ClaimPermission level) @@ -427,7 +451,7 @@ public class Claim } //if not under siege, build rules apply - return this.allowBuild(player); + return this.allowBuild(player, material); } //access permission check diff --git a/src/me/ryanhamshire/GriefPrevention/EntityEventHandler.java b/src/me/ryanhamshire/GriefPrevention/EntityEventHandler.java index adc3e93..5d48bb5 100644 --- a/src/me/ryanhamshire/GriefPrevention/EntityEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/EntityEventHandler.java @@ -308,7 +308,7 @@ class EntityEventHandler implements Listener //if the player doesn't have build permission, don't allow the breakage Player playerRemover = (Player)entityEvent.getRemover(); - String noBuildReason = GriefPrevention.instance.allowBuild(playerRemover, event.getEntity().getLocation()); + String noBuildReason = GriefPrevention.instance.allowBuild(playerRemover, event.getEntity().getLocation(), Material.AIR); if(noBuildReason != null) { event.setCancelled(true); @@ -326,7 +326,7 @@ class EntityEventHandler implements Listener //FEATURE: similar to above, placing a painting requires build permission in the claim //if the player doesn't have permission, don't allow the placement - String noBuildReason = GriefPrevention.instance.allowBuild(event.getPlayer(), event.getEntity().getLocation()); + String noBuildReason = GriefPrevention.instance.allowBuild(event.getPlayer(), event.getEntity().getLocation(), Material.PAINTING); if(noBuildReason != null) { event.setCancelled(true); diff --git a/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java b/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java index 5ec3ea1..743d1b4 100644 --- a/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java +++ b/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java @@ -1509,7 +1509,7 @@ public class GriefPrevention extends JavaPlugin else { - String noBuildReason = claim.allowBuild(player); + String noBuildReason = claim.allowBuild(player, Material.TNT); if(noBuildReason != null) { GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); @@ -1762,7 +1762,7 @@ public class GriefPrevention extends JavaPlugin } //if the player isn't in a claim or has permission to build, tell him to man up - if(claim == null || claim.allowBuild(player) == null) + if(claim == null || claim.allowBuild(player, Material.AIR) == null) { GriefPrevention.sendMessage(player, TextMode.Err, Messages.NotTrappedHere); return true; @@ -2079,7 +2079,7 @@ public class GriefPrevention extends JavaPlugin errorMessage = claim.allowContainers(player); break; default: - errorMessage = claim.allowBuild(player); + errorMessage = claim.allowBuild(player, Material.AIR); } } @@ -2600,7 +2600,7 @@ public class GriefPrevention extends JavaPlugin return this.config_claims_worldModes.get((location.getWorld())) == ClaimsMode.Creative; } - public String allowBuild(Player player, Location location) + public String allowBuild(Player player, Location location, Material material) { PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); Claim claim = this.dataStore.getClaimAt(location, false, playerData.lastClaim); @@ -2632,7 +2632,7 @@ public class GriefPrevention extends JavaPlugin { //cache the claim for later reference playerData.lastClaim = claim; - return claim.allowBuild(player); + return claim.allowBuild(player, material); } } diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerData.java b/src/me/ryanhamshire/GriefPrevention/PlayerData.java index b7159dd..35f0c42 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerData.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerData.java @@ -94,9 +94,6 @@ public class PlayerData //the last claim this player was in, that we know of public Claim lastClaim = null; - //location of the last successfully-broken block, used in a performance optimization - Location lastSuccessfulBreak = null; - //siege public SiegeData siegeData = null; diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java index feb950b..e17cb02 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java @@ -763,7 +763,7 @@ class PlayerEventHandler implements Listener //don't allow interaction with item frames in claimed areas without build permission if(entity instanceof Hanging) { - String noBuildReason = GriefPrevention.instance.allowBuild(player, entity.getLocation()); + String noBuildReason = GriefPrevention.instance.allowBuild(player, entity.getLocation(), Material.ITEM_FRAME); if(noBuildReason != null) { GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); @@ -952,7 +952,7 @@ class PlayerEventHandler implements Listener int minLavaDistance = 10; //make sure the player is allowed to build at the location - String noBuildReason = GriefPrevention.instance.allowBuild(player, block.getLocation()); + String noBuildReason = GriefPrevention.instance.allowBuild(player, block.getLocation(), Material.WATER); if(noBuildReason != null) { GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); @@ -1013,7 +1013,7 @@ class PlayerEventHandler implements Listener if(!GriefPrevention.instance.claimsEnabledForWorld(block.getWorld())) return; //make sure the player is allowed to build at the location - String noBuildReason = GriefPrevention.instance.allowBuild(player, block.getLocation()); + String noBuildReason = GriefPrevention.instance.allowBuild(player, block.getLocation(), Material.AIR); if(noBuildReason != null) { GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); @@ -1086,7 +1086,7 @@ class PlayerEventHandler implements Listener { playerData.lastClaim = claim; - String noBuildReason = claim.allowBuild(player); + String noBuildReason = claim.allowBuild(player, Material.AIR); if(noBuildReason != null) { event.setCancelled(true); @@ -1187,7 +1187,7 @@ class PlayerEventHandler implements Listener Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim); if(claim != null) { - String noBuildReason = claim.allowBuild(player); + String noBuildReason = claim.allowBuild(player, clickedBlockType); if(noBuildReason != null) { event.setCancelled(true); @@ -1209,7 +1209,7 @@ class PlayerEventHandler implements Listener //if it's bonemeal, check for build permission (ink sac == bone meal, must be a Bukkit bug?) if(materialInHand == Material.INK_SACK) { - String noBuildReason = GriefPrevention.instance.allowBuild(player, clickedBlock.getLocation()); + String noBuildReason = GriefPrevention.instance.allowBuild(player, clickedBlock.getLocation(), clickedBlockType); if(noBuildReason != null) { GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason); @@ -1239,7 +1239,7 @@ class PlayerEventHandler implements Listener else if((materialInHand == Material.MONSTER_EGG || materialInHand == Material.MINECART || materialInHand == Material.POWERED_MINECART || materialInHand == Material.STORAGE_MINECART || materialInHand == Material.BOAT) && GriefPrevention.instance.creativeRulesApply(clickedBlock.getLocation())) { //player needs build permission at this location - String noBuildReason = GriefPrevention.instance.allowBuild(player, clickedBlock.getLocation()); + String noBuildReason = GriefPrevention.instance.allowBuild(player, clickedBlock.getLocation(), Material.MINECART); if(noBuildReason != null) { GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason);