The 1.13 PR (#320)

- Removes all code and config pertaining to the "mods" config section

- RestoreNature has issues in oceans
This commit is contained in:
zedwick 2018-08-13 14:53:14 +01:00 committed by RoboMWM
parent ad07915664
commit 19c0f3220f
15 changed files with 689 additions and 453 deletions

View File

@ -61,7 +61,7 @@
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId> <artifactId>bukkit</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version> <version>1.13-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!--Worldguard dependency--> <!--Worldguard dependency-->

View File

@ -84,14 +84,14 @@ class AutoExtendClaimTask implements Runnable
{ {
for(int z = 0; z < 16; z++) for(int z = 0; z < 16; z++)
{ {
int blockType = chunk.getBlockTypeId(x, y, z); Material blockType = chunk.getBlockType(x, y, z);
while(!this.yTooSmall(y) && playerBlockIDs.contains(Material.getMaterial(blockType))) while(!this.yTooSmall(y) && playerBlockIDs.contains(blockType))
{ {
ychanged = true; ychanged = true;
blockType = chunk.getBlockTypeId(x, --y, z); blockType = chunk.getBlockType(x, --y, z);
} }
if(this.yTooSmall(y)) return y; if(this.yTooSmall(y)) return y;
} }
} }
} }

View File

