Perf: Player Interactions and Block Breaks
More perf boosts. No more anti-tree-topping, and fires are no longer protected by default (new config option).
This commit is contained in:
parent
02fba83551
commit
8acbee346e
|
|
@ -84,25 +84,16 @@ public class BlockEventHandler implements Listener
|
||||||
public void onBlockBreak(BlockBreakEvent breakEvent)
|
public void onBlockBreak(BlockBreakEvent breakEvent)
|
||||||
{
|
{
|
||||||
Player player = breakEvent.getPlayer();
|
Player player = breakEvent.getPlayer();
|
||||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
|
||||||
Block block = breakEvent.getBlock();
|
Block block = breakEvent.getBlock();
|
||||||
|
|
||||||
//make sure the player is allowed to break at the location
|
//make sure the player is allowed to break at the location
|
||||||
String noBuildReason = GriefPrevention.instance.allowBreak(player, block.getLocation());
|
String noBuildReason = GriefPrevention.instance.allowBreak(player, block, block.getLocation());
|
||||||
if(noBuildReason != null)
|
if(noBuildReason != null)
|
||||||
{
|
{
|
||||||
GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason);
|
GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason);
|
||||||
breakEvent.setCancelled(true);
|
breakEvent.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FEATURE: automatically clean up hanging treetops
|
|
||||||
//if it's a log
|
|
||||||
if(block.getType() == Material.LOG && GriefPrevention.instance.config_trees_removeFloatingTreetops)
|
|
||||||
{
|
|
||||||
//run the specialized code for treetop removal (see below)
|
|
||||||
GriefPrevention.instance.handleLogBroken(block);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//when a player places a sign...
|
//when a player places a sign...
|
||||||
|
|
|
||||||
|
|
@ -161,12 +161,6 @@ class EntityEventHandler implements Listener
|
||||||
{
|
{
|
||||||
blocks.remove(i--);
|
blocks.remove(i--);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the block is not claimed and is a log, trigger the anti-tree-top code
|
|
||||||
else if(block.getType() == Material.LOG)
|
|
||||||
{
|
|
||||||
GriefPrevention.instance.handleLogBroken(block);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ public class GriefPrevention extends JavaPlugin
|
||||||
|
|
||||||
public boolean config_claims_preventTheft; //whether containers and crafting blocks are protectable
|
public boolean config_claims_preventTheft; //whether containers and crafting blocks are protectable
|
||||||
public boolean config_claims_protectCreatures; //whether claimed animals may be injured by players without permission
|
public boolean config_claims_protectCreatures; //whether claimed animals may be injured by players without permission
|
||||||
|
public boolean config_claims_protectFires; //whether open flint+steel flames should be protected - optional because it's expensive
|
||||||
public boolean config_claims_preventButtonsSwitches; //whether buttons and switches are protectable
|
public boolean config_claims_preventButtonsSwitches; //whether buttons and switches are protectable
|
||||||
public boolean config_claims_lockWoodenDoors; //whether wooden doors should be locked by default (require /accesstrust)
|
public boolean config_claims_lockWoodenDoors; //whether wooden doors should be locked by default (require /accesstrust)
|
||||||
public boolean config_claims_lockTrapDoors; //whether trap doors should be locked by default (require /accesstrust)
|
public boolean config_claims_lockTrapDoors; //whether trap doors should be locked by default (require /accesstrust)
|
||||||
|
|
@ -115,9 +116,6 @@ public class GriefPrevention extends JavaPlugin
|
||||||
public boolean config_pvp_noCombatInPlayerLandClaims; //whether players may fight in player-owned land claims
|
public boolean config_pvp_noCombatInPlayerLandClaims; //whether players may fight in player-owned land claims
|
||||||
public boolean config_pvp_noCombatInAdminLandClaims; //whether players may fight in admin-owned land claims
|
public boolean config_pvp_noCombatInAdminLandClaims; //whether players may fight in admin-owned land claims
|
||||||
|
|
||||||
public boolean config_trees_removeFloatingTreetops; //whether to automatically remove partially cut trees
|
|
||||||
public boolean config_trees_regrowGriefedTrees; //whether to automatically replant partially cut trees
|
|
||||||
|
|
||||||
public double config_economy_claimBlocksPurchaseCost; //cost to purchase a claim block. set to zero to disable purchase.
|
public double config_economy_claimBlocksPurchaseCost; //cost to purchase a claim block. set to zero to disable purchase.
|
||||||
public double config_economy_claimBlocksSellValue; //return on a sold claim block. set to zero to disable sale.
|
public double config_economy_claimBlocksSellValue; //return on a sold claim block. set to zero to disable sale.
|
||||||
|
|
||||||
|
|
@ -455,6 +453,7 @@ public class GriefPrevention extends JavaPlugin
|
||||||
|
|
||||||
this.config_claims_preventTheft = config.getBoolean("GriefPrevention.Claims.PreventTheft", true);
|
this.config_claims_preventTheft = config.getBoolean("GriefPrevention.Claims.PreventTheft", true);
|
||||||
this.config_claims_protectCreatures = config.getBoolean("GriefPrevention.Claims.ProtectCreatures", true);
|
this.config_claims_protectCreatures = config.getBoolean("GriefPrevention.Claims.ProtectCreatures", true);
|
||||||
|
this.config_claims_protectFires = config.getBoolean("GriefPrevention.Claims.ProtectFires", false);
|
||||||
this.config_claims_preventButtonsSwitches = config.getBoolean("GriefPrevention.Claims.PreventButtonsSwitches", true);
|
this.config_claims_preventButtonsSwitches = config.getBoolean("GriefPrevention.Claims.PreventButtonsSwitches", true);
|
||||||
this.config_claims_lockWoodenDoors = config.getBoolean("GriefPrevention.Claims.LockWoodenDoors", false);
|
this.config_claims_lockWoodenDoors = config.getBoolean("GriefPrevention.Claims.LockWoodenDoors", false);
|
||||||
this.config_claims_lockTrapDoors = config.getBoolean("GriefPrevention.Claims.LockTrapDoors", false);
|
this.config_claims_lockTrapDoors = config.getBoolean("GriefPrevention.Claims.LockTrapDoors", false);
|
||||||
|
|
@ -487,9 +486,6 @@ public class GriefPrevention extends JavaPlugin
|
||||||
this.config_pvp_allowCombatItemDrop = config.getBoolean("GriefPrevention.PvP.AllowCombatItemDrop", false);
|
this.config_pvp_allowCombatItemDrop = config.getBoolean("GriefPrevention.PvP.AllowCombatItemDrop", false);
|
||||||
String bannedPvPCommandsList = config.getString("GriefPrevention.PvP.BlockedSlashCommands", "/home;/vanish;/spawn;/tpa");
|
String bannedPvPCommandsList = config.getString("GriefPrevention.PvP.BlockedSlashCommands", "/home;/vanish;/spawn;/tpa");
|
||||||
|
|
||||||
this.config_trees_removeFloatingTreetops = config.getBoolean("GriefPrevention.Trees.RemoveFloatingTreetops", true);
|
|
||||||
this.config_trees_regrowGriefedTrees = config.getBoolean("GriefPrevention.Trees.RegrowGriefedTrees", true);
|
|
||||||
|
|
||||||
this.config_economy_claimBlocksPurchaseCost = config.getDouble("GriefPrevention.Economy.ClaimBlocksPurchaseCost", 0);
|
this.config_economy_claimBlocksPurchaseCost = config.getDouble("GriefPrevention.Economy.ClaimBlocksPurchaseCost", 0);
|
||||||
this.config_economy_claimBlocksSellValue = config.getDouble("GriefPrevention.Economy.ClaimBlocksSellValue", 0);
|
this.config_economy_claimBlocksSellValue = config.getDouble("GriefPrevention.Economy.ClaimBlocksSellValue", 0);
|
||||||
|
|
||||||
|
|
@ -704,6 +700,7 @@ public class GriefPrevention extends JavaPlugin
|
||||||
outConfig.set("GriefPrevention.Claims.LockTrapDoors", this.config_claims_lockTrapDoors);
|
outConfig.set("GriefPrevention.Claims.LockTrapDoors", this.config_claims_lockTrapDoors);
|
||||||
outConfig.set("GriefPrevention.Claims.LockFenceGates", this.config_claims_lockFenceGates);
|
outConfig.set("GriefPrevention.Claims.LockFenceGates", this.config_claims_lockFenceGates);
|
||||||
outConfig.set("GriefPrevention.Claims.EnderPearlsRequireAccessTrust", this.config_claims_enderPearlsRequireAccessTrust);
|
outConfig.set("GriefPrevention.Claims.EnderPearlsRequireAccessTrust", this.config_claims_enderPearlsRequireAccessTrust);
|
||||||
|
outConfig.set("GriefPrevention.Claims.ProtectFires", this.config_claims_protectFires);
|
||||||
outConfig.set("GriefPrevention.Claims.InitialBlocks", this.config_claims_initialBlocks);
|
outConfig.set("GriefPrevention.Claims.InitialBlocks", this.config_claims_initialBlocks);
|
||||||
outConfig.set("GriefPrevention.Claims.BlocksAccruedPerHour", this.config_claims_blocksAccruedPerHour);
|
outConfig.set("GriefPrevention.Claims.BlocksAccruedPerHour", this.config_claims_blocksAccruedPerHour);
|
||||||
outConfig.set("GriefPrevention.Claims.MaxAccruedBlocks", this.config_claims_maxAccruedBlocks);
|
outConfig.set("GriefPrevention.Claims.MaxAccruedBlocks", this.config_claims_maxAccruedBlocks);
|
||||||
|
|
@ -737,9 +734,6 @@ public class GriefPrevention extends JavaPlugin
|
||||||
outConfig.set("GriefPrevention.PvP.ProtectPlayersInLandClaims.PlayerOwnedClaims", this.config_pvp_noCombatInPlayerLandClaims);
|
outConfig.set("GriefPrevention.PvP.ProtectPlayersInLandClaims.PlayerOwnedClaims", this.config_pvp_noCombatInPlayerLandClaims);
|
||||||
outConfig.set("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeClaims", this.config_pvp_noCombatInAdminLandClaims);
|
outConfig.set("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeClaims", this.config_pvp_noCombatInAdminLandClaims);
|
||||||
|
|
||||||
outConfig.set("GriefPrevention.Trees.RemoveFloatingTreetops", this.config_trees_removeFloatingTreetops);
|
|
||||||
outConfig.set("GriefPrevention.Trees.RegrowGriefedTrees", this.config_trees_regrowGriefedTrees);
|
|
||||||
|
|
||||||
outConfig.set("GriefPrevention.Economy.ClaimBlocksPurchaseCost", this.config_economy_claimBlocksPurchaseCost);
|
outConfig.set("GriefPrevention.Economy.ClaimBlocksPurchaseCost", this.config_economy_claimBlocksPurchaseCost);
|
||||||
outConfig.set("GriefPrevention.Economy.ClaimBlocksSellValue", this.config_economy_claimBlocksSellValue);
|
outConfig.set("GriefPrevention.Economy.ClaimBlocksSellValue", this.config_economy_claimBlocksSellValue);
|
||||||
|
|
||||||
|
|
@ -2360,198 +2354,6 @@ public class GriefPrevention extends JavaPlugin
|
||||||
return this.config_siege_enabledWorlds.contains(world);
|
return this.config_siege_enabledWorlds.contains(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
//processes broken log blocks to automatically remove floating treetops
|
|
||||||
void handleLogBroken(Block block)
|
|
||||||
{
|
|
||||||
//find the lowest log in the tree trunk including this log
|
|
||||||
Block rootBlock = this.getRootBlock(block);
|
|
||||||
|
|
||||||
//null indicates this block isn't part of a tree trunk
|
|
||||||
if(rootBlock == null) return;
|
|
||||||
|
|
||||||
//next step: scan for other log blocks and leaves in this tree
|
|
||||||
|
|
||||||
//set boundaries for the scan
|
|
||||||
int min_x = rootBlock.getX() - GriefPrevention.TREE_RADIUS;
|
|
||||||
int max_x = rootBlock.getX() + GriefPrevention.TREE_RADIUS;
|
|
||||||
int min_z = rootBlock.getZ() - GriefPrevention.TREE_RADIUS;
|
|
||||||
int max_z = rootBlock.getZ() + GriefPrevention.TREE_RADIUS;
|
|
||||||
int max_y = rootBlock.getWorld().getMaxHeight() - 1;
|
|
||||||
|
|
||||||
//keep track of all the examined blocks, and all the log blocks found
|
|
||||||
ArrayList<Block> examinedBlocks = new ArrayList<Block>();
|
|
||||||
ArrayList<Block> treeBlocks = new ArrayList<Block>();
|
|
||||||
|
|
||||||
//queue the first block, which is the block immediately above the player-chopped block
|
|
||||||
ConcurrentLinkedQueue<Block> blocksToExamine = new ConcurrentLinkedQueue<Block>();
|
|
||||||
blocksToExamine.add(rootBlock);
|
|
||||||
examinedBlocks.add(rootBlock);
|
|
||||||
|
|
||||||
boolean hasLeaves = false;
|
|
||||||
|
|
||||||
while(!blocksToExamine.isEmpty())
|
|
||||||
{
|
|
||||||
//pop a block from the queue
|
|
||||||
Block currentBlock = blocksToExamine.remove();
|
|
||||||
|
|
||||||
//if this is a log block, determine whether it should be chopped
|
|
||||||
if(currentBlock.getType() == Material.LOG)
|
|
||||||
{
|
|
||||||
boolean partOfTree = false;
|
|
||||||
|
|
||||||
//if it's stacked with the original chopped block, the answer is always yes
|
|
||||||
if(currentBlock.getX() == block.getX() && currentBlock.getZ() == block.getZ())
|
|
||||||
{
|
|
||||||
partOfTree = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//otherwise find the block underneath this stack of logs
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Block downBlock = currentBlock.getRelative(BlockFace.DOWN);
|
|
||||||
while(downBlock.getType() == Material.LOG)
|
|
||||||
{
|
|
||||||
downBlock = downBlock.getRelative(BlockFace.DOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if it's air or leaves, it's okay to chop this block
|
|
||||||
//this avoids accidentally chopping neighboring trees which are close enough to touch their leaves to ours
|
|
||||||
if(downBlock.getType() == Material.AIR || downBlock.getType() == Material.LEAVES)
|
|
||||||
{
|
|
||||||
partOfTree = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//otherwise this is a stack of logs which touches a solid surface
|
|
||||||
//if it's close to the original block's stack, don't clean up this tree (just stop here)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(Math.abs(downBlock.getX() - block.getX()) <= 1 && Math.abs(downBlock.getZ() - block.getZ()) <= 1) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(partOfTree)
|
|
||||||
{
|
|
||||||
treeBlocks.add(currentBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if this block is a log OR a leaf block, also check its neighbors
|
|
||||||
if(currentBlock.getType() == Material.LOG || currentBlock.getType() == Material.LEAVES)
|
|
||||||
{
|
|
||||||
if(currentBlock.getType() == Material.LEAVES)
|
|
||||||
{
|
|
||||||
hasLeaves = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Block [] neighboringBlocks = new Block []
|
|
||||||
{
|
|
||||||
currentBlock.getRelative(BlockFace.EAST),
|
|
||||||
currentBlock.getRelative(BlockFace.WEST),
|
|
||||||
currentBlock.getRelative(BlockFace.NORTH),
|
|
||||||
currentBlock.getRelative(BlockFace.SOUTH),
|
|
||||||
currentBlock.getRelative(BlockFace.UP),
|
|
||||||
currentBlock.getRelative(BlockFace.DOWN)
|
|
||||||
};
|
|
||||||
|
|
||||||
for(int i = 0; i < neighboringBlocks.length; i++)
|
|
||||||
{
|
|
||||||
Block neighboringBlock = neighboringBlocks[i];
|
|
||||||
|
|
||||||
//if the neighboringBlock is out of bounds, skip it
|
|
||||||
if(neighboringBlock.getX() < min_x || neighboringBlock.getX() > max_x || neighboringBlock.getZ() < min_z || neighboringBlock.getZ() > max_z || neighboringBlock.getY() > max_y) continue;
|
|
||||||
|
|
||||||
//if we already saw this block, skip it
|
|
||||||
if(examinedBlocks.contains(neighboringBlock)) continue;
|
|
||||||
|
|
||||||
//mark the block as examined
|
|
||||||
examinedBlocks.add(neighboringBlock);
|
|
||||||
|
|
||||||
//if the neighboringBlock is a leaf or log, put it in the queue to be examined later
|
|
||||||
if(neighboringBlock.getType() == Material.LOG || neighboringBlock.getType() == Material.LEAVES)
|
|
||||||
{
|
|
||||||
blocksToExamine.add(neighboringBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if we encounter any player-placed block type, bail out (don't automatically remove parts of this tree, it might support a treehouse!)
|
|
||||||
else if(this.isPlayerBlock(neighboringBlock))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if it doesn't have leaves, it's not a tree, so don't clean it up
|
|
||||||
if(hasLeaves)
|
|
||||||
{
|
|
||||||
//schedule a cleanup task for later, in case the player leaves part of this tree hanging in the air
|
|
||||||
TreeCleanupTask cleanupTask = new TreeCleanupTask(block, rootBlock, treeBlocks, rootBlock.getData());
|
|
||||||
|
|
||||||
//20L ~ 1 second, so 2 mins = 120 seconds ~ 2400L
|
|
||||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, cleanupTask, 2400L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//helper for above, finds the "root" of a stack of logs
|
|
||||||
//will return null if the stack is determined to not be a natural tree
|
|
||||||
private Block getRootBlock(Block logBlock)
|
|
||||||
{
|
|
||||||
if(logBlock.getType() != Material.LOG) return null;
|
|
||||||
|
|
||||||
//run down through log blocks until finding a non-log block
|
|
||||||
Block underBlock = logBlock.getRelative(BlockFace.DOWN);
|
|
||||||
while(underBlock.getType() == Material.LOG)
|
|
||||||
{
|
|
||||||
underBlock = underBlock.getRelative(BlockFace.DOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if this is a standard tree, that block MUST be dirt
|
|
||||||
if(underBlock.getType() != Material.DIRT) return null;
|
|
||||||
|
|
||||||
//run up through log blocks until finding a non-log block
|
|
||||||
Block aboveBlock = logBlock.getRelative(BlockFace.UP);
|
|
||||||
while(aboveBlock.getType() == Material.LOG)
|
|
||||||
{
|
|
||||||
aboveBlock = aboveBlock.getRelative(BlockFace.UP);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if this is a standard tree, that block MUST be air or leaves
|
|
||||||
if(aboveBlock.getType() != Material.AIR && aboveBlock.getType() != Material.LEAVES) return null;
|
|
||||||
|
|
||||||
return underBlock.getRelative(BlockFace.UP);
|
|
||||||
}
|
|
||||||
|
|
||||||
//for sake of identifying trees ONLY, a cheap but not 100% reliable method for identifying player-placed blocks
|
|
||||||
private boolean isPlayerBlock(Block block)
|
|
||||||
{
|
|
||||||
Material material = block.getType();
|
|
||||||
|
|
||||||
//list of natural blocks which are OK to have next to a log block in a natural tree setting
|
|
||||||
if( material == Material.AIR ||
|
|
||||||
material == Material.LEAVES ||
|
|
||||||
material == Material.LOG ||
|
|
||||||
material == Material.DIRT ||
|
|
||||||
material == Material.GRASS ||
|
|
||||||
material == Material.STATIONARY_WATER ||
|
|
||||||
material == Material.BROWN_MUSHROOM ||
|
|
||||||
material == Material.RED_MUSHROOM ||
|
|
||||||
material == Material.RED_ROSE ||
|
|
||||||
material == Material.LONG_GRASS ||
|
|
||||||
material == Material.SNOW ||
|
|
||||||
material == Material.STONE ||
|
|
||||||
material == Material.VINE ||
|
|
||||||
material == Material.WATER_LILY ||
|
|
||||||
material == Material.YELLOW_FLOWER ||
|
|
||||||
material == Material.CLAY)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//moves a player from the claim he's in to a nearby wilderness location
|
//moves a player from the claim he's in to a nearby wilderness location
|
||||||
public Location ejectPlayer(Player player)
|
public Location ejectPlayer(Player player)
|
||||||
{
|
{
|
||||||
|
|
@ -2677,7 +2479,7 @@ public class GriefPrevention extends JavaPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String allowBreak(Player player, Location location)
|
public String allowBreak(Player player, Block block, Location location)
|
||||||
{
|
{
|
||||||
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||||
Claim claim = this.dataStore.getClaimAt(location, false, playerData.lastClaim);
|
Claim claim = this.dataStore.getClaimAt(location, false, playerData.lastClaim);
|
||||||
|
|
@ -2709,7 +2511,7 @@ public class GriefPrevention extends JavaPlugin
|
||||||
playerData.lastClaim = claim;
|
playerData.lastClaim = claim;
|
||||||
|
|
||||||
//if not in the wilderness, then apply claim rules (permissions, etc)
|
//if not in the wilderness, then apply claim rules (permissions, etc)
|
||||||
return claim.allowBreak(player, location.getBlock().getType());
|
return claim.allowBreak(player, block.getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1122,7 +1122,7 @@ class PlayerEventHandler implements Listener
|
||||||
if(!this.onLeftClickWatchList(clickedBlockType) && !GriefPrevention.instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getTypeId(), clickedBlock.getData(), null)))
|
if(!this.onLeftClickWatchList(clickedBlockType) && !GriefPrevention.instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getTypeId(), clickedBlock.getData(), null)))
|
||||||
{
|
{
|
||||||
//and an exception for putting our fires
|
//and an exception for putting our fires
|
||||||
if(clickedBlockType == Material.NETHERRACK && event.getClickedBlock() != null && event.getClickedBlock().getRelative(event.getBlockFace()).getType() == Material.FIRE)
|
if(GriefPrevention.instance.config_claims_protectFires && event.getClickedBlock() != null && event.getClickedBlock().getRelative(event.getBlockFace()).getType() == Material.FIRE)
|
||||||
{
|
{
|
||||||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
|
||||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||||
|
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
/*
|
|
||||||
GriefPrevention Server Plugin for Minecraft
|
|
||||||
Copyright (C) 2012 Ryan Hamshire
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package me.ryanhamshire.GriefPrevention;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
|
|
||||||
//FEATURE: treetops left unnaturally hanging will be automatically cleaned up
|
|
||||||
|
|
||||||
//this main thread task revisits the location of a partially chopped tree from several minutes ago
|
|
||||||
//if any part of the tree is still there and nothing else has been built in its place, remove the remaining parts
|
|
||||||
class TreeCleanupTask implements Runnable
|
|
||||||
{
|
|
||||||
private Block originalChoppedBlock; //first block chopped in the tree
|
|
||||||
private Block originalRootBlock; //where the root of the tree used to be
|
|
||||||
private byte originalRootBlockData; //data value of that root block (TYPE of log)
|
|
||||||
private ArrayList<Block> originalTreeBlocks; //a list of other log blocks determined to be part of this tree
|
|
||||||
|
|
||||||
public TreeCleanupTask(Block originalChoppedBlock, Block originalRootBlock, ArrayList<Block> originalTreeBlocks, byte originalRootBlockData)
|
|
||||||
{
|
|
||||||
this.originalChoppedBlock = originalChoppedBlock;
|
|
||||||
this.originalRootBlock = originalRootBlock;
|
|
||||||
this.originalTreeBlocks = originalTreeBlocks;
|
|
||||||
this.originalRootBlockData = originalRootBlockData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
//if this chunk is no longer loaded, load it and come back in a few seconds
|
|
||||||
Chunk chunk = this.originalChoppedBlock.getWorld().getChunkAt(this.originalChoppedBlock);
|
|
||||||
if(!chunk.isLoaded())
|
|
||||||
{
|
|
||||||
chunk.load();
|
|
||||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, this, 100L);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if the block originally chopped has been replaced with anything but air, something has been built (or has grown here)
|
|
||||||
//in that case, don't do any cleanup
|
|
||||||
if(this.originalChoppedBlock.getWorld().getBlockAt(this.originalChoppedBlock.getLocation()).getType() != Material.AIR) return;
|
|
||||||
|
|
||||||
//scan the original tree block locations to see if any of them have been replaced
|
|
||||||
for(int i = 0; i < this.originalTreeBlocks.size(); i++)
|
|
||||||
{
|
|
||||||
Location location = this.originalTreeBlocks.get(i).getLocation();
|
|
||||||
Block currentBlock = location.getBlock();
|
|
||||||
|
|
||||||
//if the block has been replaced, stop here, we won't do any cleanup
|
|
||||||
if(currentBlock.getType() != Material.LOG && currentBlock.getType() != Material.AIR)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//otherwise scan again, this time removing any remaining log blocks
|
|
||||||
boolean logsRemaining = false;
|
|
||||||
for(int i = 0; i < this.originalTreeBlocks.size(); i++)
|
|
||||||
{
|
|
||||||
Location location = this.originalTreeBlocks.get(i).getLocation();
|
|
||||||
Block currentBlock = location.getBlock();
|
|
||||||
if(currentBlock.getType() == Material.LOG)
|
|
||||||
{
|
|
||||||
logsRemaining = true;
|
|
||||||
currentBlock.setType(Material.AIR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if any were actually removed and we're set to automatically replant griefed trees, place a sapling where the root block was previously
|
|
||||||
if(logsRemaining && GriefPrevention.instance.config_trees_regrowGriefedTrees)
|
|
||||||
{
|
|
||||||
Block currentBlock = this.originalRootBlock.getLocation().getBlock();
|
|
||||||
//make sure there's grass or dirt underneath
|
|
||||||
if(currentBlock.getType() == Material.AIR && (currentBlock.getRelative(BlockFace.DOWN).getType() == Material.DIRT || currentBlock.getRelative(BlockFace.DOWN).getType() == Material.GRASS))
|
|
||||||
{
|
|
||||||
currentBlock.setType(Material.SAPLING);
|
|
||||||
currentBlock.setData(this.originalRootBlockData); //makes the sapling type match the original tree type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user