@ -25,6 +25,7 @@ import java.util.List;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
@ -74,11 +75,16 @@ public class BlockEventHandler implements Listener
this.trashBlocks.add(Material.COBBLESTONE); this.trashBlocks.add(Material.COBBLESTONE);
this.trashBlocks.add(Material.TORCH); this.trashBlocks.add(Material.TORCH);
this.trashBlocks.add(Material.DIRT); this.trashBlocks.add(Material.DIRT);
this.trashBlocks.add(Material.SAPLING); this.trashBlocks.add(Material.OAK_SAPLING);
this.trashBlocks.add(Material.SPRUCE_SAPLING);
this.trashBlocks.add(Material.BIRCH_SAPLING);
this.trashBlocks.add(Material.JUNGLE_SAPLING);
this.trashBlocks.add(Material.ACACIA_SAPLING);
this.trashBlocks.add(Material.DARK_OAK_SAPLING);
this.trashBlocks.add(Material.GRAVEL); this.trashBlocks.add(Material.GRAVEL);
this.trashBlocks.add(Material.SAND); this.trashBlocks.add(Material.SAND);
this.trashBlocks.add(Material.TNT); this.trashBlocks.add(Material.TNT);
this.trashBlocks.add(Material.WORKBENCH); this.trashBlocks.add(Material.CRAFTING_TABLE);
} }
//when a player breaks a block... //when a player breaks a block...
@ -319,7 +325,7 @@ public class BlockEventHandler implements Listener
} }
//FEATURE: limit wilderness tree planting to grass, or dirt with more blocks beneath it //FEATURE: limit wilderness tree planting to grass, or dirt with more blocks beneath it
else if(block.getType() == Material.SAPLING && GriefPrevention.instance.config_blockSkyTrees && GriefPrevention.instance.claimsEnabledForWorld(player.getWorld())) else if(Tag.SAPLINGS.isTagged(block.getType()) && GriefPrevention.instance.config_blockSkyTrees && GriefPrevention.instance.claimsEnabledForWorld(player.getWorld()))
{ {
Block earthBlock = placeEvent.getBlockAgainst(); Block earthBlock = placeEvent.getBlockAgainst();
if(earthBlock.getType() != Material.GRASS) if(earthBlock.getType() != Material.GRASS)
@ -375,7 +381,7 @@ public class BlockEventHandler implements Listener
//warn players about disabled pistons outside of land claims //warn players about disabled pistons outside of land claims
if( GriefPrevention.instance.config_pistonsInClaimsOnly && if( GriefPrevention.instance.config_pistonsInClaimsOnly &&
(block.getType() == Material.PISTON_BASE || block.getType() == Material.PISTON_STICKY_BASE) && (block.getType() == Material.PISTON || block.getType() == Material.STICKY_PISTON) &&
claim == null ) claim == null )
{ {
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoPistonsOutsideClaims); GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoPistonsOutsideClaims);
@ -406,7 +412,7 @@ public class BlockEventHandler implements Listener
static boolean isActiveBlock(Material type) static boolean isActiveBlock(Material type)
{ {
if(type == Material.HOPPER || type == Material.BEACON || type == Material.MOB_SPAWNER) return true; if(type == Material.HOPPER || type == Material.BEACON || type == Material.SPAWNER) return true;
return false; return false;
} }
@ -589,7 +595,7 @@ public class BlockEventHandler implements Listener
{ {
event.setCancelled(true); event.setCancelled(true);
block.getWorld().createExplosion(block.getLocation(), 0); block.getWorld().createExplosion(block.getLocation(), 0);
block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.PISTON_STICKY_BASE)); block.getWorld().dropItem(block.getLocation(), new ItemStack(Material.STICKY_PISTON));
block.setType(Material.AIR); block.setType(Material.AIR);
return; return;
} }
@ -656,10 +662,10 @@ public class BlockEventHandler implements Listener
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
public void onBlockBurn (BlockBurnEvent burnEvent) public void onBlockBurn (BlockBurnEvent burnEvent)
{ {
//don't track in worlds where claims are not enabled //don't track in worlds where claims are not enabled
if(!GriefPrevention.instance.claimsEnabledForWorld(burnEvent.getBlock().getWorld())) return; if(!GriefPrevention.instance.claimsEnabledForWorld(burnEvent.getBlock().getWorld())) return;
if(!GriefPrevention.instance.config_fireDestroys) if(!GriefPrevention.instance.config_fireDestroys)
{ {
burnEvent.setCancelled(true); burnEvent.setCancelled(true);
Block block = burnEvent.getBlock(); Block block = burnEvent.getBlock();
@ -736,7 +742,7 @@ public class BlockEventHandler implements Listener
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onForm(BlockFormEvent event) public void onForm(BlockFormEvent event)
{ {
Block block = event.getBlock(); Block block = event.getBlock();
Location location = block.getLocation(); Location location = block.getLocation();
@ -744,7 +750,7 @@ public class BlockEventHandler implements Listener
if(GriefPrevention.instance.creativeRulesApply(location)) if(GriefPrevention.instance.creativeRulesApply(location))
{ {
Material type = block.getType(); Material type = block.getType();
if(type == Material.COBBLESTONE || type == Material.OBSIDIAN || type == Material.STATIONARY_LAVA || type == Material.STATIONARY_WATER) if(type == Material.COBBLESTONE || type == Material.OBSIDIAN || type == Material.LAVA || type == Material.WATER)
{ {
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(location, false, null); Claim claim = GriefPrevention.instance.dataStore.getClaimAt(location, false, null);
if(claim == null) if(claim == null)

View File

@ -20,6 +20,7 @@ package me.ryanhamshire.GriefPrevention;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
//basically, just a few data points from a block conveniently encapsulated in a class //basically, just a few data points from a block conveniently encapsulated in a class
//this is used only by the RestoreNature code //this is used only by the RestoreNature code
@ -27,9 +28,9 @@ public class BlockSnapshot
{ {
public Location location; public Location location;
public Material typeId; public Material typeId;
public byte data; public BlockData data;
public BlockSnapshot(Location location, Material typeId, byte data) public BlockSnapshot(Location location, Material typeId, BlockData data)
{ {
this.location = location; this.location = location;
this.typeId = typeId; this.typeId = typeId;

View File

@ -145,7 +145,7 @@ public class Claim
Block block = lesser.getWorld().getBlockAt(x, y, z); Block block = lesser.getWorld().getBlockAt(x, y, z);
if(exclusionClaim != null && exclusionClaim.contains(block.getLocation(), true, false)) continue; if(exclusionClaim != null && exclusionClaim.contains(block.getLocation(), true, false)) continue;
if(block.getType() == Material.STATIONARY_LAVA || block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER || block.getType() == Material.LAVA) if(block.getType() == Material.LAVA || block.getType() == Material.WATER)
{ {
block.setType(Material.AIR); block.setType(Material.AIR);
} }
@ -178,7 +178,7 @@ public class Claim
//dodge the exclusion claim //dodge the exclusion claim
Block block = lesser.getWorld().getBlockAt(x, y, z); Block block = lesser.getWorld().getBlockAt(x, y, z);
if(block.getType() == Material.STATIONARY_LAVA || block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER || block.getType() == Material.LAVA) if(block.getType() == Material.WATER || block.getType() == Material.LAVA)
{ {
return true; return true;
} }
@ -334,12 +334,12 @@ public class Claim
private List<Material> placeableFarmingBlocksList = Arrays.asList( private List<Material> placeableFarmingBlocksList = Arrays.asList(
Material.PUMPKIN_STEM, Material.PUMPKIN_STEM,
Material.CROPS, Material.WHEAT,
Material.MELON_STEM, Material.MELON_STEM,
Material.CARROT, Material.CARROT,
Material.POTATO, Material.POTATO,
Material.NETHER_WARTS, Material.NETHER_WART,
Material.BEETROOT_BLOCK); Material.BEETROOT);
private boolean placeableForFarming(Material material) private boolean placeableForFarming(Material material)
{ {
@ -385,14 +385,14 @@ public class Claim
if(ClaimPermission.Build == permissionLevel) return null; if(ClaimPermission.Build == permissionLevel) return null;
//allow for farming with /containertrust permission //allow for farming with /containertrust permission
if(this.allowContainers(player) == null) if(this.allowContainers(player) == null)
{ {
//do allow for farming, if player has /containertrust permission //do allow for farming, if player has /containertrust permission
if(this.placeableForFarming(material)) if(this.placeableForFarming(material))
{ {
return null; return null;
} }
} }
//subdivision permission inheritance //subdivision permission inheritance
if(this.parent != null) if(this.parent != null)
@ -913,7 +913,7 @@ public class Claim
{ {
score += 10; score += 10;
} }
else if(creativeMode && (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA)) else if(creativeMode && (block.getType() == Material.LAVA))
{ {
score -= 10; score -= 10;
} }

View File

@ -92,7 +92,7 @@ class EntityCleanupTask implements Runnable
else else
{ {
Material material = world.getBlockAt(vehicle.getLocation()).getType(); Material material = world.getBlockAt(vehicle.getLocation()).getType();
if(material != Material.RAILS && material != Material.POWERED_RAIL && material != Material.DETECTOR_RAIL) if(material != Material.RAIL && material != Material.POWERED_RAIL && material != Material.DETECTOR_RAIL)
{ {
remove = true; remove = true;
} }

View File

@ -133,33 +133,33 @@ public class EntityEventHandler implements Listener
} }
else if(!GriefPrevention.instance.config_rabbitsEatCrops && event.getEntityType() == EntityType.RABBIT) else if(!GriefPrevention.instance.config_rabbitsEatCrops && event.getEntityType() == EntityType.RABBIT)
{ {
event.setCancelled(true); event.setCancelled(true);
} else if(event.getEntityType() == EntityType.WITHER && GriefPrevention.instance.config_claims_worldModes.get(event.getBlock().getWorld()) != ClaimsMode.Disabled) } else if(event.getEntityType() == EntityType.WITHER && GriefPrevention.instance.config_claims_worldModes.get(event.getBlock().getWorld()) != ClaimsMode.Disabled)
{ {
Claim claim = this.dataStore.getClaimAt(event.getBlock().getLocation(), false, null); Claim claim = this.dataStore.getClaimAt(event.getBlock().getLocation(), false, null);
if(claim == null || !claim.areExplosivesAllowed || !GriefPrevention.instance.config_blockClaimExplosions) if(claim == null || !claim.areExplosivesAllowed || !GriefPrevention.instance.config_blockClaimExplosions)
{ {
event.setCancelled(true); event.setCancelled(true);
} }
} }
//don't allow crops to be trampled, except by a player with build permission //don't allow crops to be trampled, except by a player with build permission
else if(event.getTo() == Material.DIRT && event.getBlock().getType() == Material.SOIL) else if(event.getTo() == Material.DIRT && event.getBlock().getType() == Material.FARMLAND)
{ {
if(event.getEntityType() != EntityType.PLAYER) if(event.getEntityType() != EntityType.PLAYER)
{ {
event.setCancelled(true); event.setCancelled(true);
} }
else else
{ {
Player player = (Player)event.getEntity(); Player player = (Player)event.getEntity();
Block block = event.getBlock(); Block block = event.getBlock();
if(GriefPrevention.instance.allowBreak(player, block, block.getLocation()) != null) if(GriefPrevention.instance.allowBreak(player, block, block.getLocation()) != null)
{ {
event.setCancelled(true); event.setCancelled(true);
} }
} }
} }
//sand cannon fix - when the falling block doesn't fall straight down, take additional anti-grief steps //sand cannon fix - when the falling block doesn't fall straight down, take additional anti-grief steps
@ -201,7 +201,7 @@ public class EntityEventHandler implements Listener
//when not allowed, drop as item instead of forming a block //when not allowed, drop as item instead of forming a block
event.setCancelled(true); event.setCancelled(true);
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
ItemStack itemStack = new ItemStack(entity.getMaterial(), 1, entity.getBlockData()); ItemStack itemStack = new ItemStack(entity.getMaterial(), 1);
Item item = block.getWorld().dropItem(entity.getLocation(), itemStack); Item item = block.getWorld().dropItem(entity.getLocation(), itemStack);
item.setVelocity(new Vector()); item.setVelocity(new Vector());
} }
@ -244,20 +244,20 @@ public class EntityEventHandler implements Listener
public void onEntityInteract(EntityInteractEvent event) public void onEntityInteract(EntityInteractEvent event)
{ {
Material material = event.getBlock().getType(); Material material = event.getBlock().getType();
if(material == Material.SOIL) if(material == Material.FARMLAND)
{ {
if(!GriefPrevention.instance.config_creaturesTrampleCrops) if(!GriefPrevention.instance.config_creaturesTrampleCrops)
{ {
event.setCancelled(true); event.setCancelled(true);
} }
else else
{ {
Entity rider = event.getEntity().getPassenger(); Entity rider = event.getEntity().getPassenger();
if(rider != null && rider.getType() == EntityType.PLAYER) if(rider != null && rider.getType() == EntityType.PLAYER)
{ {
event.setCancelled(true); event.setCancelled(true);
} }
} }
} }
} }
@ -294,7 +294,6 @@ public class EntityEventHandler implements Listener
for(int i = 0; i < blocks.size(); i++) for(int i = 0; i < blocks.size(); i++)
{ {
Block block = blocks.get(i); Block block = blocks.get(i);
if(GriefPrevention.instance.config_mods_explodableIds.Contains(new MaterialInfo(block.getType(), block.getData(), null))) continue;
blocks.remove(i--); blocks.remove(i--);
} }
@ -312,13 +311,6 @@ public class EntityEventHandler implements Listener
//always ignore air blocks //always ignore air blocks
if(block.getType() == Material.AIR) continue; if(block.getType() == Material.AIR) continue;
//always allow certain block types to explode
if(GriefPrevention.instance.config_mods_explodableIds.Contains(new MaterialInfo(block.getType(), block.getData(), null)))
{
explodedBlocks.add(block);
continue;
}
//is it in a land claim? //is it in a land claim?
Claim claim = this.dataStore.getClaimAt(block.getLocation(), false, cachedClaim); Claim claim = this.dataStore.getClaimAt(block.getLocation(), false, cachedClaim);
if(claim != null) if(claim != null)

View File

@ -189,11 +189,6 @@ public class GriefPrevention extends JavaPlugin
public int config_ipLimit; //how many players can share an IP address public int config_ipLimit; //how many players can share an IP address
public boolean config_trollFilterEnabled; //whether to auto-mute new players who use banned words right after joining public boolean config_trollFilterEnabled; //whether to auto-mute new players who use banned words right after joining
public MaterialCollection config_mods_accessTrustIds; //list of block IDs which should require /accesstrust for player interaction
public MaterialCollection config_mods_containerTrustIds; //list of block IDs which should require /containertrust for player interaction
public List<String> config_mods_ignoreClaimsAccounts; //list of player names which ALWAYS ignore claims
public MaterialCollection config_mods_explodableIds; //list of block IDs which can be destroyed by explosions, even in claimed areas
public HashMap<String, Integer> config_seaLevelOverride; //override for sea level, because bukkit doesn't report the right value for all situations public HashMap<String, Integer> config_seaLevelOverride; //override for sea level, because bukkit doesn't report the right value for all situations
@ -622,33 +617,6 @@ public class GriefPrevention extends JavaPlugin
this.config_ban_useCommand = config.getBoolean("GriefPrevention.UseBanCommand", false); this.config_ban_useCommand = config.getBoolean("GriefPrevention.UseBanCommand", false);
this.config_ban_commandFormat = config.getString("GriefPrevention.BanCommandPattern", "ban %name% %reason%"); this.config_ban_commandFormat = config.getString("GriefPrevention.BanCommandPattern", "ban %name% %reason%");
this.config_mods_ignoreClaimsAccounts = config.getStringList("GriefPrevention.Mods.PlayersIgnoringAllClaims");
if(this.config_mods_ignoreClaimsAccounts == null) this.config_mods_ignoreClaimsAccounts = new ArrayList<String>();
this.config_mods_accessTrustIds = new MaterialCollection();
List<String> accessTrustStrings = config.getStringList("GriefPrevention.Mods.BlockIdsRequiringAccessTrust");
this.parseMaterialListFromConfig(accessTrustStrings, this.config_mods_accessTrustIds);
this.config_mods_containerTrustIds = new MaterialCollection();
List<String> containerTrustStrings = config.getStringList("GriefPrevention.Mods.BlockIdsRequiringContainerTrust");
//default values for container trust mod blocks
if(containerTrustStrings == null || containerTrustStrings.size() == 0)
{
// containerTrustStrings.add(new MaterialInfo(99999, "Example - ID 99999, all data values.").toString());
}
//parse the strings from the config file
this.parseMaterialListFromConfig(containerTrustStrings, this.config_mods_containerTrustIds);
this.config_mods_explodableIds = new MaterialCollection();
List<String> explodableStrings = config.getStringList("GriefPrevention.Mods.BlockIdsExplodable");
//parse the strings from the config file
this.parseMaterialListFromConfig(explodableStrings, this.config_mods_explodableIds);
//default for claim investigation tool //default for claim investigation tool
String investigationToolMaterialName = Material.STICK.name(); String investigationToolMaterialName = Material.STICK.name();
@ -664,7 +632,7 @@ public class GriefPrevention extends JavaPlugin
} }
//default for claim creation/modification tool //default for claim creation/modification tool
String modificationToolMaterialName = Material.GOLD_SPADE.name(); String modificationToolMaterialName = Material.GOLDEN_SHOVEL.name();
//get modification tool from config //get modification tool from config
modificationToolMaterialName = config.getString("GriefPrevention.Claims.ModificationTool", modificationToolMaterialName); modificationToolMaterialName = config.getString("GriefPrevention.Claims.ModificationTool", modificationToolMaterialName);
@ -674,7 +642,7 @@ public class GriefPrevention extends JavaPlugin
if(this.config_claims_modificationTool == null) if(this.config_claims_modificationTool == null)
{ {
GriefPrevention.AddLogEntry("ERROR: Material " + modificationToolMaterialName + " not found. Defaulting to the golden shovel. Please update your config.yml."); GriefPrevention.AddLogEntry("ERROR: Material " + modificationToolMaterialName + " not found. Defaulting to the golden shovel. Please update your config.yml.");
this.config_claims_modificationTool = Material.GOLD_SPADE; this.config_claims_modificationTool = Material.GOLDEN_SHOVEL;
} }
//default for siege worlds list //default for siege worlds list
@ -706,15 +674,37 @@ public class GriefPrevention extends JavaPlugin
//default siege blocks //default siege blocks
this.config_siege_blocks = new ArrayList<Material>(); this.config_siege_blocks = new ArrayList<Material>();
this.config_siege_blocks.add(Material.DIRT); this.config_siege_blocks.add(Material.DIRT);
this.config_siege_blocks.add(Material.GRASS_BLOCK);
this.config_siege_blocks.add(Material.GRASS); this.config_siege_blocks.add(Material.GRASS);
this.config_siege_blocks.add(Material.LONG_GRASS); this.config_siege_blocks.add(Material.FERN);
this.config_siege_blocks.add(Material.DEAD_BUSH);
this.config_siege_blocks.add(Material.COBBLESTONE); this.config_siege_blocks.add(Material.COBBLESTONE);
this.config_siege_blocks.add(Material.GRAVEL); this.config_siege_blocks.add(Material.GRAVEL);
this.config_siege_blocks.add(Material.SAND); this.config_siege_blocks.add(Material.SAND);
this.config_siege_blocks.add(Material.GLASS); this.config_siege_blocks.add(Material.GLASS);
this.config_siege_blocks.add(Material.THIN_GLASS); this.config_siege_blocks.add(Material.GLASS_PANE);
this.config_siege_blocks.add(Material.WOOD); this.config_siege_blocks.add(Material.OAK_PLANKS);
this.config_siege_blocks.add(Material.WOOL); this.config_siege_blocks.add(Material.SPRUCE_PLANKS);
this.config_siege_blocks.add(Material.BIRCH_PLANKS);
this.config_siege_blocks.add(Material.JUNGLE_PLANKS);
this.config_siege_blocks.add(Material.ACACIA_PLANKS);
this.config_siege_blocks.add(Material.DARK_OAK_PLANKS);
this.config_siege_blocks.add(Material.WHITE_WOOL);
this.config_siege_blocks.add(Material.ORANGE_WOOL);
this.config_siege_blocks.add(Material.MAGENTA_WOOL);
this.config_siege_blocks.add(Material.LIGHT_BLUE_WOOL);
this.config_siege_blocks.add(Material.YELLOW_WOOL);
this.config_siege_blocks.add(Material.LIME_WOOL);
this.config_siege_blocks.add(Material.PINK_WOOL);
this.config_siege_blocks.add(Material.GRAY_WOOL);
this.config_siege_blocks.add(Material.LIGHT_GRAY_WOOL);
this.config_siege_blocks.add(Material.CYAN_WOOL);
this.config_siege_blocks.add(Material.PURPLE_WOOL);
this.config_siege_blocks.add(Material.BLUE_WOOL);
this.config_siege_blocks.add(Material.BROWN_WOOL);
this.config_siege_blocks.add(Material.GREEN_WOOL);
this.config_siege_blocks.add(Material.RED_WOOL);
this.config_siege_blocks.add(Material.BLACK_WOOL);
this.config_siege_blocks.add(Material.SNOW); this.config_siege_blocks.add(Material.SNOW);
//build a default config entry //build a default config entry
@ -898,14 +888,6 @@ public class GriefPrevention extends JavaPlugin
outConfig.set("GriefPrevention.UseBanCommand", this.config_ban_useCommand); outConfig.set("GriefPrevention.UseBanCommand", this.config_ban_useCommand);
outConfig.set("GriefPrevention.BanCommandPattern", this.config_ban_commandFormat); outConfig.set("GriefPrevention.BanCommandPattern", this.config_ban_commandFormat);
outConfig.set("GriefPrevention.Mods.BlockIdsRequiringAccessTrust", this.config_mods_accessTrustIds);
outConfig.set("GriefPrevention.Mods.BlockIdsRequiringContainerTrust", this.config_mods_containerTrustIds);
outConfig.set("GriefPrevention.Mods.BlockIdsExplodable", this.config_mods_explodableIds);
outConfig.set("GriefPrevention.Mods.PlayersIgnoringAllClaims", this.config_mods_ignoreClaimsAccounts);
outConfig.set("GriefPrevention.Mods.BlockIdsRequiringAccessTrust", accessTrustStrings);
outConfig.set("GriefPrevention.Mods.BlockIdsRequiringContainerTrust", containerTrustStrings);
outConfig.set("GriefPrevention.Mods.BlockIdsExplodable", explodableStrings);
outConfig.set("GriefPrevention.Advanced.fixNegativeClaimblockAmounts", this.config_advanced_fixNegativeClaimblockAmounts); outConfig.set("GriefPrevention.Advanced.fixNegativeClaimblockAmounts", this.config_advanced_fixNegativeClaimblockAmounts);
@ -3368,8 +3350,8 @@ public class GriefPrevention extends JavaPlugin
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);
//exception: administrators in ignore claims mode and special player accounts created by server mods //exception: administrators in ignore claims mode
if(playerData.ignoreClaims || GriefPrevention.instance.config_mods_ignoreClaimsAccounts.contains(player.getName())) return null; if(playerData.ignoreClaims) return null;
//wilderness rules //wilderness rules
if(claim == null) if(claim == null)
@ -3420,8 +3402,8 @@ public class GriefPrevention extends JavaPlugin
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);
//exception: administrators in ignore claims mode, and special player accounts created by server mods //exception: administrators in ignore claims mode
if(playerData.ignoreClaims || GriefPrevention.instance.config_mods_ignoreClaimsAccounts.contains(player.getName())) return null; if(playerData.ignoreClaims) return null;
//wilderness rules //wilderness rules
if(claim == null) if(claim == null)
@ -3496,7 +3478,7 @@ public class GriefPrevention extends JavaPlugin
for(int y = 0; y < snapshots[0].length; y++) for(int y = 0; y < snapshots[0].length; y++)
{ {
Block block = chunk.getWorld().getBlockAt(startLocation.getBlockX() + x, startLocation.getBlockY() + y, startLocation.getBlockZ() + z); Block block = chunk.getWorld().getBlockAt(startLocation.getBlockX() + x, startLocation.getBlockY() + y, startLocation.getBlockZ() + z);
snapshots[x][y][z] = new BlockSnapshot(block.getLocation(), block.getType(), block.getData()); snapshots[x][y][z] = new BlockSnapshot(block.getLocation(), block.getType(), block.getBlockData());
} }
} }
} }
@ -3617,7 +3599,12 @@ public class GriefPrevention extends JavaPlugin
public static boolean isNewToServer(Player player) public static boolean isNewToServer(Player player)
{ {
if(player.getStatistic(Statistic.PICKUP, Material.WOOD) > 0) return false; if( player.getStatistic(Statistic.PICKUP, Material.OAK_LOG) > 0 ||
player.getStatistic(Statistic.PICKUP, Material.SPRUCE_LOG) > 0 ||
player.getStatistic(Statistic.PICKUP, Material.BIRCH_LOG) > 0 ||
player.getStatistic(Statistic.PICKUP, Material.JUNGLE_LOG) > 0 ||
player.getStatistic(Statistic.PICKUP, Material.ACACIA_LOG) > 0 ||
player.getStatistic(Statistic.PICKUP, Material.DARK_OAK_LOG) > 0) return false;
PlayerData playerData = instance.dataStore.getPlayerData(player.getUniqueId()); PlayerData playerData = instance.dataStore.getPlayerData(player.getUniqueId());
if(playerData.getClaims().size() > 0) return false; if(playerData.getClaims().size() > 0) return false;

View File

@ -42,10 +42,12 @@ import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.Tag;
import org.bukkit.TravelAgent; import org.bukkit.TravelAgent;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Levelled;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Animals; import org.bukkit.entity.Animals;
@ -1059,11 +1061,11 @@ class PlayerEventHandler implements Listener
} }
//if creating a new portal //if creating a new portal
if(destination.getBlock().getType() != Material.PORTAL) if(destination.getBlock().getType() != Material.NETHER_PORTAL)
{ {
//check for a land claim and the player's permission that land claim //check for a land claim and the player's permission that land claim
Claim claim = this.dataStore.getClaimAt(destination, false, null); Claim claim = this.dataStore.getClaimAt(destination, false, null);
if(claim != null && claim.allowBuild(player, Material.PORTAL) != null) if(claim != null && claim.allowBuild(player, Material.NETHER_PORTAL) != null)
{ {
//cancel and inform about the reason //cancel and inform about the reason
event.setCancelled(true); event.setCancelled(true);
@ -1296,7 +1298,7 @@ class PlayerEventHandler implements Listener
} }
//if preventing theft, prevent leashing claimed creatures //if preventing theft, prevent leashing claimed creatures
if(instance.config_claims_preventTheft && entity instanceof Creature && instance.getItemInHand(player, event.getHand()).getType() == Material.LEASH) if(instance.config_claims_preventTheft && entity instanceof Creature && instance.getItemInHand(player, event.getHand()).getType() == Material.LEAD)
{ {
Claim claim = this.dataStore.getClaimAt(entity.getLocation(), false, playerData.lastClaim); Claim claim = this.dataStore.getClaimAt(entity.getLocation(), false, playerData.lastClaim);
if(claim != null) if(claim != null)
@ -1426,8 +1428,8 @@ class PlayerEventHandler implements Listener
} }
//block use of buckets within other players' claims //block use of buckets within other players' claims
private HashSet<Material> commonAdjacentBlocks_water = new HashSet<Material>(Arrays.asList(Material.WATER, Material.STATIONARY_WATER, Material.SOIL, Material.DIRT, Material.STONE)); private HashSet<Material> commonAdjacentBlocks_water = new HashSet<Material>(Arrays.asList(Material.WATER, Material.FARMLAND, Material.DIRT, Material.STONE));
private HashSet<Material> commonAdjacentBlocks_lava = new HashSet<Material>(Arrays.asList(Material.LAVA, Material.STATIONARY_LAVA, Material.DIRT, Material.STONE)); private HashSet<Material> commonAdjacentBlocks_lava = new HashSet<Material>(Arrays.asList(Material.LAVA, Material.DIRT, Material.STONE));
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerBucketEmpty (PlayerBucketEmptyEvent bucketEvent) public void onPlayerBucketEmpty (PlayerBucketEmptyEvent bucketEvent)
{ {
@ -1564,39 +1566,39 @@ class PlayerEventHandler implements Listener
} }
//don't care about left-clicking on most blocks, this is probably a break action //don't care about left-clicking on most blocks, this is probably a break action
PlayerData playerData = null; PlayerData playerData = null;
if(action == Action.LEFT_CLICK_BLOCK && clickedBlock != null) if(action == Action.LEFT_CLICK_BLOCK && clickedBlock != null)
{
if(clickedBlock.getY() < clickedBlock.getWorld().getMaxHeight() - 1 || event.getBlockFace() != BlockFace.UP)
{
Block adjacentBlock = clickedBlock.getRelative(event.getBlockFace());
byte lightLevel = adjacentBlock.getLightFromBlocks();
if(lightLevel == 15 && adjacentBlock.getType() == Material.FIRE)
{ {
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId()); if(clickedBlock.getY() < clickedBlock.getWorld().getMaxHeight() - 1 || event.getBlockFace() != BlockFace.UP)
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim); {
if(claim != null) Block adjacentBlock = clickedBlock.getRelative(event.getBlockFace());
{ byte lightLevel = adjacentBlock.getLightFromBlocks();
playerData.lastClaim = claim; if(lightLevel == 15 && adjacentBlock.getType() == Material.FIRE)
{
String noBuildReason = claim.allowBuild(player, Material.AIR); if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
if(noBuildReason != null) Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
if(claim != null)
{
playerData.lastClaim = claim;
String noBuildReason = claim.allowBuild(player, Material.AIR);
if(noBuildReason != null)
{
event.setCancelled(true);
instance.sendMessage(player, TextMode.Err, noBuildReason);
player.sendBlockChange(adjacentBlock.getLocation(), adjacentBlock.getType(), adjacentBlock.getData());
return;
}
}
}
}
//exception for blocks on a specific watch list
if(!this.onLeftClickWatchList(clickedBlockType))
{ {
event.setCancelled(true);
instance.sendMessage(player, TextMode.Err, noBuildReason);
player.sendBlockChange(adjacentBlock.getLocation(), adjacentBlock.getType(), adjacentBlock.getData());
return; return;
} }
}
} }
}
//exception for blocks on a specific watch list
if(!this.onLeftClickWatchList(clickedBlockType) && !instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getType(), clickedBlock.getData(), null)))
{
return;
}
}
//apply rules for containers and crafting blocks //apply rules for containers and crafting blocks
if( clickedBlock != null && instance.config_claims_preventTheft && ( if( clickedBlock != null && instance.config_claims_preventTheft && (
@ -1605,12 +1607,11 @@ class PlayerEventHandler implements Listener
clickedBlockType == Material.CAULDRON || clickedBlockType == Material.CAULDRON ||
clickedBlockType == Material.JUKEBOX || clickedBlockType == Material.JUKEBOX ||
clickedBlockType == Material.ANVIL || clickedBlockType == Material.ANVIL ||
clickedBlockType == Material.CAKE_BLOCK || clickedBlockType == Material.CAKE)))
instance.config_mods_containerTrustIds.Contains(new MaterialInfo(clickedBlock.getType(), clickedBlock.getData(), null)))))
{ {
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId()); if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
//block container use while under siege, so players can't hide items from attackers //block container use while under siege, so players can't hide items from attackers
if(playerData.siegeData != null) if(playerData.siegeData != null)
{ {
instance.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers); instance.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers);
@ -1653,26 +1654,46 @@ class PlayerEventHandler implements Listener
//otherwise apply rules for doors and beds, if configured that way //otherwise apply rules for doors and beds, if configured that way
else if( clickedBlock != null && else if( clickedBlock != null &&
(instance.config_claims_lockWoodenDoors && ( (instance.config_claims_lockWoodenDoors && (
clickedBlockType == Material.WOODEN_DOOR || clickedBlockType == Material.OAK_DOOR ||
clickedBlockType == Material.ACACIA_DOOR || clickedBlockType == Material.ACACIA_DOOR ||
clickedBlockType == Material.BIRCH_DOOR || clickedBlockType == Material.BIRCH_DOOR ||
clickedBlockType == Material.JUNGLE_DOOR || clickedBlockType == Material.JUNGLE_DOOR ||
clickedBlockType == Material.SPRUCE_DOOR || clickedBlockType == Material.SPRUCE_DOOR ||
clickedBlockType == Material.DARK_OAK_DOOR)) || clickedBlockType == Material.DARK_OAK_DOOR)) ||
(instance.config_claims_preventButtonsSwitches && clickedBlockType == Material.BED_BLOCK) || (instance.config_claims_preventButtonsSwitches && ( clickedBlockType == Material.WHITE_BED ||
clickedBlockType == Material.ORANGE_BED ||
clickedBlockType == Material.MAGENTA_BED ||
clickedBlockType == Material.LIGHT_BLUE_BED ||
clickedBlockType == Material.YELLOW_BED ||
clickedBlockType == Material.LIME_BED ||
clickedBlockType == Material.PINK_BED ||
clickedBlockType == Material.GRAY_BED ||
clickedBlockType == Material.LIGHT_GRAY_BED ||
clickedBlockType == Material.CYAN_BED ||
clickedBlockType == Material.PURPLE_BED ||
clickedBlockType == Material.BLUE_BED ||
clickedBlockType == Material.BROWN_BED ||
clickedBlockType == Material.GREEN_BED ||
clickedBlockType == Material.RED_BED ||
clickedBlockType == Material.BLACK_BED)) ||
(instance.config_claims_lockTrapDoors && ( (instance.config_claims_lockTrapDoors && (
clickedBlockType == Material.TRAP_DOOR)) || clickedBlockType == Material.OAK_TRAPDOOR ||
clickedBlockType == Material.SPRUCE_TRAPDOOR ||
clickedBlockType == Material.BIRCH_TRAPDOOR ||
clickedBlockType == Material.JUNGLE_TRAPDOOR ||
clickedBlockType == Material.ACACIA_TRAPDOOR ||
clickedBlockType == Material.DARK_OAK_TRAPDOOR)) ||
(instance.config_claims_lockFenceGates && ( (instance.config_claims_lockFenceGates && (
clickedBlockType == Material.FENCE_GATE || clickedBlockType == Material.OAK_FENCE_GATE ||
clickedBlockType == Material.ACACIA_FENCE_GATE || clickedBlockType == Material.ACACIA_FENCE_GATE ||
clickedBlockType == Material.BIRCH_FENCE_GATE || clickedBlockType == Material.BIRCH_FENCE_GATE ||
clickedBlockType == Material.JUNGLE_FENCE_GATE || clickedBlockType == Material.JUNGLE_FENCE_GATE ||
clickedBlockType == Material.SPRUCE_FENCE_GATE || clickedBlockType == Material.SPRUCE_FENCE_GATE ||
clickedBlockType == Material.DARK_OAK_FENCE_GATE))) clickedBlockType == Material.DARK_OAK_FENCE_GATE)))
{ {
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);
@ -1691,7 +1712,7 @@ class PlayerEventHandler implements Listener
} }
//otherwise apply rules for buttons and switches //otherwise apply rules for buttons and switches
else if(clickedBlock != null && instance.config_claims_preventButtonsSwitches && (clickedBlockType == null || clickedBlockType == Material.STONE_BUTTON || clickedBlockType == Material.WOOD_BUTTON || clickedBlockType == Material.LEVER || instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getType(), clickedBlock.getData(), null)))) else if(clickedBlock != null && instance.config_claims_preventButtonsSwitches && (clickedBlockType == null || clickedBlockType == Material.STONE_BUTTON || Tag.BUTTONS.isTagged(clickedBlockType) || clickedBlockType == Material.LEVER))
{ {
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);
@ -1710,7 +1731,7 @@ class PlayerEventHandler implements Listener
} }
//otherwise apply rule for cake //otherwise apply rule for cake
else if(clickedBlock != null && instance.config_claims_preventTheft && clickedBlockType == Material.CAKE_BLOCK) else if(clickedBlock != null && instance.config_claims_preventTheft && clickedBlockType == Material.CAKE)
{ {
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);
@ -1730,16 +1751,13 @@ class PlayerEventHandler implements Listener
//apply rule for note blocks and repeaters and daylight sensors //RoboMWM: Include flower pots //apply rule for note blocks and repeaters and daylight sensors //RoboMWM: Include flower pots
else if(clickedBlock != null && else if(clickedBlock != null &&
( (
clickedBlockType == Material.NOTE_BLOCK || clickedBlockType == Material.NOTE_BLOCK ||
clickedBlockType == Material.DIODE_BLOCK_ON || clickedBlockType == Material.REPEATER ||
clickedBlockType == Material.DIODE_BLOCK_OFF ||
clickedBlockType == Material.DRAGON_EGG || clickedBlockType == Material.DRAGON_EGG ||
clickedBlockType == Material.DAYLIGHT_DETECTOR || clickedBlockType == Material.DAYLIGHT_DETECTOR ||
clickedBlockType == Material.DAYLIGHT_DETECTOR_INVERTED || clickedBlockType == Material.COMPARATOR ||
clickedBlockType == Material.REDSTONE_COMPARATOR_ON || clickedBlockType == Material.FLOWER_POT
clickedBlockType == Material.REDSTONE_COMPARATOR_OFF ||
clickedBlockType == Material.FLOWER_POT
)) ))
{ {
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId()); if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
@ -1765,10 +1783,64 @@ class PlayerEventHandler implements Listener
//what's the player holding? //what's the player holding?
EquipmentSlot hand = event.getHand(); EquipmentSlot hand = event.getHand();
ItemStack itemInHand = instance.getItemInHand(player, hand); ItemStack itemInHand = instance.getItemInHand(player, hand);
Material materialInHand = itemInHand.getType(); Material materialInHand = itemInHand.getType();
ArrayList<Material> spawn_eggs = new ArrayList<Material>();
spawn_eggs.add(Material.BAT_SPAWN_EGG);
spawn_eggs.add(Material.BLAZE_SPAWN_EGG);
spawn_eggs.add(Material.CAVE_SPIDER_SPAWN_EGG);
spawn_eggs.add(Material.CHICKEN_SPAWN_EGG);
spawn_eggs.add(Material.COD_SPAWN_EGG);
spawn_eggs.add(Material.COW_SPAWN_EGG);
spawn_eggs.add(Material.CREEPER_SPAWN_EGG);
spawn_eggs.add(Material.DOLPHIN_SPAWN_EGG);
spawn_eggs.add(Material.DONKEY_SPAWN_EGG);
spawn_eggs.add(Material.DROWNED_SPAWN_EGG);
spawn_eggs.add(Material.ELDER_GUARDIAN_SPAWN_EGG);
spawn_eggs.add(Material.ENDERMAN_SPAWN_EGG);
spawn_eggs.add(Material.ENDERMITE_SPAWN_EGG);
spawn_eggs.add(Material.EVOKER_SPAWN_EGG);
spawn_eggs.add(Material.GHAST_SPAWN_EGG);
spawn_eggs.add(Material.GUARDIAN_SPAWN_EGG);
spawn_eggs.add(Material.HORSE_SPAWN_EGG);
spawn_eggs.add(Material.HUSK_SPAWN_EGG);
spawn_eggs.add(Material.LLAMA_SPAWN_EGG);
spawn_eggs.add(Material.MAGMA_CUBE_SPAWN_EGG);
spawn_eggs.add(Material.MOOSHROOM_SPAWN_EGG);
spawn_eggs.add(Material.MULE_SPAWN_EGG);
spawn_eggs.add(Material.OCELOT_SPAWN_EGG);
spawn_eggs.add(Material.PARROT_SPAWN_EGG);
spawn_eggs.add(Material.PHANTOM_SPAWN_EGG);
spawn_eggs.add(Material.PIG_SPAWN_EGG);
spawn_eggs.add(Material.POLAR_BEAR_SPAWN_EGG);
spawn_eggs.add(Material.PUFFERFISH_SPAWN_EGG);
spawn_eggs.add(Material.RABBIT_SPAWN_EGG);
spawn_eggs.add(Material.SALMON_SPAWN_EGG);
spawn_eggs.add(Material.SHEEP_SPAWN_EGG);
spawn_eggs.add(Material.SHULKER_SPAWN_EGG);
spawn_eggs.add(Material.SILVERFISH_SPAWN_EGG);
spawn_eggs.add(Material.SKELETON_SPAWN_EGG);
spawn_eggs.add(Material.SKELETON_HORSE_SPAWN_EGG);
spawn_eggs.add(Material.SLIME_SPAWN_EGG);
spawn_eggs.add(Material.SPIDER_SPAWN_EGG);
spawn_eggs.add(Material.SQUID_SPAWN_EGG);
spawn_eggs.add(Material.STRAY_SPAWN_EGG);
spawn_eggs.add(Material.TROPICAL_FISH_SPAWN_EGG);
spawn_eggs.add(Material.TURTLE_SPAWN_EGG);
spawn_eggs.add(Material.VEX_SPAWN_EGG);
spawn_eggs.add(Material.VILLAGER_SPAWN_EGG);
spawn_eggs.add(Material.VINDICATOR_SPAWN_EGG);
spawn_eggs.add(Material.WITCH_SPAWN_EGG);
spawn_eggs.add(Material.WITHER_SKELETON_SPAWN_EGG);
spawn_eggs.add(Material.WOLF_SPAWN_EGG);
spawn_eggs.add(Material.ZOMBIE_SPAWN_EGG);
spawn_eggs.add(Material.ZOMBIE_HORSE_SPAWN_EGG);
spawn_eggs.add(Material.ZOMBIE_PIGMAN_SPAWN_EGG);
spawn_eggs.add(Material.ZOMBIE_VILLAGER_SPAWN_EGG);
//if it's bonemeal, armor stand, spawn egg, etc - check for build permission (ink sac == bone meal, must be a Bukkit bug?) //if it's bonemeal, armor stand, spawn egg, etc - check for build permission (ink sac == bone meal, must be a Bukkit bug?)
if(clickedBlock != null && (materialInHand == Material.INK_SACK || materialInHand == Material.ARMOR_STAND || (materialInHand == Material.MONSTER_EGG && GriefPrevention.instance.config_claims_preventGlobalMonsterEggs) || materialInHand == Material.END_CRYSTAL)) if(clickedBlock != null && (materialInHand == Material.BONE_MEAL || materialInHand == Material.ARMOR_STAND || (spawn_eggs.contains(materialInHand) && GriefPrevention.instance.config_claims_preventGlobalMonsterEggs) || materialInHand == Material.END_CRYSTAL))
{ {
String noBuildReason = instance.allowBuild(player, clickedBlock.getLocation(), clickedBlockType); String noBuildReason = instance.allowBuild(player, clickedBlock.getLocation(), clickedBlockType);
if(noBuildReason != null) if(noBuildReason != null)
@ -1781,18 +1853,18 @@ class PlayerEventHandler implements Listener
} }
else if(clickedBlock != null && ( else if(clickedBlock != null && (
materialInHand == Material.BOAT || materialInHand == Material.OAK_BOAT ||
materialInHand == Material.BOAT_ACACIA || materialInHand == Material.SPRUCE_BOAT ||
materialInHand == Material.BOAT_BIRCH || materialInHand == Material.BIRCH_BOAT ||
materialInHand == Material.BOAT_DARK_OAK || materialInHand == Material.JUNGLE_BOAT ||
materialInHand == Material.BOAT_JUNGLE || materialInHand == Material.ACACIA_BOAT ||
materialInHand == Material.BOAT_SPRUCE)) materialInHand == Material.DARK_OAK_BOAT))
{ {
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);
if(claim != null) if(claim != null)
{ {
String noBuildReason = claim.allowBuild(player, Material.BOAT); String noBuildReason = claim.allowBuild(player, Material.OAK_BOAT); // Though only checks OAK_BOAT, permission should be same for all boats. Plus it being a boat doesn't seem to make a difference currently.
if(noBuildReason != null) if(noBuildReason != null)
{ {
instance.sendMessage(player, TextMode.Err, noBuildReason); instance.sendMessage(player, TextMode.Err, noBuildReason);
@ -1805,26 +1877,44 @@ class PlayerEventHandler implements Listener
//survival world minecart placement requires container trust, which is the permission required to remove the minecart later //survival world minecart placement requires container trust, which is the permission required to remove the minecart later
else if(clickedBlock != null && else if(clickedBlock != null &&
(materialInHand == Material.MINECART || materialInHand == Material.POWERED_MINECART || materialInHand == Material.STORAGE_MINECART || materialInHand == Material.EXPLOSIVE_MINECART || materialInHand == Material.HOPPER_MINECART) && (materialInHand == Material.MINECART ||
!instance.creativeRulesApply(clickedBlock.getLocation())) materialInHand == Material.FURNACE_MINECART ||
{ materialInHand == Material.CHEST_MINECART ||
if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId()); materialInHand == Material.TNT_MINECART ||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim); materialInHand == Material.HOPPER_MINECART) &&
if(claim != null) !instance.creativeRulesApply(clickedBlock.getLocation()))
{ {
String reason = claim.allowContainers(player); if(playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
if(reason != null) Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
{ if(claim != null)
instance.sendMessage(player, TextMode.Err, reason); {
event.setCancelled(true); String reason = claim.allowContainers(player);
} if(reason != null)
} {
instance.sendMessage(player, TextMode.Err, reason);
return; event.setCancelled(true);
} }
}
return;
}
//if it's a spawn egg, minecart, or boat, and this is a creative world, apply special rules //if it's a spawn egg, minecart, or boat, and this is a creative world, apply special rules
else if(clickedBlock != null && (materialInHand == Material.MINECART || materialInHand == Material.POWERED_MINECART || materialInHand == Material.STORAGE_MINECART || materialInHand == Material.ARMOR_STAND || materialInHand == Material.ITEM_FRAME || materialInHand == Material.MONSTER_EGG || materialInHand == Material.MONSTER_EGGS || materialInHand == Material.EXPLOSIVE_MINECART || materialInHand == Material.HOPPER_MINECART) && instance.creativeRulesApply(clickedBlock.getLocation())) else if(clickedBlock != null && (materialInHand == Material.MINECART ||
materialInHand == Material.FURNACE_MINECART ||
materialInHand == Material.CHEST_MINECART ||
materialInHand == Material.TNT_MINECART ||
materialInHand == Material.ARMOR_STAND ||
materialInHand == Material.ITEM_FRAME ||
spawn_eggs.contains(materialInHand) ||
materialInHand == Material.INFESTED_STONE ||
materialInHand == Material.INFESTED_COBBLESTONE ||
materialInHand == Material.INFESTED_STONE_BRICKS ||
materialInHand == Material.INFESTED_MOSSY_STONE_BRICKS ||
materialInHand == Material.INFESTED_CRACKED_STONE_BRICKS ||
materialInHand == Material.INFESTED_CHISELED_STONE_BRICKS ||
materialInHand == Material.HOPPER_MINECART) &&
instance.creativeRulesApply(clickedBlock.getLocation()))
{ {
//player needs build permission at this location //player needs build permission at this location
String noBuildReason = instance.allowBuild(player, clickedBlock.getLocation(), Material.MINECART); String noBuildReason = instance.allowBuild(player, clickedBlock.getLocation(), Material.MINECART);
@ -2043,7 +2133,7 @@ class PlayerEventHandler implements Listener
} }
else if(environment == Environment.THE_END) else if(environment == Environment.THE_END)
{ {
allowedFillBlocks.add(Material.ENDER_STONE); allowedFillBlocks.add(Material.END_STONE);
} }
else else
{ {
@ -2084,7 +2174,7 @@ class PlayerEventHandler implements Listener
} }
//if the player clicks on water, try to sink through the water to find something underneath that's useful for a filler //if the player clicks on water, try to sink through the water to find something underneath that's useful for a filler
else if(centerBlock.getType() == Material.WATER || centerBlock.getType() == Material.STATIONARY_WATER) else if(centerBlock.getType() == Material.WATER)
{ {
Block block = centerBlock.getWorld().getBlockAt(centerBlock.getLocation()); Block block = centerBlock.getWorld().getBlockAt(centerBlock.getLocation());
while(!allowedFillBlocks.contains(block.getType()) && block.getY() > centerBlock.getY() - 10) while(!allowedFillBlocks.contains(block.getType()) && block.getY() > centerBlock.getY() - 10)
@ -2111,7 +2201,7 @@ class PlayerEventHandler implements Listener
} }
//only replace air, spilling water, snow, long grass //only replace air, spilling water, snow, long grass
if(block.getType() == Material.AIR || block.getType() == Material.SNOW || (block.getType() == Material.STATIONARY_WATER && block.getData() != 0) || block.getType() == Material.LONG_GRASS) if(block.getType() == Material.AIR || block.getType() == Material.SNOW || (block.getType() == Material.WATER && ((Levelled) block.getBlockData()).getLevel() != 0) || block.getType() == Material.GRASS)
{ {
//if the top level, always use the default filler picked above //if the top level, always use the default filler picked above
if(y == maxHeight) if(y == maxHeight)
@ -2511,18 +2601,22 @@ class PlayerEventHandler implements Listener
this.inventoryHolderCache.put(cacheKey, isHolder); this.inventoryHolderCache.put(cacheKey, isHolder);
return isHolder; return isHolder;
} }
} }
private boolean onLeftClickWatchList(Material material) private boolean onLeftClickWatchList(Material material)
{ {
switch(material) switch(material)
{ {
case WOOD_BUTTON: case OAK_BUTTON:
case SPRUCE_BUTTON:
case BIRCH_BUTTON:
case JUNGLE_BUTTON:
case ACACIA_BUTTON:
case DARK_OAK_BUTTON:
case STONE_BUTTON: case STONE_BUTTON:
case LEVER: case LEVER:
case DIODE_BLOCK_ON: //redstone repeater case REPEATER:
case DIODE_BLOCK_OFF: case CAKE:
case CAKE_BLOCK:
case DRAGON_EGG: case DRAGON_EGG:
return true; return true;
default: default:
@ -2534,7 +2628,7 @@ class PlayerEventHandler implements Listener
{ {
Location eye = player.getEyeLocation(); Location eye = player.getEyeLocation();
Material eyeMaterial = eye.getBlock().getType(); Material eyeMaterial = eye.getBlock().getType();
boolean passThroughWater = (eyeMaterial == Material.WATER || eyeMaterial == Material.STATIONARY_WATER); boolean passThroughWater = (eyeMaterial == Material.WATER);
BlockIterator iterator = new BlockIterator(player.getLocation(), player.getEyeHeight(), maxDistance); BlockIterator iterator = new BlockIterator(player.getLocation(), player.getEyeHeight(), maxDistance);
Block result = player.getLocation().getBlock().getRelative(BlockFace.UP); Block result = player.getLocation().getBlock().getRelative(BlockFace.UP);
while (iterator.hasNext()) while (iterator.hasNext())
@ -2542,9 +2636,8 @@ class PlayerEventHandler implements Listener
result = iterator.next(); result = iterator.next();
Material type = result.getType(); Material type = result.getType();
if(type != Material.AIR && if(type != Material.AIR &&
(!passThroughWater || type != Material.STATIONARY_WATER) &&
(!passThroughWater || type != Material.WATER) && (!passThroughWater || type != Material.WATER) &&
type != Material.LONG_GRASS && type != Material.GRASS &&
type != Material.SNOW) return result; type != Material.SNOW) return result;
} }

View File

@ -56,7 +56,7 @@ class RestoreNatureExecutionTask implements Runnable
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public void run() public void run()
{ {
//apply changes to the world, but ONLY to unclaimed blocks //apply changes to the world, but ONLY to unclaimed blocks
@ -71,7 +71,7 @@ class RestoreNatureExecutionTask implements Runnable
{ {
BlockSnapshot blockUpdate = this.snapshots[x][y][z]; BlockSnapshot blockUpdate = this.snapshots[x][y][z];
Block currentBlock = blockUpdate.location.getBlock(); Block currentBlock = blockUpdate.location.getBlock();
if(blockUpdate.typeId != currentBlock.getType()|| blockUpdate.data != currentBlock.getData()) if(blockUpdate.typeId != currentBlock.getType()|| !blockUpdate.data.equals(currentBlock.getBlockData()))
{ {
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(blockUpdate.location, false, cachedClaim); Claim claim = GriefPrevention.instance.dataStore.getClaimAt(blockUpdate.location, false, cachedClaim);
if(claim != null) if(claim != null)
@ -82,8 +82,8 @@ class RestoreNatureExecutionTask implements Runnable
try try
{ {
currentBlock.setType(blockUpdate.typeId, false); currentBlock.setType(blockUpdate.typeId, false);
currentBlock.setData(blockUpdate.data, false); currentBlock.setBlockData(blockUpdate.data, false);
} }
catch(IllegalArgumentException e) catch(IllegalArgumentException e)
{ {

View File

@ -22,8 +22,11 @@ import java.util.ArrayList;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.data.Levelled;
import org.bukkit.block.data.type.Leaves;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
//non-main-thread task which processes world data to repair the unnatural //non-main-thread task which processes world data to repair the unnatural
@ -67,9 +70,14 @@ class RestoreNatureProcessingTask implements Runnable
this.notAllowedToHang = new ArrayList<Material>(); this.notAllowedToHang = new ArrayList<Material>();
this.notAllowedToHang.add(Material.DIRT); this.notAllowedToHang.add(Material.DIRT);
this.notAllowedToHang.add(Material.LONG_GRASS); this.notAllowedToHang.add(Material.GRASS);
this.notAllowedToHang.add(Material.SNOW); this.notAllowedToHang.add(Material.SNOW);
this.notAllowedToHang.add(Material.LOG); this.notAllowedToHang.add(Material.OAK_LOG);
this.notAllowedToHang.add(Material.SPRUCE_LOG);
this.notAllowedToHang.add(Material.BIRCH_LOG);
this.notAllowedToHang.add(Material.JUNGLE_LOG);
this.notAllowedToHang.add(Material.ACACIA_LOG);
this.notAllowedToHang.add(Material.DARK_OAK_LOG);
if(this.aggressiveMode) if(this.aggressiveMode)
{ {
@ -88,21 +96,28 @@ class RestoreNatureProcessingTask implements Runnable
this.playerBlocks.add(Material.IRON_ORE); this.playerBlocks.add(Material.IRON_ORE);
this.playerBlocks.add(Material.GOLD_ORE); this.playerBlocks.add(Material.GOLD_ORE);
this.playerBlocks.add(Material.DIAMOND_ORE); this.playerBlocks.add(Material.DIAMOND_ORE);
this.playerBlocks.add(Material.MELON_BLOCK); this.playerBlocks.add(Material.MELON);
this.playerBlocks.add(Material.MELON_STEM); this.playerBlocks.add(Material.MELON_STEM);
this.playerBlocks.add(Material.BEDROCK); this.playerBlocks.add(Material.BEDROCK);
this.playerBlocks.add(Material.COAL_ORE); this.playerBlocks.add(Material.COAL_ORE);
this.playerBlocks.add(Material.PUMPKIN); this.playerBlocks.add(Material.PUMPKIN);
this.playerBlocks.add(Material.PUMPKIN_STEM); this.playerBlocks.add(Material.PUMPKIN_STEM);
this.playerBlocks.add(Material.MELON);
} }
if(this.aggressiveMode) if(this.aggressiveMode)
{ {
this.playerBlocks.add(Material.LEAVES); this.playerBlocks.add(Material.OAK_LEAVES);
this.playerBlocks.add(Material.LEAVES_2); this.playerBlocks.add(Material.SPRUCE_LEAVES);
this.playerBlocks.add(Material.LOG); this.playerBlocks.add(Material.BIRCH_LEAVES);
this.playerBlocks.add(Material.LOG_2); this.playerBlocks.add(Material.JUNGLE_LEAVES);
this.playerBlocks.add(Material.ACACIA_LEAVES);
this.playerBlocks.add(Material.DARK_OAK_LEAVES);
this.playerBlocks.add(Material.OAK_LOG);
this.playerBlocks.add(Material.SPRUCE_LOG);
this.playerBlocks.add(Material.BIRCH_LOG);
this.playerBlocks.add(Material.JUNGLE_LOG);
this.playerBlocks.add(Material.ACACIA_LOG);
this.playerBlocks.add(Material.DARK_OAK_LOG);
this.playerBlocks.add(Material.VINE); this.playerBlocks.add(Material.VINE);
} }
} }
@ -161,9 +176,8 @@ class RestoreNatureProcessingTask implements Runnable
{ {
for(int y = this.seaLevel - 1; y < snapshots[0].length; y++) for(int y = this.seaLevel - 1; y < snapshots[0].length; y++)
{ {
//note: see minecraft wiki data values for leaves
BlockSnapshot block = snapshots[x][y][z]; BlockSnapshot block = snapshots[x][y][z];
if(block.typeId == Material.LEAVES && (block.data & 0x4) != 0) if(Tag.LEAVES.isTagged(block.typeId) && ((Leaves) block.data).isPersistent())
{ {
block.typeId = Material.AIR; block.typeId = Material.AIR;
} }
@ -233,19 +247,19 @@ class RestoreNatureProcessingTask implements Runnable
//count adjacent non-air/non-leaf blocks //count adjacent non-air/non-leaf blocks
byte adjacentBlockCount = 0; byte adjacentBlockCount = 0;
if(leftBlock.typeId != Material.AIR && leftBlock.typeId != Material.LEAVES && leftBlock.typeId != Material.VINE) if(leftBlock.typeId != Material.AIR && !Tag.LEAVES.isTagged(leftBlock.typeId) && leftBlock.typeId != Material.VINE)
{ {
adjacentBlockCount++; adjacentBlockCount++;
} }
if(rightBlock.typeId != Material.AIR && rightBlock.typeId != Material.LEAVES && rightBlock.typeId != Material.VINE) if(rightBlock.typeId != Material.AIR && !Tag.LEAVES.isTagged(rightBlock.typeId) && rightBlock.typeId != Material.VINE)
{ {
adjacentBlockCount++; adjacentBlockCount++;
} }
if(downBlock.typeId != Material.AIR && downBlock.typeId != Material.LEAVES && downBlock.typeId != Material.VINE) if(downBlock.typeId != Material.AIR && !Tag.LEAVES.isTagged(downBlock.typeId) && downBlock.typeId != Material.VINE)
{ {
adjacentBlockCount++; adjacentBlockCount++;
} }
if(upBlock.typeId != Material.AIR && upBlock.typeId != Material.LEAVES && upBlock.typeId != Material.VINE) if(upBlock.typeId != Material.AIR && !Tag.LEAVES.isTagged(upBlock.typeId) && upBlock.typeId != Material.VINE)
{ {
adjacentBlockCount++; adjacentBlockCount++;
} }
@ -278,11 +292,10 @@ class RestoreNatureProcessingTask implements Runnable
BlockSnapshot block = snapshots[x][y][z]; BlockSnapshot block = snapshots[x][y][z];
//skip non-logs //skip non-logs
if(block.typeId != Material.LOG) continue; if(!Tag.LOGS.isTagged(block.typeId)) continue;
if(block.typeId != Material.LOG_2) continue;
//if in jungle biome, skip jungle logs //if in jungle biome, skip jungle logs
if(jungleBiome && block.data == 3) continue; if(jungleBiome && block.typeId == Material.JUNGLE_LOG) continue;
//examine adjacent blocks for logs //examine adjacent blocks for logs
BlockSnapshot leftBlock = this.snapshots[x + 1][y][z]; BlockSnapshot leftBlock = this.snapshots[x + 1][y][z];
@ -291,7 +304,7 @@ class RestoreNatureProcessingTask implements Runnable
BlockSnapshot downBlock = this.snapshots[x][y][z - 1]; BlockSnapshot downBlock = this.snapshots[x][y][z - 1];
//if any, remove the log //if any, remove the log
if(leftBlock.typeId == Material.LOG || rightBlock.typeId == Material.LOG || upBlock.typeId == Material.LOG || downBlock.typeId == Material.LOG) if(Tag.LOGS.isTagged(leftBlock.typeId) || Tag.LOGS.isTagged(rightBlock.typeId) || Tag.LOGS.isTagged(upBlock.typeId) || Tag.LOGS.isTagged(downBlock.typeId))
{ {
this.snapshots[x][y][z].typeId = Material.AIR; this.snapshots[x][y][z].typeId = Material.AIR;
} }
@ -338,7 +351,7 @@ class RestoreNatureProcessingTask implements Runnable
BlockSnapshot block = snapshots[x][y][z]; BlockSnapshot block = snapshots[x][y][z];
BlockSnapshot underBlock = snapshots[x][y - 1][z]; BlockSnapshot underBlock = snapshots[x][y - 1][z];
if(underBlock.typeId == Material.AIR || underBlock.typeId == Material.STATIONARY_WATER || underBlock.typeId == Material.STATIONARY_LAVA || underBlock.typeId == Material.LEAVES) if(underBlock.typeId == Material.AIR || underBlock.typeId == Material.WATER || Tag.LEAVES.isTagged(underBlock.typeId))
{ {
if(this.notAllowedToHang.contains(block.typeId)) if(this.notAllowedToHang.contains(block.typeId))
{ {
@ -356,22 +369,31 @@ class RestoreNatureProcessingTask implements Runnable
Material [] excludedBlocksArray = new Material [] Material [] excludedBlocksArray = new Material []
{ {
Material.CACTUS, Material.CACTUS,
Material.LONG_GRASS, Material.GRASS,
Material.RED_MUSHROOM, Material.RED_MUSHROOM,
Material.BROWN_MUSHROOM, Material.BROWN_MUSHROOM,
Material.DEAD_BUSH, Material.DEAD_BUSH,
Material.SAPLING, Material.DANDELION,
Material.YELLOW_FLOWER, Material.POPPY,
Material.RED_ROSE, Material.ALLIUM,
Material.SUGAR_CANE_BLOCK, Material.BLUE_ORCHID,
Material.AZURE_BLUET,
Material.RED_TULIP,
Material.ORANGE_TULIP,
Material.WHITE_TULIP,
Material.PINK_TULIP,
Material.OXEYE_DAISY,
Material.SUGAR_CANE,
Material.VINE, Material.VINE,
Material.PUMPKIN, Material.PUMPKIN,
Material.WATER_LILY, Material.LILY_PAD
Material.LEAVES
}; };
ArrayList<Material> excludedBlocks = new ArrayList<Material>(); ArrayList<Material> excludedBlocks = new ArrayList<Material>();
for(int i = 0; i < excludedBlocksArray.length; i++) excludedBlocks.add(excludedBlocksArray[i]); for(int i = 0; i < excludedBlocksArray.length; i++) excludedBlocks.add(excludedBlocksArray[i]);
excludedBlocks.addAll(Tag.SAPLINGS.getValues());
excludedBlocks.addAll(Tag.LEAVES.getValues());
boolean changed; boolean changed;
do do
@ -414,9 +436,9 @@ class RestoreNatureProcessingTask implements Runnable
int y = this.highestY(x, z, true); int y = this.highestY(x, z, true);
BlockSnapshot block = snapshots[x][y][z]; BlockSnapshot block = snapshots[x][y][z];
if(block.typeId == Material.STONE || block.typeId == Material.GRAVEL || block.typeId == Material.SOIL || block.typeId == Material.DIRT || block.typeId == Material.SANDSTONE) if(block.typeId == Material.STONE || block.typeId == Material.GRAVEL || block.typeId == Material.FARMLAND || block.typeId == Material.DIRT || block.typeId == Material.SANDSTONE)
{ {
if(this.biome == Biome.DESERT || this.biome == Biome.DESERT_HILLS || this.biome == Biome.BEACHES) if(this.biome == Biome.DESERT || this.biome == Biome.DESERT_HILLS || this.biome == Biome.BEACH)
{ {
this.snapshots[x][y][z].typeId = Material.SAND; this.snapshots[x][y][z].typeId = Material.SAND;
} }
@ -434,17 +456,16 @@ class RestoreNatureProcessingTask implements Runnable
{ {
ArrayList<Material> fillableBlocks = new ArrayList<Material>(); ArrayList<Material> fillableBlocks = new ArrayList<Material>();
fillableBlocks.add(Material.AIR); fillableBlocks.add(Material.AIR);
fillableBlocks.add(Material.STATIONARY_WATER); fillableBlocks.add(Material.WATER);
fillableBlocks.add(Material.STATIONARY_LAVA); fillableBlocks.add(Material.LAVA);
fillableBlocks.add(Material.LONG_GRASS); fillableBlocks.add(Material.GRASS);
ArrayList<Material> notSuitableForFillBlocks = new ArrayList<Material>(); ArrayList<Material> notSuitableForFillBlocks = new ArrayList<Material>();
notSuitableForFillBlocks.add(Material.LONG_GRASS); notSuitableForFillBlocks.add(Material.GRASS);
notSuitableForFillBlocks.add(Material.CACTUS); notSuitableForFillBlocks.add(Material.CACTUS);
notSuitableForFillBlocks.add(Material.STATIONARY_WATER); notSuitableForFillBlocks.add(Material.WATER);
notSuitableForFillBlocks.add(Material.STATIONARY_LAVA); notSuitableForFillBlocks.add(Material.LAVA);
notSuitableForFillBlocks.add(Material.LOG); notSuitableForFillBlocks.addAll(Tag.LOGS.getValues());
notSuitableForFillBlocks.add(Material.LOG_2);
boolean changed; boolean changed;
do do
@ -504,10 +525,11 @@ class RestoreNatureProcessingTask implements Runnable
for(int y = miny; y < snapshots[0].length - 1; y++) for(int y = miny; y < snapshots[0].length - 1; y++)
{ {
BlockSnapshot block = this.snapshots[x][y][z]; BlockSnapshot block = this.snapshots[x][y][z];
BlockSnapshot underBlock = this.snapshots[x][y][z]; BlockSnapshot underBlock = this.snapshots[x][y--][z];
if(block.typeId == Material.STATIONARY_WATER || block.typeId == Material.STATIONARY_LAVA) if(block.typeId == Material.WATER || block.typeId == Material.LAVA)
{ {
if(underBlock.typeId == Material.AIR || (underBlock.data != 0)) // check if block below is air or is a non-source fluid block (level 1-7 = flowing, 8 = falling)
if(underBlock.typeId == Material.AIR || (underBlock.typeId == Material.WATER && (((Levelled) underBlock.data).getLevel() != 0)))
{ {
block.typeId = Material.AIR; block.typeId = Material.AIR;
} }
@ -529,7 +551,7 @@ class RestoreNatureProcessingTask implements Runnable
BlockSnapshot block = snapshots[x][y][z]; BlockSnapshot block = snapshots[x][y][z];
//only consider air blocks and flowing water blocks for upgrade to water source blocks //only consider air blocks and flowing water blocks for upgrade to water source blocks
if(block.typeId == Material.AIR || (block.typeId == Material.STATIONARY_WATER && block.data != 0)) if(block.typeId == Material.AIR || (block.typeId == Material.WATER && ((Levelled) block.data).getLevel() != 0))
{ {
BlockSnapshot leftBlock = this.snapshots[x + 1][y][z]; BlockSnapshot leftBlock = this.snapshots[x + 1][y][z];
BlockSnapshot rightBlock = this.snapshots[x - 1][y][z]; BlockSnapshot rightBlock = this.snapshots[x - 1][y][z];
@ -538,23 +560,23 @@ class RestoreNatureProcessingTask implements Runnable
BlockSnapshot underBlock = this.snapshots[x][y - 1][z]; BlockSnapshot underBlock = this.snapshots[x][y - 1][z];
//block underneath MUST be source water //block underneath MUST be source water
if(underBlock.typeId != Material.STATIONARY_WATER || underBlock.data != 0) continue; if(!(underBlock.typeId == Material.WATER && ((Levelled) underBlock.data).getLevel() == 0)) continue;
//count adjacent source water blocks //count adjacent source water blocks
byte adjacentSourceWaterCount = 0; byte adjacentSourceWaterCount = 0;
if(leftBlock.typeId == Material.STATIONARY_WATER && leftBlock.data == 0) if(leftBlock.typeId == Material.WATER && ((Levelled) leftBlock.data).getLevel() == 0)
{ {
adjacentSourceWaterCount++; adjacentSourceWaterCount++;
} }
if(rightBlock.typeId == Material.STATIONARY_WATER && rightBlock.data == 0) if(rightBlock.typeId == Material.WATER && ((Levelled) rightBlock.data).getLevel() == 0)
{ {
adjacentSourceWaterCount++; adjacentSourceWaterCount++;
} }
if(upBlock.typeId == Material.STATIONARY_WATER && upBlock.data == 0) if(upBlock.typeId == Material.WATER && ((Levelled) upBlock.data).getLevel() == 0)
{ {
adjacentSourceWaterCount++; adjacentSourceWaterCount++;
} }
if(downBlock.typeId == Material.STATIONARY_WATER && downBlock.data == 0) if(downBlock.typeId == Material.WATER && ((Levelled) downBlock.data).getLevel() == 0)
{ {
adjacentSourceWaterCount++; adjacentSourceWaterCount++;
} }
@ -562,8 +584,8 @@ class RestoreNatureProcessingTask implements Runnable
//at least two adjacent blocks must be source water //at least two adjacent blocks must be source water
if(adjacentSourceWaterCount >= 2) if(adjacentSourceWaterCount >= 2)
{ {
block.typeId = Material.STATIONARY_WATER; block.typeId = Material.WATER;
block.data = 0; ((Levelled) downBlock.data).setLevel(0);
changed = true; changed = true;
} }
} }
@ -578,7 +600,7 @@ class RestoreNatureProcessingTask implements Runnable
{ {
if(this.seaLevel < 1) return; if(this.seaLevel < 1) return;
//remove any surface water or lava above sea level, presumed to be placed by players //remove any surface water or lava above sea level, presumed to be placed by players
//sometimes, this is naturally generated. but replacing it is very easy with a bucket, so overall this is a good plan //sometimes, this is naturally generated. but replacing it is very easy with a bucket, so overall this is a good plan
if(this.environment == Environment.NETHER) return; if(this.environment == Environment.NETHER) return;
for(int x = 1; x < snapshots.length - 1; x++) for(int x = 1; x < snapshots.length - 1; x++)
@ -588,8 +610,7 @@ class RestoreNatureProcessingTask implements Runnable
for(int y = this.seaLevel - 1; y < snapshots[0].length - 1; y++) for(int y = this.seaLevel - 1; y < snapshots[0].length - 1; y++)
{ {
BlockSnapshot block = snapshots[x][y][z]; BlockSnapshot block = snapshots[x][y][z];
if(block.typeId == Material.STATIONARY_WATER || block.typeId == Material.STATIONARY_LAVA || if(block.typeId == Material.WATER || block.typeId == Material.LAVA)
block.typeId == Material.WATER || block.typeId == Material.LAVA)
{ {
block.typeId = Material.AIR; block.typeId = Material.AIR;
} }
@ -599,7 +620,7 @@ class RestoreNatureProcessingTask implements Runnable
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private int highestY(int x, int z, boolean ignoreLeaves) private int highestY(int x, int z, boolean ignoreLeaves)
{ {
int y; int y;
for(y = snapshots[0].length - 1; y > 0; y--) for(y = snapshots[0].length - 1; y > 0; y--)
@ -607,12 +628,9 @@ class RestoreNatureProcessingTask implements Runnable
BlockSnapshot block = this.snapshots[x][y][z]; BlockSnapshot block = this.snapshots[x][y][z];
if(block.typeId != Material.AIR && if(block.typeId != Material.AIR &&
!(ignoreLeaves && block.typeId == Material.SNOW) && !(ignoreLeaves && block.typeId == Material.SNOW) &&
!(ignoreLeaves && block.typeId == Material.LEAVES) && !(ignoreLeaves && Tag.LEAVES.isTagged(block.typeId)) &&
!(ignoreLeaves && block.typeId == Material.LEAVES_2) &&
!(block.typeId == Material.STATIONARY_WATER) &&
!(block.typeId == Material.WATER) && !(block.typeId == Material.WATER) &&
!(block.typeId == Material.LAVA) && !(block.typeId == Material.LAVA))
!(block.typeId == Material.STATIONARY_LAVA))
{ {
return y; return y;
} }
@ -622,15 +640,35 @@ class RestoreNatureProcessingTask implements Runnable
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
static ArrayList<Material> getPlayerBlocks(Environment environment, Biome biome) static ArrayList<Material> getPlayerBlocks(Environment environment, Biome biome)
{ {
//NOTE on this list. why not make a list of natural blocks? //NOTE on this list. why not make a list of natural blocks?
//answer: better to leave a few player blocks than to remove too many natural blocks. remember we're "restoring nature" //answer: better to leave a few player blocks than to remove too many natural blocks. remember we're "restoring nature"
//a few extra player blocks can be manually removed, but it will be impossible to guess exactly which natural materials to use in manual repair of an overzealous block removal //a few extra player blocks can be manually removed, but it will be impossible to guess exactly which natural materials to use in manual repair of an overzealous block removal
ArrayList<Material> playerBlocks = new ArrayList<Material>(); ArrayList<Material> playerBlocks = new ArrayList<Material>();
playerBlocks.add(Material.FIRE); playerBlocks.add(Material.FIRE);
playerBlocks.add(Material.BED_BLOCK); playerBlocks.add(Material.WHITE_BED);
playerBlocks.add(Material.WOOD); playerBlocks.add(Material.ORANGE_BED);
playerBlocks.add(Material.MAGENTA_BED);
playerBlocks.add(Material.LIGHT_BLUE_BED);
playerBlocks.add(Material.YELLOW_BED);
playerBlocks.add(Material.LIME_BED);
playerBlocks.add(Material.PINK_BED);
playerBlocks.add(Material.GRAY_BED);
playerBlocks.add(Material.LIGHT_GRAY_BED);
playerBlocks.add(Material.CYAN_BED);
playerBlocks.add(Material.PURPLE_BED);
playerBlocks.add(Material.BLUE_BED);
playerBlocks.add(Material.BROWN_BED);
playerBlocks.add(Material.GREEN_BED);
playerBlocks.add(Material.RED_BED);
playerBlocks.add(Material.BLACK_BED);
playerBlocks.add(Material.OAK_PLANKS);
playerBlocks.add(Material.SPRUCE_PLANKS);
playerBlocks.add(Material.BIRCH_PLANKS);
playerBlocks.add(Material.JUNGLE_PLANKS);
playerBlocks.add(Material.ACACIA_PLANKS);
playerBlocks.add(Material.DARK_OAK_PLANKS);
playerBlocks.add(Material.BOOKSHELF); playerBlocks.add(Material.BOOKSHELF);
playerBlocks.add(Material.BREWING_STAND); playerBlocks.add(Material.BREWING_STAND);
playerBlocks.add(Material.BRICK); playerBlocks.add(Material.BRICK);
@ -641,99 +679,201 @@ class RestoreNatureProcessingTask implements Runnable
playerBlocks.add(Material.NOTE_BLOCK); playerBlocks.add(Material.NOTE_BLOCK);
playerBlocks.add(Material.POWERED_RAIL); playerBlocks.add(Material.POWERED_RAIL);
playerBlocks.add(Material.DETECTOR_RAIL); playerBlocks.add(Material.DETECTOR_RAIL);
playerBlocks.add(Material.PISTON_STICKY_BASE); playerBlocks.add(Material.STICKY_PISTON);
playerBlocks.add(Material.PISTON_BASE); playerBlocks.add(Material.PISTON);
playerBlocks.add(Material.PISTON_EXTENSION); playerBlocks.add(Material.PISTON_HEAD);
playerBlocks.add(Material.WOOL); playerBlocks.add(Material.MOVING_PISTON);
playerBlocks.add(Material.PISTON_MOVING_PIECE); playerBlocks.add(Material.WHITE_WOOL);
playerBlocks.add(Material.ORANGE_WOOL);
playerBlocks.add(Material.MAGENTA_WOOL);
playerBlocks.add(Material.LIGHT_BLUE_WOOL);
playerBlocks.add(Material.YELLOW_WOOL);
playerBlocks.add(Material.LIME_WOOL);
playerBlocks.add(Material.PINK_WOOL);
playerBlocks.add(Material.GRAY_WOOL);
playerBlocks.add(Material.LIGHT_GRAY_WOOL);
playerBlocks.add(Material.CYAN_WOOL);
playerBlocks.add(Material.PURPLE_WOOL);
playerBlocks.add(Material.BLUE_WOOL);
playerBlocks.add(Material.BROWN_WOOL);
playerBlocks.add(Material.GREEN_WOOL);
playerBlocks.add(Material.RED_WOOL);
playerBlocks.add(Material.BLACK_WOOL);
playerBlocks.add(Material.GOLD_BLOCK); playerBlocks.add(Material.GOLD_BLOCK);
playerBlocks.add(Material.IRON_BLOCK); playerBlocks.add(Material.IRON_BLOCK);
playerBlocks.add(Material.DOUBLE_STEP); playerBlocks.add(Material.OAK_SLAB);
playerBlocks.add(Material.STEP); playerBlocks.add(Material.SPRUCE_SLAB);
playerBlocks.add(Material.CROPS); playerBlocks.add(Material.BIRCH_SLAB);
playerBlocks.add(Material.JUNGLE_SLAB);
playerBlocks.add(Material.ACACIA_SLAB);
playerBlocks.add(Material.DARK_OAK_SLAB);
playerBlocks.add(Material.STONE_SLAB);
playerBlocks.add(Material.SANDSTONE_SLAB);
playerBlocks.add(Material.PETRIFIED_OAK_SLAB);
playerBlocks.add(Material.COBBLESTONE_SLAB);
playerBlocks.add(Material.BRICK_SLAB);
playerBlocks.add(Material.STONE_BRICK_SLAB);
playerBlocks.add(Material.NETHER_BRICK_SLAB);
playerBlocks.add(Material.QUARTZ_SLAB);
playerBlocks.add(Material.RED_SANDSTONE_SLAB);
playerBlocks.add(Material.PURPUR_SLAB);
playerBlocks.add(Material.PRISMARINE_SLAB);
playerBlocks.add(Material.PRISMARINE_BRICK_SLAB);
playerBlocks.add(Material.DARK_PRISMARINE_SLAB);
playerBlocks.add(Material.WHEAT);
playerBlocks.add(Material.TNT); playerBlocks.add(Material.TNT);
playerBlocks.add(Material.MOSSY_COBBLESTONE); playerBlocks.add(Material.MOSSY_COBBLESTONE);
playerBlocks.add(Material.TORCH); playerBlocks.add(Material.TORCH);
playerBlocks.add(Material.FIRE); playerBlocks.add(Material.FIRE);
playerBlocks.add(Material.WOOD_STAIRS); playerBlocks.add(Material.OAK_STAIRS);
playerBlocks.add(Material.SPRUCE_STAIRS);
playerBlocks.add(Material.BIRCH_STAIRS);
playerBlocks.add(Material.JUNGLE_STAIRS);
playerBlocks.add(Material.ACACIA_STAIRS);
playerBlocks.add(Material.DARK_OAK_STAIRS);
playerBlocks.add(Material.CHEST); playerBlocks.add(Material.CHEST);
playerBlocks.add(Material.REDSTONE_WIRE); playerBlocks.add(Material.REDSTONE_WIRE);
playerBlocks.add(Material.DIAMOND_BLOCK); playerBlocks.add(Material.DIAMOND_BLOCK);
playerBlocks.add(Material.WORKBENCH); playerBlocks.add(Material.CRAFTING_TABLE);
playerBlocks.add(Material.FURNACE); playerBlocks.add(Material.FURNACE);
playerBlocks.add(Material.BURNING_FURNACE); playerBlocks.add(Material.OAK_DOOR);
playerBlocks.add(Material.WOODEN_DOOR); playerBlocks.add(Material.SIGN);
playerBlocks.add(Material.SIGN_POST);
playerBlocks.add(Material.LADDER); playerBlocks.add(Material.LADDER);
playerBlocks.add(Material.RAILS); playerBlocks.add(Material.RAIL);
playerBlocks.add(Material.COBBLESTONE_STAIRS); playerBlocks.add(Material.COBBLESTONE_STAIRS);
playerBlocks.add(Material.WALL_SIGN); playerBlocks.add(Material.WALL_SIGN);
playerBlocks.add(Material.STONE_PLATE); playerBlocks.add(Material.STONE_PRESSURE_PLATE);
playerBlocks.add(Material.LEVER); playerBlocks.add(Material.LEVER);
playerBlocks.add(Material.IRON_DOOR_BLOCK); playerBlocks.add(Material.IRON_DOOR);
playerBlocks.add(Material.WOOD_PLATE); playerBlocks.add(Material.OAK_PRESSURE_PLATE);
playerBlocks.add(Material.REDSTONE_TORCH_ON); playerBlocks.add(Material.SPRUCE_PRESSURE_PLATE);
playerBlocks.add(Material.REDSTONE_TORCH_OFF); playerBlocks.add(Material.BIRCH_PRESSURE_PLATE);
playerBlocks.add(Material.JUNGLE_PRESSURE_PLATE);
playerBlocks.add(Material.ACACIA_PRESSURE_PLATE);
playerBlocks.add(Material.DARK_OAK_PRESSURE_PLATE);
playerBlocks.add(Material.REDSTONE_TORCH);
playerBlocks.add(Material.STONE_BUTTON); playerBlocks.add(Material.STONE_BUTTON);
playerBlocks.add(Material.SNOW_BLOCK); playerBlocks.add(Material.SNOW_BLOCK);
playerBlocks.add(Material.JUKEBOX); playerBlocks.add(Material.JUKEBOX);
playerBlocks.add(Material.FENCE); playerBlocks.add(Material.OAK_FENCE);
playerBlocks.add(Material.PORTAL); playerBlocks.add(Material.SPRUCE_FENCE);
playerBlocks.add(Material.BIRCH_FENCE);
playerBlocks.add(Material.JUNGLE_FENCE);
playerBlocks.add(Material.ACACIA_FENCE);
playerBlocks.add(Material.DARK_OAK_FENCE);
playerBlocks.add(Material.NETHER_PORTAL);
playerBlocks.add(Material.JACK_O_LANTERN); playerBlocks.add(Material.JACK_O_LANTERN);
playerBlocks.add(Material.CAKE_BLOCK); playerBlocks.add(Material.CAKE);
playerBlocks.add(Material.DIODE_BLOCK_ON); playerBlocks.add(Material.REPEATER);
playerBlocks.add(Material.DIODE_BLOCK_OFF); playerBlocks.add(Material.OAK_TRAPDOOR);
playerBlocks.add(Material.TRAP_DOOR); playerBlocks.add(Material.SPRUCE_TRAPDOOR);
playerBlocks.add(Material.SMOOTH_BRICK); playerBlocks.add(Material.BIRCH_TRAPDOOR);
playerBlocks.add(Material.HUGE_MUSHROOM_1); playerBlocks.add(Material.JUNGLE_TRAPDOOR);
playerBlocks.add(Material.HUGE_MUSHROOM_2); playerBlocks.add(Material.ACACIA_TRAPDOOR);
playerBlocks.add(Material.IRON_FENCE); playerBlocks.add(Material.DARK_OAK_TRAPDOOR);
playerBlocks.add(Material.THIN_GLASS); playerBlocks.add(Material.STONE_BRICKS);
playerBlocks.add(Material.MOSSY_STONE_BRICKS);
playerBlocks.add(Material.CRACKED_STONE_BRICKS);
playerBlocks.add(Material.CHISELED_STONE_BRICKS);
playerBlocks.add(Material.MUSHROOM_STEM);
playerBlocks.add(Material.RED_MUSHROOM_BLOCK);
playerBlocks.add(Material.BROWN_MUSHROOM_BLOCK);
playerBlocks.add(Material.IRON_BARS);
playerBlocks.add(Material.GLASS_PANE);
playerBlocks.add(Material.MELON_STEM); playerBlocks.add(Material.MELON_STEM);
playerBlocks.add(Material.FENCE_GATE); playerBlocks.add(Material.OAK_FENCE_GATE);
playerBlocks.add(Material.SPRUCE_FENCE_GATE);
playerBlocks.add(Material.BIRCH_FENCE_GATE);
playerBlocks.add(Material.JUNGLE_FENCE_GATE);
playerBlocks.add(Material.ACACIA_FENCE_GATE);
playerBlocks.add(Material.DARK_OAK_FENCE_GATE);
playerBlocks.add(Material.BRICK_STAIRS); playerBlocks.add(Material.BRICK_STAIRS);
playerBlocks.add(Material.SMOOTH_STAIRS); playerBlocks.add(Material.ENCHANTING_TABLE);
playerBlocks.add(Material.ENCHANTMENT_TABLE);
playerBlocks.add(Material.BREWING_STAND); playerBlocks.add(Material.BREWING_STAND);
playerBlocks.add(Material.CAULDRON); playerBlocks.add(Material.CAULDRON);
playerBlocks.add(Material.DIODE_BLOCK_ON); playerBlocks.add(Material.COBWEB);
playerBlocks.add(Material.DIODE_BLOCK_ON);
playerBlocks.add(Material.WEB);
playerBlocks.add(Material.SPONGE); playerBlocks.add(Material.SPONGE);
playerBlocks.add(Material.GRAVEL); playerBlocks.add(Material.GRAVEL);
playerBlocks.add(Material.EMERALD_BLOCK); playerBlocks.add(Material.EMERALD_BLOCK);
playerBlocks.add(Material.SANDSTONE); playerBlocks.add(Material.SANDSTONE);
playerBlocks.add(Material.WOOD_STEP);
playerBlocks.add(Material.WOOD_DOUBLE_STEP);
playerBlocks.add(Material.ENDER_CHEST); playerBlocks.add(Material.ENDER_CHEST);
playerBlocks.add(Material.SANDSTONE_STAIRS); playerBlocks.add(Material.SANDSTONE_STAIRS);
playerBlocks.add(Material.SPRUCE_WOOD_STAIRS); playerBlocks.add(Material.COMMAND_BLOCK);
playerBlocks.add(Material.JUNGLE_WOOD_STAIRS); playerBlocks.add(Material.REPEATING_COMMAND_BLOCK);
playerBlocks.add(Material.COMMAND); playerBlocks.add(Material.CHAIN_COMMAND_BLOCK);
playerBlocks.add(Material.BEACON); playerBlocks.add(Material.BEACON);
playerBlocks.add(Material.COBBLE_WALL); playerBlocks.add(Material.COBBLESTONE_WALL);
playerBlocks.add(Material.MOSSY_COBBLESTONE_WALL);
playerBlocks.add(Material.FLOWER_POT); playerBlocks.add(Material.FLOWER_POT);
playerBlocks.add(Material.CARROT); playerBlocks.add(Material.CARROT);
playerBlocks.add(Material.POTATO); playerBlocks.add(Material.POTATO);
playerBlocks.add(Material.WOOD_BUTTON); playerBlocks.add(Material.OAK_BUTTON);
playerBlocks.add(Material.SKULL); playerBlocks.add(Material.SPRUCE_BUTTON);
playerBlocks.add(Material.BIRCH_BUTTON);
playerBlocks.add(Material.JUNGLE_BUTTON);
playerBlocks.add(Material.ACACIA_BUTTON);
playerBlocks.add(Material.DARK_OAK_BUTTON);
playerBlocks.add(Material.SKELETON_SKULL);
playerBlocks.add(Material.WITHER_SKELETON_SKULL);
playerBlocks.add(Material.CREEPER_HEAD);
playerBlocks.add(Material.ZOMBIE_HEAD);
playerBlocks.add(Material.PLAYER_HEAD);
playerBlocks.add(Material.DRAGON_HEAD);
playerBlocks.add(Material.ANVIL); playerBlocks.add(Material.ANVIL);
playerBlocks.add(Material.SPONGE); playerBlocks.add(Material.SPONGE);
playerBlocks.add(Material.DOUBLE_STONE_SLAB2); playerBlocks.add(Material.WHITE_STAINED_GLASS);
playerBlocks.add(Material.STAINED_GLASS); playerBlocks.add(Material.ORANGE_STAINED_GLASS);
playerBlocks.add(Material.STAINED_GLASS_PANE); playerBlocks.add(Material.MAGENTA_STAINED_GLASS);
playerBlocks.add(Material.BANNER); playerBlocks.add(Material.LIGHT_BLUE_STAINED_GLASS);
playerBlocks.add(Material.STANDING_BANNER); playerBlocks.add(Material.YELLOW_STAINED_GLASS);
playerBlocks.add(Material.ACACIA_STAIRS); playerBlocks.add(Material.LIME_STAINED_GLASS);
playerBlocks.add(Material.BIRCH_WOOD_STAIRS); playerBlocks.add(Material.PINK_STAINED_GLASS);
playerBlocks.add(Material.DARK_OAK_STAIRS); playerBlocks.add(Material.GRAY_STAINED_GLASS);
playerBlocks.add(Material.LIGHT_GRAY_STAINED_GLASS);
playerBlocks.add(Material.CYAN_STAINED_GLASS);
playerBlocks.add(Material.PURPLE_STAINED_GLASS);
playerBlocks.add(Material.BLUE_STAINED_GLASS);
playerBlocks.add(Material.BROWN_STAINED_GLASS);
playerBlocks.add(Material.GREEN_STAINED_GLASS);
playerBlocks.add(Material.RED_STAINED_GLASS);
playerBlocks.add(Material.BLACK_STAINED_GLASS);
playerBlocks.add(Material.WHITE_STAINED_GLASS_PANE);
playerBlocks.add(Material.ORANGE_STAINED_GLASS_PANE);
playerBlocks.add(Material.MAGENTA_STAINED_GLASS_PANE);
playerBlocks.add(Material.LIGHT_BLUE_STAINED_GLASS_PANE);
playerBlocks.add(Material.YELLOW_STAINED_GLASS_PANE);
playerBlocks.add(Material.LIME_STAINED_GLASS_PANE);
playerBlocks.add(Material.PINK_STAINED_GLASS_PANE);
playerBlocks.add(Material.GRAY_STAINED_GLASS_PANE);
playerBlocks.add(Material.LIGHT_GRAY_STAINED_GLASS_PANE);
playerBlocks.add(Material.CYAN_STAINED_GLASS_PANE);
playerBlocks.add(Material.PURPLE_STAINED_GLASS_PANE);
playerBlocks.add(Material.BLUE_STAINED_GLASS_PANE);
playerBlocks.add(Material.BROWN_STAINED_GLASS_PANE);
playerBlocks.add(Material.GREEN_STAINED_GLASS_PANE);
playerBlocks.add(Material.RED_STAINED_GLASS_PANE);
playerBlocks.add(Material.BLACK_STAINED_GLASS_PANE);
playerBlocks.add(Material.WHITE_BANNER);
playerBlocks.add(Material.ORANGE_BANNER);
playerBlocks.add(Material.MAGENTA_BANNER);
playerBlocks.add(Material.LIGHT_BLUE_BANNER);
playerBlocks.add(Material.YELLOW_BANNER);
playerBlocks.add(Material.LIME_BANNER);
playerBlocks.add(Material.PINK_BANNER);
playerBlocks.add(Material.GRAY_BANNER);
playerBlocks.add(Material.LIGHT_GRAY_BANNER);
playerBlocks.add(Material.CYAN_BANNER);
playerBlocks.add(Material.PURPLE_BANNER);
playerBlocks.add(Material.BLUE_BANNER);
playerBlocks.add(Material.BROWN_BANNER);
playerBlocks.add(Material.GREEN_BANNER);
playerBlocks.add(Material.RED_BANNER);
playerBlocks.add(Material.BLACK_BANNER);
playerBlocks.add(Material.TRAPPED_CHEST); playerBlocks.add(Material.TRAPPED_CHEST);
playerBlocks.add(Material.GOLD_PLATE); playerBlocks.add(Material.LIGHT_WEIGHTED_PRESSURE_PLATE);
playerBlocks.add(Material.IRON_PLATE); playerBlocks.add(Material.HEAVY_WEIGHTED_PRESSURE_PLATE);
playerBlocks.add(Material.REDSTONE_COMPARATOR_OFF); playerBlocks.add(Material.COMPARATOR);
playerBlocks.add(Material.REDSTONE_COMPARATOR_ON);
playerBlocks.add(Material.DAYLIGHT_DETECTOR); playerBlocks.add(Material.DAYLIGHT_DETECTOR);
playerBlocks.add(Material.DAYLIGHT_DETECTOR_INVERTED);
playerBlocks.add(Material.REDSTONE_BLOCK); playerBlocks.add(Material.REDSTONE_BLOCK);
playerBlocks.add(Material.HOPPER); playerBlocks.add(Material.HOPPER);
playerBlocks.add(Material.QUARTZ_BLOCK); playerBlocks.add(Material.QUARTZ_BLOCK);
@ -743,10 +883,24 @@ class RestoreNatureProcessingTask implements Runnable
playerBlocks.add(Material.IRON_TRAPDOOR); playerBlocks.add(Material.IRON_TRAPDOOR);
playerBlocks.add(Material.PRISMARINE); playerBlocks.add(Material.PRISMARINE);
playerBlocks.add(Material.HAY_BLOCK); playerBlocks.add(Material.HAY_BLOCK);
playerBlocks.add(Material.CARPET); playerBlocks.add(Material.WHITE_CARPET);
playerBlocks.add(Material.ORANGE_CARPET);
playerBlocks.add(Material.MAGENTA_CARPET);
playerBlocks.add(Material.LIGHT_BLUE_CARPET);
playerBlocks.add(Material.YELLOW_CARPET);
playerBlocks.add(Material.LIME_CARPET);
playerBlocks.add(Material.PINK_CARPET);
playerBlocks.add(Material.GRAY_CARPET);
playerBlocks.add(Material.LIGHT_GRAY_CARPET);
playerBlocks.add(Material.CYAN_CARPET);
playerBlocks.add(Material.PURPLE_CARPET);
playerBlocks.add(Material.BLUE_CARPET);
playerBlocks.add(Material.BROWN_CARPET);
playerBlocks.add(Material.GREEN_CARPET);
playerBlocks.add(Material.RED_CARPET);
playerBlocks.add(Material.BLACK_CARPET);
playerBlocks.add(Material.SEA_LANTERN); playerBlocks.add(Material.SEA_LANTERN);
playerBlocks.add(Material.RED_SANDSTONE_STAIRS); playerBlocks.add(Material.RED_SANDSTONE_STAIRS);
playerBlocks.add(Material.STONE_SLAB2);
playerBlocks.add(Material.ACACIA_FENCE); playerBlocks.add(Material.ACACIA_FENCE);
playerBlocks.add(Material.ACACIA_FENCE_GATE); playerBlocks.add(Material.ACACIA_FENCE_GATE);
playerBlocks.add(Material.BIRCH_FENCE); playerBlocks.add(Material.BIRCH_FENCE);
@ -754,25 +908,23 @@ class RestoreNatureProcessingTask implements Runnable
playerBlocks.add(Material.DARK_OAK_FENCE); playerBlocks.add(Material.DARK_OAK_FENCE);
playerBlocks.add(Material.DARK_OAK_FENCE_GATE); playerBlocks.add(Material.DARK_OAK_FENCE_GATE);
playerBlocks.add(Material.JUNGLE_FENCE); playerBlocks.add(Material.JUNGLE_FENCE);
playerBlocks.add(Material.JUNGLE_FENCE_GATE); playerBlocks.add(Material.JUNGLE_FENCE_GATE);
playerBlocks.add(Material.SPRUCE_FENCE); playerBlocks.add(Material.SPRUCE_FENCE);
playerBlocks.add(Material.SPRUCE_FENCE_GATE); playerBlocks.add(Material.SPRUCE_FENCE_GATE);
playerBlocks.add(Material.ACACIA_DOOR); playerBlocks.add(Material.ACACIA_DOOR);
playerBlocks.add(Material.SPRUCE_DOOR); playerBlocks.add(Material.SPRUCE_DOOR);
playerBlocks.add(Material.DARK_OAK_DOOR); playerBlocks.add(Material.DARK_OAK_DOOR);
playerBlocks.add(Material.JUNGLE_DOOR); playerBlocks.add(Material.JUNGLE_DOOR);
playerBlocks.add(Material.BIRCH_DOOR); playerBlocks.add(Material.BIRCH_DOOR);
playerBlocks.add(Material.COAL_BLOCK); playerBlocks.add(Material.COAL_BLOCK);
playerBlocks.add(Material.REDSTONE_LAMP_OFF); playerBlocks.add(Material.REDSTONE_LAMP);
playerBlocks.add(Material.REDSTONE_LAMP_ON); playerBlocks.add(Material.PURPUR_BLOCK);
playerBlocks.add(Material.PURPUR_BLOCK); playerBlocks.add(Material.PURPUR_SLAB);
playerBlocks.add(Material.PURPUR_SLAB); playerBlocks.add(Material.PURPUR_PILLAR);
playerBlocks.add(Material.PURPUR_DOUBLE_SLAB); playerBlocks.add(Material.PURPUR_STAIRS);
playerBlocks.add(Material.PURPUR_PILLAR); playerBlocks.add(Material.NETHER_WART_BLOCK);
playerBlocks.add(Material.PURPUR_STAIRS); playerBlocks.add(Material.RED_NETHER_BRICKS);
playerBlocks.add(Material.NETHER_WART_BLOCK); playerBlocks.add(Material.BONE_BLOCK);
playerBlocks.add(Material.RED_NETHER_BRICK);
playerBlocks.add(Material.BONE_BLOCK);
//these are unnatural in the standard world, but not in the nether //these are unnatural in the standard world, but not in the nether
if(environment != Environment.NETHER) if(environment != Environment.NETHER)
@ -781,28 +933,36 @@ class RestoreNatureProcessingTask implements Runnable
playerBlocks.add(Material.SOUL_SAND); playerBlocks.add(Material.SOUL_SAND);
playerBlocks.add(Material.GLOWSTONE); playerBlocks.add(Material.GLOWSTONE);
playerBlocks.add(Material.NETHER_BRICK); playerBlocks.add(Material.NETHER_BRICK);
playerBlocks.add(Material.NETHER_FENCE); playerBlocks.add(Material.NETHER_BRICK_FENCE);
playerBlocks.add(Material.NETHER_BRICK_STAIRS); playerBlocks.add(Material.NETHER_BRICK_STAIRS);
playerBlocks.add(Material.MAGMA); playerBlocks.add(Material.MAGMA_BLOCK);
} }
//these are unnatural in the standard and nether worlds, but not in the end //these are unnatural in the standard and nether worlds, but not in the end
if(environment != Environment.THE_END) if(environment != Environment.THE_END)
{ {
playerBlocks.add(Material.OBSIDIAN); playerBlocks.add(Material.OBSIDIAN);
playerBlocks.add(Material.ENDER_STONE); playerBlocks.add(Material.END_STONE);
playerBlocks.add(Material.ENDER_PORTAL_FRAME); playerBlocks.add(Material.END_PORTAL_FRAME);
playerBlocks.add(Material.CHORUS_PLANT); playerBlocks.add(Material.CHORUS_PLANT);
playerBlocks.add(Material.CHORUS_FLOWER); playerBlocks.add(Material.CHORUS_FLOWER);
} }
//these are unnatural in sandy biomes, but not elsewhere //these are unnatural in sandy biomes, but not elsewhere
if(biome == Biome.DESERT || biome == Biome.DESERT_HILLS || biome == Biome.BEACHES || environment != Environment.NORMAL) if(biome == Biome.DESERT || biome == Biome.DESERT_HILLS || biome == Biome.BEACH || environment != Environment.NORMAL)
{ {
playerBlocks.add(Material.LEAVES); playerBlocks.add(Material.OAK_LEAVES);
playerBlocks.add(Material.LEAVES_2); playerBlocks.add(Material.SPRUCE_LEAVES);
playerBlocks.add(Material.LOG); playerBlocks.add(Material.BIRCH_LEAVES);
playerBlocks.add(Material.LOG_2); playerBlocks.add(Material.JUNGLE_LEAVES);
playerBlocks.add(Material.ACACIA_LEAVES);
playerBlocks.add(Material.DARK_OAK_LEAVES);
playerBlocks.add(Material.OAK_LOG);
playerBlocks.add(Material.SPRUCE_LOG);
playerBlocks.add(Material.BIRCH_LOG);
playerBlocks.add(Material.JUNGLE_LOG);
playerBlocks.add(Material.ACACIA_LOG);
playerBlocks.add(Material.DARK_OAK_LOG);
} }
return playerBlocks; return playerBlocks;

View File

@ -25,6 +25,8 @@ import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Lightable;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
//represents a visualization sent to a player //represents a visualization sent to a player
@ -54,7 +56,7 @@ public class Visualization
//reverts a visualization by sending another block change list, this time with the real world block values //reverts a visualization by sending another block change list, this time with the real world block values
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static void Revert(Player player) public static void Revert(Player player)
{ {
if(!player.isOnline()) return; if(!player.isOnline()) return;
@ -64,29 +66,29 @@ public class Visualization
if(playerData.currentVisualization != null) if(playerData.currentVisualization != null)
{ {
//locality //locality
int minx = player.getLocation().getBlockX() - 100; int minx = player.getLocation().getBlockX() - 100;
int minz = player.getLocation().getBlockZ() - 100; int minz = player.getLocation().getBlockZ() - 100;
int maxx = player.getLocation().getBlockX() + 100; int maxx = player.getLocation().getBlockX() + 100;
int maxz = player.getLocation().getBlockZ() + 100; int maxz = player.getLocation().getBlockZ() + 100;
//remove any elements which are too far away //remove any elements which are too far away
visualization.removeElementsOutOfRange(visualization.elements, minx, minz, maxx, maxz); visualization.removeElementsOutOfRange(visualization.elements, minx, minz, maxx, maxz);
//send real block information for any remaining elements //send real block information for any remaining elements
for(int i = 0; i < visualization.elements.size(); i++) for(int i = 0; i < visualization.elements.size(); i++)
{ {
VisualizationElement element = visualization.elements.get(i); VisualizationElement element = visualization.elements.get(i);
//check player still in world where visualization exists //check player still in world where visualization exists
if(i == 0) if(i == 0)
{ {
if(!player.getWorld().equals(element.location.getWorld())) return; if(!player.getWorld().equals(element.location.getWorld())) return;
} }
player.sendBlockChange(element.location, element.realMaterial, element.realData); player.sendBlockChange(element.location, element.realBlock);
} }
playerData.currentVisualization = null; playerData.currentVisualization = null;
} }
} }
@ -127,51 +129,52 @@ public class Visualization
//handy for combining several visualizations together, as when visualization a top level claim with several subdivisions inside //handy for combining several visualizations together, as when visualization a top level claim with several subdivisions inside
//locality is a performance consideration. only create visualization blocks for around 100 blocks of the locality //locality is a performance consideration. only create visualization blocks for around 100 blocks of the locality
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void addClaimElements(Claim claim, int height, VisualizationType visualizationType, Location locality) private void addClaimElements(Claim claim, int height, VisualizationType visualizationType, Location locality)
{ {
Location smallXsmallZ = claim.getLesserBoundaryCorner(); Location smallXsmallZ = claim.getLesserBoundaryCorner();
Location bigXbigZ = claim.getGreaterBoundaryCorner(); Location bigXbigZ = claim.getGreaterBoundaryCorner();
World world = smallXsmallZ.getWorld(); World world = smallXsmallZ.getWorld();
boolean waterIsTransparent = locality.getBlock().getType() == Material.STATIONARY_WATER; boolean waterIsTransparent = locality.getBlock().getType() == Material.WATER;
int smallx = smallXsmallZ.getBlockX(); int smallx = smallXsmallZ.getBlockX();
int smallz = smallXsmallZ.getBlockZ(); int smallz = smallXsmallZ.getBlockZ();
int bigx = bigXbigZ.getBlockX(); int bigx = bigXbigZ.getBlockX();
int bigz = bigXbigZ.getBlockZ(); int bigz = bigXbigZ.getBlockZ();
Material cornerMaterial; BlockData cornerBlockData;
Material accentMaterial; BlockData accentBlockData;
ArrayList<VisualizationElement> newElements = new ArrayList<VisualizationElement>(); ArrayList<VisualizationElement> newElements = new ArrayList<VisualizationElement>();
if(visualizationType == VisualizationType.Claim) if(visualizationType == VisualizationType.Claim)
{ {
cornerMaterial = Material.GLOWSTONE; cornerBlockData = Material.GLOWSTONE.createBlockData();
accentMaterial = Material.GOLD_BLOCK; accentBlockData = Material.GOLD_BLOCK.createBlockData();
} }
else if(visualizationType == VisualizationType.AdminClaim) else if(visualizationType == VisualizationType.AdminClaim)
{ {
cornerMaterial = Material.GLOWSTONE; cornerBlockData = Material.GLOWSTONE.createBlockData();
accentMaterial = Material.PUMPKIN; accentBlockData = Material.PUMPKIN.createBlockData();
} }
else if(visualizationType == VisualizationType.Subdivision) else if(visualizationType == VisualizationType.Subdivision)
{ {
cornerMaterial = Material.IRON_BLOCK; cornerBlockData = Material.IRON_BLOCK.createBlockData();
accentMaterial = Material.WOOL; accentBlockData = Material.WHITE_WOOL.createBlockData();
} }
else if(visualizationType == VisualizationType.RestoreNature) else if(visualizationType == VisualizationType.RestoreNature)
{ {
cornerMaterial = Material.DIAMOND_BLOCK; cornerBlockData = Material.DIAMOND_BLOCK.createBlockData();
accentMaterial = Material.DIAMOND_BLOCK; accentBlockData = Material.DIAMOND_BLOCK.createBlockData();
} }
else else
{ {
cornerMaterial = Material.GLOWING_REDSTONE_ORE; cornerBlockData = Material.REDSTONE_ORE.createBlockData();
accentMaterial = Material.NETHERRACK; ((Lightable) cornerBlockData).setLit(true);
accentBlockData = Material.NETHERRACK.createBlockData();
} }
//initialize visualization elements without Y values and real data //initialize visualization elements without Y values and real data
@ -186,46 +189,46 @@ public class Visualization
final int STEP = 10; final int STEP = 10;
//top line //top line
newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz), cornerMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz), cornerBlockData, Material.AIR.createBlockData()));
newElements.add(new VisualizationElement(new Location(world, smallx + 1, 0, bigz), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, smallx + 1, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
for(int x = smallx + STEP; x < bigx - STEP / 2; x += STEP) for(int x = smallx + STEP; x < bigx - STEP / 2; x += STEP)
{ {
if(x > minx && x < maxx) if(x > minx && x < maxx)
newElements.add(new VisualizationElement(new Location(world, x, 0, bigz), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, x, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
} }
newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, bigz), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
//bottom line //bottom line
newElements.add(new VisualizationElement(new Location(world, smallx + 1, 0, smallz), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, smallx + 1, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
for(int x = smallx + STEP; x < bigx - STEP / 2; x += STEP) for(int x = smallx + STEP; x < bigx - STEP / 2; x += STEP)
{ {
if(x > minx && x < maxx) if(x > minx && x < maxx)
newElements.add(new VisualizationElement(new Location(world, x, 0, smallz), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, x, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
} }
newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, smallz), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
//left line //left line
newElements.add(new VisualizationElement(new Location(world, smallx, 0, smallz), cornerMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, smallx, 0, smallz), cornerBlockData, Material.AIR.createBlockData()));
newElements.add(new VisualizationElement(new Location(world, smallx, 0, smallz + 1), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, smallx, 0, smallz + 1), accentBlockData, Material.AIR.createBlockData()));
for(int z = smallz + STEP; z < bigz - STEP / 2; z += STEP) for(int z = smallz + STEP; z < bigz - STEP / 2; z += STEP)
{ {
if(z > minz && z < maxz) if(z > minz && z < maxz)
newElements.add(new VisualizationElement(new Location(world, smallx, 0, z), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, smallx, 0, z), accentBlockData, Material.AIR.createBlockData()));
} }
newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz - 1), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz - 1), accentBlockData, Material.AIR.createBlockData()));
//right line //right line
newElements.add(new VisualizationElement(new Location(world, bigx, 0, smallz), cornerMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, bigx, 0, smallz), cornerBlockData, Material.AIR.createBlockData()));
newElements.add(new VisualizationElement(new Location(world, bigx, 0, smallz + 1), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, bigx, 0, smallz + 1), accentBlockData, Material.AIR.createBlockData()));
for(int z = smallz + STEP; z < bigz - STEP / 2; z += STEP) for(int z = smallz + STEP; z < bigz - STEP / 2; z += STEP)
{ {
if(z > minz && z < maxz) if(z > minz && z < maxz)
newElements.add(new VisualizationElement(new Location(world, bigx, 0, z), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, bigx, 0, z), accentBlockData, Material.AIR.createBlockData()));
} }
newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz - 1), accentMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz - 1), accentBlockData, Material.AIR.createBlockData()));
newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz), cornerMaterial, (byte)0, Material.AIR, (byte)0)); newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz), cornerBlockData, Material.AIR.createBlockData()));
//remove any out of range elements //remove any out of range elements
this.removeElementsOutOfRange(newElements, minx, minz, maxx, maxz); this.removeElementsOutOfRange(newElements, minx, minz, maxx, maxz);
//remove any elements outside the claim //remove any elements outside the claim
@ -244,8 +247,7 @@ public class Visualization
Location tempLocation = element.location; Location tempLocation = element.location;
element.location = getVisibleLocation(tempLocation.getWorld(), tempLocation.getBlockX(), height, tempLocation.getBlockZ(), waterIsTransparent); element.location = getVisibleLocation(tempLocation.getWorld(), tempLocation.getBlockX(), height, tempLocation.getBlockZ(), waterIsTransparent);
height = element.location.getBlockY(); height = element.location.getBlockY();
element.realMaterial = element.location.getBlock().getType(); element.realBlock = element.location.getBlock().getBlockData();
element.realData = element.location.getBlock().getData();
} }
this.elements.addAll(newElements); this.elements.addAll(newElements);
@ -265,7 +267,7 @@ public class Visualization
} }
//finds a block the player can probably see. this is how visualizations "cling" to the ground or ceiling //finds a block the player can probably see. this is how visualizations "cling" to the ground or ceiling
private static Location getVisibleLocation(World world, int x, int y, int z, boolean waterIsTransparent) private static Location getVisibleLocation(World world, int x, int y, int z, boolean waterIsTransparent)
{ {
Block block = world.getBlockAt(x, y, z); Block block = world.getBlockAt(x, y, z);
BlockFace direction = (isTransparent(block, waterIsTransparent)) ? BlockFace.DOWN : BlockFace.UP; BlockFace direction = (isTransparent(block, waterIsTransparent)) ? BlockFace.DOWN : BlockFace.UP;
@ -294,29 +296,26 @@ public class Visualization
switch (block.getType()) switch (block.getType())
{ {
case AIR: case AIR:
case FENCE: case OAK_FENCE:
case ACACIA_FENCE: case ACACIA_FENCE:
case BIRCH_FENCE: case BIRCH_FENCE:
case DARK_OAK_FENCE: case DARK_OAK_FENCE:
case JUNGLE_FENCE: case JUNGLE_FENCE:
case NETHER_FENCE: case NETHER_BRICK_FENCE:
case SPRUCE_FENCE: case SPRUCE_FENCE:
case FENCE_GATE: case OAK_FENCE_GATE:
case ACACIA_FENCE_GATE: case ACACIA_FENCE_GATE:
case BIRCH_FENCE_GATE: case BIRCH_FENCE_GATE:
case DARK_OAK_FENCE_GATE: case DARK_OAK_FENCE_GATE:
case SPRUCE_FENCE_GATE: case SPRUCE_FENCE_GATE:
case JUNGLE_FENCE_GATE: case JUNGLE_FENCE_GATE:
case SIGN: case SIGN:
case SIGN_POST:
case WALL_SIGN: case WALL_SIGN:
return true; return true;
} }
if ((waterIsTransparent && block.getType() == Material.STATIONARY_WATER) || return (waterIsTransparent && block.getType() == Material.WATER) ||
block.getType().isTransparent()) block.getType().isTransparent();
return true;
return false;
} }
public static Visualization fromClaims(Iterable<Claim> claims, int height, VisualizationType type, Location locality) public static Visualization fromClaims(Iterable<Claim> claims, int height, VisualizationType type, Location locality)

View File

@ -45,7 +45,7 @@ class VisualizationApplicationTask implements Runnable
//send the player a fake block change event //send the player a fake block change event
if(!element.location.getChunk().isLoaded()) continue; //cheap distance check if(!element.location.getChunk().isLoaded()) continue; //cheap distance check
player.sendBlockChange(element.location, element.visualizedMaterial, element.visualizedData); player.sendBlockChange(element.location, element.visualizedBlock);
} }
//remember the visualization applied to this player for later (so it can be inexpensively reverted) //remember the visualization applied to this player for later (so it can be inexpensively reverted)

View File

@ -19,22 +19,19 @@
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
//represents a "fake" block sent to a player as part of a visualization //represents a "fake" block sent to a player as part of a visualization
public class VisualizationElement public class VisualizationElement
{ {
public Location location; public Location location;
public Material visualizedMaterial; public BlockData visualizedBlock;
public byte visualizedData; public BlockData realBlock;
public Material realMaterial;
public byte realData;
public VisualizationElement(Location location, Material visualizedMaterial, byte visualizedData, Material realMaterial, byte realData) public VisualizationElement(Location location, BlockData visualizedBlock, BlockData realBlock)
{ {
this.location = location; this.location = location;
this.visualizedMaterial= visualizedMaterial; this.visualizedBlock = visualizedBlock;
this.visualizedData = visualizedData; this.realBlock = realBlock;
this.realData = realData;
this.realMaterial = realMaterial;
} }
} }

View File

@ -4,6 +4,7 @@ softdepend: [Vault, Multiverse-Core, My Worlds, MystCraft, Transporter, TheUnder
dev-url: http://dev.bukkit.org/server-mods/grief-prevention dev-url: http://dev.bukkit.org/server-mods/grief-prevention
loadbefore: [TheUnderground] loadbefore: [TheUnderground]
version: ${project.version} version: ${project.version}
api-version: 1.13
commands: commands:
abandonclaim: abandonclaim:
description: Deletes a claim. description: Deletes a claim.