6.9
This commit is contained in:
parent
6632af96df
commit
e09a6732ba
|
|
@ -2,7 +2,7 @@ name: GriefPrevention
|
|||
main: me.ryanhamshire.GriefPrevention.GriefPrevention
|
||||
softdepend: [Vault, Multiverse-Core, My Worlds, MystCraft, Transporter]
|
||||
dev-url: http://dev.bukkit.org/server-mods/grief-prevention
|
||||
version: 6.7
|
||||
version: 6.9
|
||||
commands:
|
||||
abandonclaim:
|
||||
description: Deletes a claim.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,10 @@ import org.bukkit.block.Block;
|
|||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Chest;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
|
@ -46,6 +49,7 @@ import org.bukkit.event.block.BlockPistonRetractEvent;
|
|||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.BlockSpreadEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
|
@ -77,6 +81,36 @@ public class BlockEventHandler implements Listener
|
|||
this.trashBlocks.add(Material.WORKBENCH);
|
||||
}
|
||||
|
||||
//when a wooden button is triggered by an arrow...
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onProjectileHit(ProjectileHitEvent event)
|
||||
{
|
||||
Projectile projectile = event.getEntity();
|
||||
Location location = projectile.getLocation();
|
||||
Block block = location.getBlock();
|
||||
|
||||
//only care about wooden buttons
|
||||
if(block.getType() != Material.WOOD_BUTTON) return;
|
||||
|
||||
//only care about arrows
|
||||
if(projectile instanceof Arrow)
|
||||
{
|
||||
Arrow arrow = (Arrow)projectile;
|
||||
LivingEntity shooterEntity = arrow.getShooter();
|
||||
|
||||
//player arrows only trigger buttons when they have permission
|
||||
if(shooterEntity instanceof Player)
|
||||
{
|
||||
//Player player = (Player)shooterEntity;
|
||||
}
|
||||
|
||||
//other arrows don't trigger buttons, could be used as a workaround to get access to areas without permission
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//when a block is damaged...
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBlockDamaged(BlockDamageEvent event)
|
||||
|
|
@ -377,7 +411,7 @@ public class BlockEventHandler implements Listener
|
|||
//warn players when they place TNT above sea level, since it doesn't destroy blocks there
|
||||
if( GriefPrevention.instance.config_blockSurfaceOtherExplosions && block.getType() == Material.TNT &&
|
||||
block.getWorld().getEnvironment() != Environment.NETHER &&
|
||||
block.getY() > block.getWorld().getSeaLevel() - 5)
|
||||
block.getY() > GriefPrevention.instance.getSeaLevel(block.getWorld()) - 5)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageAboveSeaLevel);
|
||||
}
|
||||
|
|
@ -514,11 +548,7 @@ public class BlockEventHandler implements Listener
|
|||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onBlockIgnite (BlockIgniteEvent igniteEvent)
|
||||
{
|
||||
if(!GriefPrevention.instance.config_fireSpreads &&
|
||||
igniteEvent.getBlock().getWorld().getEnvironment() == Environment.NORMAL &&
|
||||
igniteEvent.getCause() != IgniteCause.FLINT_AND_STEEL &&
|
||||
igniteEvent.getCause() != IgniteCause.LIGHTNING &&
|
||||
igniteEvent.getCause() != IgniteCause.LAVA)
|
||||
if(!GriefPrevention.instance.config_fireSpreads && igniteEvent.getCause() != IgniteCause.FLINT_AND_STEEL && igniteEvent.getCause() != IgniteCause.LIGHTNING)
|
||||
{
|
||||
igniteEvent.setCancelled(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ public class Claim
|
|||
int seaLevel = 0; //clean up all fluids in the end
|
||||
|
||||
//respect sea level in normal worlds
|
||||
if(lesser.getWorld().getEnvironment() == Environment.NORMAL) seaLevel = lesser.getWorld().getSeaLevel();
|
||||
if(lesser.getWorld().getEnvironment() == Environment.NORMAL) seaLevel = GriefPrevention.instance.getSeaLevel(lesser.getWorld());
|
||||
|
||||
for(int x = lesser.getBlockX(); x <= greater.getBlockX(); x++)
|
||||
{
|
||||
|
|
@ -165,7 +165,7 @@ public class Claim
|
|||
int seaLevel = 0; //clean up all fluids in the end
|
||||
|
||||
//respect sea level in normal worlds
|
||||
if(lesser.getWorld().getEnvironment() == Environment.NORMAL) seaLevel = lesser.getWorld().getSeaLevel();
|
||||
if(lesser.getWorld().getEnvironment() == Environment.NORMAL) seaLevel = GriefPrevention.instance.getSeaLevel(lesser.getWorld());
|
||||
|
||||
int waterCount = 0;
|
||||
for(int x = lesser.getBlockX(); x <= greater.getBlockX(); x++)
|
||||
|
|
@ -362,7 +362,10 @@ public class Claim
|
|||
return this.parent.allowBuild(player);
|
||||
|
||||
//failure message for all other cases
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildPermission, this.getOwnerName());
|
||||
String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildPermission, this.getOwnerName());
|
||||
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||
reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||
return reason;
|
||||
}
|
||||
|
||||
private boolean hasExplicitPermission(Player player, ClaimPermission level)
|
||||
|
|
@ -458,7 +461,10 @@ public class Claim
|
|||
return this.parent.allowAccess(player);
|
||||
|
||||
//catch-all error message for all other cases
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoAccessPermission, this.getOwnerName());
|
||||
String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoAccessPermission, this.getOwnerName());
|
||||
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||
reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||
return reason;
|
||||
}
|
||||
|
||||
//inventory permission check
|
||||
|
|
@ -498,7 +504,10 @@ public class Claim
|
|||
return this.parent.allowContainers(player);
|
||||
|
||||
//error message for all other cases
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoContainersPermission, this.getOwnerName());
|
||||
String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoContainersPermission, this.getOwnerName());
|
||||
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||
reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||
return reason;
|
||||
}
|
||||
|
||||
//grant permission check, relatively simple
|
||||
|
|
@ -529,7 +538,10 @@ public class Claim
|
|||
return this.parent.allowGrantPermission(player);
|
||||
|
||||
//generic error message
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoPermissionTrust, this.getOwnerName());
|
||||
String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoPermissionTrust, this.getOwnerName());
|
||||
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||
reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||
return reason;
|
||||
}
|
||||
|
||||
//grants a permission for a player or the public
|
||||
|
|
@ -778,7 +790,7 @@ public class Claim
|
|||
for(int z = this.lesserBoundaryCorner.getBlockZ(); z <= this.greaterBoundaryCorner.getBlockZ(); z++)
|
||||
{
|
||||
int y = this.lesserBoundaryCorner.getBlockY();
|
||||
for(; y < this.lesserBoundaryCorner.getWorld().getSeaLevel(); y++)
|
||||
for(; y < GriefPrevention.instance.getSeaLevel(this.lesserBoundaryCorner.getWorld()) - 5; y++)
|
||||
{
|
||||
Block block = this.lesserBoundaryCorner.getWorld().getBlockAt(x, y, z);
|
||||
if(playerBlocks.contains(block.getTypeId()))
|
||||
|
|
@ -789,7 +801,7 @@ public class Claim
|
|||
}
|
||||
else
|
||||
{
|
||||
score += .2;
|
||||
score += .5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
import java.util.Calendar;
|
||||
import java.util.Random;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
|
|
@ -63,6 +64,9 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
//skip administrative claims
|
||||
if(claim.isAdminClaim()) return;
|
||||
|
||||
//track whether we do any important work which would require cleanup afterward
|
||||
boolean cleanupChunks = false;
|
||||
|
||||
//get data for the player, especially last login timestamp
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(claim.ownerName);
|
||||
|
||||
|
|
@ -75,20 +79,21 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
|
||||
//if he's been gone at least a week, if he has ONLY the new player claim, it will be removed
|
||||
Calendar sevenDaysAgo = Calendar.getInstance();
|
||||
sevenDaysAgo.add(Calendar.DATE, -7);
|
||||
sevenDaysAgo.add(Calendar.DATE, -GriefPrevention.instance.config_claims_chestClaimExpirationDays);
|
||||
boolean newPlayerClaimsExpired = sevenDaysAgo.getTime().after(playerData.lastLogin);
|
||||
|
||||
//if only one claim, and the player hasn't played in a week
|
||||
if(newPlayerClaimsExpired && playerData.claims.size() == 1)
|
||||
{
|
||||
//if that's a chest claim, delete it
|
||||
if(claim.getArea() <= areaOfDefaultClaim)
|
||||
//if that's a chest claim and those are set to expire
|
||||
if(claim.getArea() <= areaOfDefaultClaim && GriefPrevention.instance.config_claims_chestClaimExpirationDays > 0)
|
||||
{
|
||||
claim.removeSurfaceFluids(null);
|
||||
GriefPrevention.instance.dataStore.deleteClaim(claim);
|
||||
cleanupChunks = true;
|
||||
|
||||
//if in a creative mode world, delete the claim
|
||||
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
|
||||
//if configured to do so, restore the land to natural
|
||||
if((GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()) && GriefPrevention.instance.config_claims_creativeAutoNatureRestoration) || GriefPrevention.instance.config_claims_survivalAutoNatureRestoration)
|
||||
{
|
||||
GriefPrevention.instance.restoreClaim(claim, 0);
|
||||
}
|
||||
|
|
@ -105,18 +110,35 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
|
||||
if(earliestPermissibleLastLogin.getTime().after(playerData.lastLogin))
|
||||
{
|
||||
//make a copy of this player's claim list
|
||||
Vector<Claim> claims = new Vector<Claim>();
|
||||
for(int i = 0; i < playerData.claims.size(); i++)
|
||||
{
|
||||
claims.add(playerData.claims.get(i));
|
||||
}
|
||||
|
||||
//delete them
|
||||
GriefPrevention.instance.dataStore.deleteClaimsForPlayer(claim.getOwnerName(), true);
|
||||
GriefPrevention.AddLogEntry(" All of " + claim.getOwnerName() + "'s claims have expired.");
|
||||
|
||||
for(int i = 0; i < claims.size(); i++)
|
||||
{
|
||||
//if configured to do so, restore the land to natural
|
||||
if((GriefPrevention.instance.creativeRulesApply(claims.get(i).getLesserBoundaryCorner()) && GriefPrevention.instance.config_claims_creativeAutoNatureRestoration) || GriefPrevention.instance.config_claims_survivalAutoNatureRestoration)
|
||||
{
|
||||
GriefPrevention.instance.restoreClaim(claims.get(i), 0);
|
||||
cleanupChunks = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
else if(GriefPrevention.instance.config_claims_unusedClaimExpirationDays > 0)
|
||||
{
|
||||
|
||||
//if the player has been gone two weeks, scan claim content to assess player investment
|
||||
Calendar fourteenDaysAgo = Calendar.getInstance();
|
||||
fourteenDaysAgo.add(Calendar.DATE, -14);
|
||||
boolean needsInvestmentScan = fourteenDaysAgo.getTime().after(playerData.lastLogin);
|
||||
Calendar earliestAllowedLoginDate = Calendar.getInstance();
|
||||
earliestAllowedLoginDate.add(Calendar.DATE, -GriefPrevention.instance.config_claims_unusedClaimExpirationDays);
|
||||
boolean needsInvestmentScan = earliestAllowedLoginDate.getTime().after(playerData.lastLogin);
|
||||
|
||||
//avoid scanning large claims and administrative claims
|
||||
if(claim.isAdminClaim() || claim.getWidth() > 25 || claim.getHeight() > 25) return;
|
||||
|
|
@ -131,10 +153,11 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
}
|
||||
else
|
||||
{
|
||||
minInvestment = 200;
|
||||
minInvestment = 100;
|
||||
}
|
||||
|
||||
long investmentScore = claim.getPlayerInvestmentScore();
|
||||
cleanupChunks = true;
|
||||
boolean removeClaim = false;
|
||||
|
||||
//in creative mode, a build which is almost entirely lava above sea level will be automatically removed, even if the owner is an active player
|
||||
|
|
@ -156,8 +179,8 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
GriefPrevention.instance.dataStore.deleteClaim(claim);
|
||||
GriefPrevention.AddLogEntry("Removed " + claim.getOwnerName() + "'s unused claim @ " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()));
|
||||
|
||||
//if in a creative mode world, restore the claim area
|
||||
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
|
||||
//if configured to do so, restore the claim area to natural state
|
||||
if((GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()) && GriefPrevention.instance.config_claims_creativeAutoNatureRestoration) || GriefPrevention.instance.config_claims_survivalAutoNatureRestoration)
|
||||
{
|
||||
GriefPrevention.instance.restoreClaim(claim, 0);
|
||||
}
|
||||
|
|
@ -172,8 +195,7 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
}
|
||||
|
||||
//since we're potentially loading a lot of chunks to scan parts of the world where there are no players currently playing, be mindful of memory usage
|
||||
//unfortunately, java/minecraft don't do a good job of clearing unused memory, leading to out of memory errors from this type of world scanning
|
||||
if(this.nextClaimIndex % 20 == 0)
|
||||
if(cleanupChunks)
|
||||
{
|
||||
World world = claim.getLesserBoundaryCorner().getWorld();
|
||||
Chunk [] chunks = world.getLoadedChunks();
|
||||
|
|
@ -182,7 +204,11 @@ class CleanupUnusedClaimsTask implements Runnable
|
|||
Chunk chunk = chunks[i];
|
||||
chunk.unload(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
//unfortunately, java/minecraft don't do a good job of clearing unused memory, leading to out of memory errors from this type of world scanning
|
||||
if(this.nextClaimIndex % 10 == 0)
|
||||
{
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -960,6 +960,7 @@ public abstract class DataStore
|
|||
this.addDefault(defaults, Messages.NoTeleportPvPCombat, "You can't teleport while fighting another player.", null);
|
||||
this.addDefault(defaults, Messages.NoTNTDamageAboveSeaLevel, "Warning: TNT will not destroy blocks above sea level.", null);
|
||||
this.addDefault(defaults, Messages.NoTNTDamageClaims, "Warning: TNT will not destroy claimed blocks.", null);
|
||||
this.addDefault(defaults, Messages.IgnoreClaimsAdvertisement, "To override, use /IgnoreClaims.", null);
|
||||
|
||||
//load the config file
|
||||
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath));
|
||||
|
|
|
|||
|
|
@ -50,9 +50,9 @@ import org.bukkit.event.entity.EntityExplodeEvent;
|
|||
import org.bukkit.event.entity.EntityInteractEvent;
|
||||
import org.bukkit.event.entity.ExpBottleEvent;
|
||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
|
||||
import org.bukkit.event.painting.PaintingBreakEvent;
|
||||
import org.bukkit.event.painting.PaintingPlaceEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakEvent;
|
||||
import org.bukkit.event.hanging.HangingPlaceEvent;
|
||||
import org.bukkit.event.vehicle.VehicleDamageEvent;
|
||||
|
||||
//handles events related to entities
|
||||
|
|
@ -74,6 +74,12 @@ class EntityEventHandler implements Listener
|
|||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
//don't allow the wither to break blocks, when the wither is determined, too expensive to constantly check for claimed blocks
|
||||
else if(event.getEntityType() == EntityType.WITHER)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
//don't allow zombies to break down doors
|
||||
|
|
@ -109,7 +115,7 @@ class EntityEventHandler implements Listener
|
|||
Block block = blocks.get(i);
|
||||
if(GriefPrevention.instance.config_mods_explodableIds.Contains(new MaterialInfo(block.getTypeId(), block.getData(), null))) continue;
|
||||
|
||||
if(block.getLocation().getBlockY() > location.getWorld().getSeaLevel() - 7)
|
||||
if(block.getLocation().getBlockY() > GriefPrevention.instance.getSeaLevel(location.getWorld()) - 7)
|
||||
{
|
||||
blocks.remove(i--);
|
||||
}
|
||||
|
|
@ -252,18 +258,18 @@ class EntityEventHandler implements Listener
|
|||
|
||||
//when a painting is broken
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPaintingBreak(PaintingBreakEvent event)
|
||||
public void onHangingBreak(HangingBreakEvent event)
|
||||
{
|
||||
//FEATURE: claimed paintings are protected from breakage
|
||||
|
||||
//only allow players to break paintings, not anything else (like water and explosions)
|
||||
if(!(event instanceof PaintingBreakByEntityEvent))
|
||||
if(!(event instanceof HangingBreakByEntityEvent))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
PaintingBreakByEntityEvent entityEvent = (PaintingBreakByEntityEvent)event;
|
||||
HangingBreakByEntityEvent entityEvent = (HangingBreakByEntityEvent)event;
|
||||
|
||||
//who is removing it?
|
||||
Entity remover = entityEvent.getRemover();
|
||||
|
|
@ -277,7 +283,7 @@ class EntityEventHandler implements Listener
|
|||
|
||||
//if the player doesn't have build permission, don't allow the breakage
|
||||
Player playerRemover = (Player)entityEvent.getRemover();
|
||||
String noBuildReason = GriefPrevention.instance.allowBuild(playerRemover, event.getPainting().getLocation());
|
||||
String noBuildReason = GriefPrevention.instance.allowBuild(playerRemover, event.getEntity().getLocation());
|
||||
if(noBuildReason != null)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
|
|
@ -287,12 +293,12 @@ class EntityEventHandler implements Listener
|
|||
|
||||
//when a painting is placed...
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPaintingPlace(PaintingPlaceEvent event)
|
||||
public void onPaintingPlace(HangingPlaceEvent event)
|
||||
{
|
||||
//FEATURE: similar to above, placing a painting requires build permission in the claim
|
||||
|
||||
//if the player doesn't have permission, don't allow the placement
|
||||
String noBuildReason = GriefPrevention.instance.allowBuild(event.getPlayer(), event.getPainting().getLocation());
|
||||
String noBuildReason = GriefPrevention.instance.allowBuild(event.getPlayer(), event.getEntity().getLocation());
|
||||
if(noBuildReason != null)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
|
|
@ -301,7 +307,7 @@ class EntityEventHandler implements Listener
|
|||
}
|
||||
|
||||
//otherwise, apply entity-count limitations for creative worlds
|
||||
else if(GriefPrevention.instance.creativeRulesApply(event.getPainting().getLocation()))
|
||||
else if(GriefPrevention.instance.creativeRulesApply(event.getEntity().getLocation()))
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
|
||||
Claim claim = this.dataStore.getClaimAt(event.getBlock().getLocation(), false, playerData.lastClaim);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
GriefPrevention Server Plugin for Minecraft
|
||||
Copyright (C) 2011 Ryan Hamshire
|
||||
Copyright (C) 2012 Ryan Hamshire
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -85,6 +85,11 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
public boolean config_claims_noBuildOutsideClaims; //whether players can build in survival worlds outside their claimed areas
|
||||
|
||||
public int config_claims_chestClaimExpirationDays; //number of days of inactivity before an automatic chest claim will be deleted
|
||||
public int config_claims_unusedClaimExpirationDays; //number of days of inactivity before an unused (nothing build) claim will be deleted
|
||||
public boolean config_claims_survivalAutoNatureRestoration; //whether survival claims will be automatically restored to nature when auto-deleted
|
||||
public boolean config_claims_creativeAutoNatureRestoration; //whether creative claims will be automatically restored to nature when auto-deleted
|
||||
|
||||
public int config_claims_trappedCooldownHours; //number of hours between uses of the /trapped command
|
||||
|
||||
public Material config_claims_investigationTool; //which material will be used to investigate claims with a right click
|
||||
|
|
@ -256,12 +261,26 @@ public class GriefPrevention extends JavaPlugin
|
|||
this.config_claims_creationRequiresPermission = config.getBoolean("GriefPrevention.Claims.CreationRequiresPermission", false);
|
||||
this.config_claims_minSize = config.getInt("GriefPrevention.Claims.MinimumSize", 10);
|
||||
this.config_claims_maxDepth = config.getInt("GriefPrevention.Claims.MaximumDepth", 0);
|
||||
this.config_claims_expirationDays = config.getInt("GriefPrevention.Claims.IdleLimitDays", 0);
|
||||
this.config_claims_trappedCooldownHours = config.getInt("GriefPrevention.Claims.TrappedCommandCooldownHours", 8);
|
||||
this.config_claims_noBuildOutsideClaims = config.getBoolean("GriefPrevention.Claims.NoSurvivalBuildingOutsideClaims", false);
|
||||
this.config_claims_warnOnBuildOutside = config.getBoolean("GriefPrevention.Claims.WarnWhenBuildingOutsideClaims", true);
|
||||
this.config_claims_allowUnclaimInCreative = config.getBoolean("GriefPrevention.Claims.AllowUnclaimingCreativeModeLand", true);
|
||||
|
||||
this.config_claims_chestClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.ChestClaimDays", 7);
|
||||
config.set("GriefPrevention.Claims.Expiration.ChestClaimDays", this.config_claims_chestClaimExpirationDays);
|
||||
|
||||
this.config_claims_unusedClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.UnusedClaimDays", 14);
|
||||
config.set("GriefPrevention.Claims.Expiration.UnusedClaimDays", this.config_claims_unusedClaimExpirationDays);
|
||||
|
||||
this.config_claims_expirationDays = config.getInt("GriefPrevention.Claims.Expiration.AllClaimDays", 0);
|
||||
config.set("GriefPrevention.Claims.Expiration.AllClaimDays", this.config_claims_expirationDays);
|
||||
|
||||
this.config_claims_survivalAutoNatureRestoration = config.getBoolean("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", false);
|
||||
config.set("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", this.config_claims_survivalAutoNatureRestoration);
|
||||
|
||||
this.config_claims_creativeAutoNatureRestoration = config.getBoolean("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.CreativeWorlds", true);
|
||||
config.set("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.CreativeWorlds", this.config_claims_creativeAutoNatureRestoration);
|
||||
|
||||
this.config_spam_enabled = config.getBoolean("GriefPrevention.Spam.Enabled", true);
|
||||
this.config_spam_loginCooldownMinutes = config.getInt("GriefPrevention.Spam.LoginCooldownMinutes", 2);
|
||||
this.config_spam_warningMessage = config.getString("GriefPrevention.Spam.WarningMessage", "Please reduce your noise level. Spammers will be banned.");
|
||||
|
|
@ -961,6 +980,12 @@ public class GriefPrevention extends JavaPlugin
|
|||
//determine which claim the player is standing in
|
||||
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true /*ignore height*/, null);
|
||||
|
||||
//bracket any permissions
|
||||
if(args[0].contains("."))
|
||||
{
|
||||
args[0] = "[" + args[0] + "]";
|
||||
}
|
||||
|
||||
//determine whether a single player or clearing permissions entirely
|
||||
boolean clearPermissions = false;
|
||||
OfflinePlayer otherPlayer = null;
|
||||
|
|
@ -1796,6 +1821,11 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
}
|
||||
|
||||
else if(recipientName.contains("."))
|
||||
{
|
||||
permission = recipientName;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
otherPlayer = this.resolvePlayer(recipientName);
|
||||
|
|
@ -2310,8 +2340,10 @@ public class GriefPrevention extends JavaPlugin
|
|||
//no building in the wilderness in creative mode
|
||||
if(this.creativeRulesApply(location))
|
||||
{
|
||||
return this.dataStore.getMessage(Messages.NoBuildOutsideClaims) + " " + this.dataStore.getMessage(Messages.CreativeBasicsDemoAdvertisement);
|
||||
|
||||
String reason = this.dataStore.getMessage(Messages.NoBuildOutsideClaims) + " " + this.dataStore.getMessage(Messages.CreativeBasicsDemoAdvertisement);
|
||||
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||
reason += " " + this.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||
return reason;
|
||||
}
|
||||
|
||||
//no building in survival wilderness when that is configured
|
||||
|
|
@ -2350,7 +2382,10 @@ public class GriefPrevention extends JavaPlugin
|
|||
//no building in the wilderness in creative mode
|
||||
if(this.creativeRulesApply(location))
|
||||
{
|
||||
return this.dataStore.getMessage(Messages.NoBuildOutsideClaims) + " " + this.dataStore.getMessage(Messages.CreativeBasicsDemoAdvertisement);
|
||||
String reason = this.dataStore.getMessage(Messages.NoBuildOutsideClaims) + " " + this.dataStore.getMessage(Messages.CreativeBasicsDemoAdvertisement);
|
||||
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||
reason += " " + this.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||
return reason;
|
||||
}
|
||||
|
||||
else if(this.config_claims_noBuildOutsideClaims && this.config_claims_enabledWorlds.contains(location.getWorld()))
|
||||
|
|
@ -2392,7 +2427,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
for(int z = lesserChunk.getZ(); z <= greaterChunk.getZ(); z++)
|
||||
{
|
||||
Chunk chunk = lesserChunk.getWorld().getChunkAt(x, z);
|
||||
this.restoreChunk(chunk, chunk.getWorld().getSeaLevel() - 15, false, delayInTicks, null);
|
||||
this.restoreChunk(chunk, this.getSeaLevel(chunk.getWorld()) - 15, false, delayInTicks, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2421,7 +2456,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
//create task
|
||||
//when done processing, this task will create a main thread task to actually update the world with processing results
|
||||
RestoreNatureProcessingTask task = new RestoreNatureProcessingTask(snapshots, miny, chunk.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome(), lesserBoundaryCorner, greaterBoundaryCorner, chunk.getWorld().getSeaLevel(), aggressiveMode, GriefPrevention.instance.creativeRulesApply(lesserBoundaryCorner), playerReceivingVisualization);
|
||||
RestoreNatureProcessingTask task = new RestoreNatureProcessingTask(snapshots, miny, chunk.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome(), lesserBoundaryCorner, greaterBoundaryCorner, this.getSeaLevel(chunk.getWorld()), aggressiveMode, GriefPrevention.instance.creativeRulesApply(lesserBoundaryCorner), playerReceivingVisualization);
|
||||
GriefPrevention.instance.getServer().getScheduler().scheduleAsyncDelayedTask(GriefPrevention.instance, task, delayInTicks);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ package me.ryanhamshire.GriefPrevention;
|
|||
|
||||
public enum Messages
|
||||
{
|
||||
RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionDemo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, TrappedOnCooldown, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, TrustCommandAdvertisement, GoldenShovelAdvertisement, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsDemoAdvertisement, SurvivalBasicsDemoAdvertisement, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify, AdjustGroupBlocksSuccess, InvalidPermissionID, UntrustOwnerOnly, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning, BuySellNotConfigured, NoTeleportPvPCombat, NoTNTDamageAboveSeaLevel, NoTNTDamageClaims
|
||||
RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionDemo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, TrappedOnCooldown, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, TrustCommandAdvertisement, GoldenShovelAdvertisement, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsDemoAdvertisement, SurvivalBasicsDemoAdvertisement, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify, AdjustGroupBlocksSuccess, InvalidPermissionID, UntrustOwnerOnly, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning, BuySellNotConfigured, NoTeleportPvPCombat, NoTNTDamageAboveSeaLevel, NoTNTDamageClaims, IgnoreClaimsAdvertisement
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import org.bukkit.block.BlockFace;
|
|||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Boat;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Hanging;
|
||||
import org.bukkit.entity.PoweredMinecart;
|
||||
import org.bukkit.entity.StorageMinecart;
|
||||
import org.bukkit.entity.Player;
|
||||
|
|
@ -675,9 +676,21 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
Player player = event.getPlayer();
|
||||
Entity entity = event.getRightClicked();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
|
||||
//don't allow interaction with item frames in claimed areas without build permission
|
||||
if(entity instanceof Hanging)
|
||||
{
|
||||
String noBuildReason = GriefPrevention.instance.allowBuild(player, entity.getLocation());
|
||||
if(noBuildReason != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//don't allow container access during pvp combat
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
if((entity instanceof StorageMinecart || entity instanceof PoweredMinecart))
|
||||
{
|
||||
if(playerData.siegeData != null)
|
||||
|
|
@ -850,7 +863,7 @@ class PlayerEventHandler implements Listener
|
|||
//otherwise no wilderness dumping (unless underground) in worlds where claims are enabled
|
||||
else if(GriefPrevention.instance.config_claims_enabledWorlds.contains(block.getWorld()))
|
||||
{
|
||||
if(block.getY() >= block.getWorld().getSeaLevel() - 5 && !player.hasPermission("griefprevention.lava"))
|
||||
if(block.getY() >= GriefPrevention.instance.getSeaLevel(block.getWorld()) - 5 && !player.hasPermission("griefprevention.lava"))
|
||||
{
|
||||
if(bucketEvent.getBucket() == Material.LAVA_BUCKET || GriefPrevention.instance.config_blockWildernessWaterBuckets)
|
||||
{
|
||||
|
|
@ -960,6 +973,7 @@ class PlayerEventHandler implements Listener
|
|||
clickedBlockType == Material.WORKBENCH ||
|
||||
clickedBlockType == Material.ENDER_CHEST ||
|
||||
clickedBlockType == Material.DISPENSER ||
|
||||
clickedBlockType == Material.ANVIL ||
|
||||
clickedBlockType == Material.BREWING_STAND ||
|
||||
clickedBlockType == Material.JUKEBOX ||
|
||||
clickedBlockType == Material.ENCHANTMENT_TABLE ||
|
||||
|
|
@ -1026,7 +1040,7 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
|
||||
//otherwise apply rules for buttons and switches
|
||||
else if(GriefPrevention.instance.config_claims_preventButtonsSwitches && (clickedBlockType == null || clickedBlockType == Material.STONE_BUTTON || clickedBlockType == Material.LEVER || GriefPrevention.instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getTypeId(), clickedBlock.getData(), null))))
|
||||
else if(GriefPrevention.instance.config_claims_preventButtonsSwitches && (clickedBlockType == null || clickedBlockType == Material.STONE_BUTTON || clickedBlockType == Material.WOOD_BUTTON || clickedBlockType == Material.LEVER || GriefPrevention.instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getTypeId(), clickedBlock.getData(), null))))
|
||||
{
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||
if(claim != null)
|
||||
|
|
@ -1216,9 +1230,9 @@ class PlayerEventHandler implements Listener
|
|||
//if not in aggressive mode, extend the selection down to a little below sea level
|
||||
if(!(playerData.shovelMode == ShovelMode.RestoreNatureAggressive))
|
||||
{
|
||||
if(miny > chunk.getWorld().getSeaLevel() - 10)
|
||||
if(miny > GriefPrevention.instance.getSeaLevel(chunk.getWorld()) - 10)
|
||||
{
|
||||
miny = chunk.getWorld().getSeaLevel() - 10;
|
||||
miny = GriefPrevention.instance.getSeaLevel(chunk.getWorld()) - 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.bukkit.block.Block;
|
|||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Hanging;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
//this main thread task takes the output from the RestoreNatureProcessingTask\
|
||||
|
|
@ -91,8 +92,15 @@ class RestoreNatureExecutionTask implements Runnable
|
|||
Entity entity = entities[i];
|
||||
if(!(entity instanceof Player || entity instanceof Animals))
|
||||
{
|
||||
entity.remove();
|
||||
//hanging entities (paintings, item frames) are protected when they're in land claims
|
||||
if(!(entity instanceof Hanging) || GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, null) == null)
|
||||
{
|
||||
//everything else is removed
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
|
||||
//for players, always ensure there's air where the player is standing
|
||||
else
|
||||
{
|
||||
Block feetBlock = entity.getLocation().getBlock();
|
||||
|
|
@ -101,7 +109,7 @@ class RestoreNatureExecutionTask implements Runnable
|
|||
}
|
||||
}
|
||||
|
||||
//show visualization to player
|
||||
//show visualization to player who started the restoration
|
||||
if(player != null)
|
||||
{
|
||||
Claim claim = new Claim(lesserCorner, greaterCorner, "", new String[] {}, new String[] {}, new String[] {}, new String[] {}, null);
|
||||
|
|
|
|||
|
|
@ -144,15 +144,15 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
//cover surface stone and gravel with sand or grass, as the biome requires
|
||||
this.coverSurfaceStone();
|
||||
|
||||
//reset leaves to NOT player placed so that they may decay as usual
|
||||
this.resetLeaves();
|
||||
//remove any player-placed leaves
|
||||
this.removePlayerLeaves();
|
||||
|
||||
//schedule main thread task to apply the result to the world
|
||||
RestoreNatureExecutionTask task = new RestoreNatureExecutionTask(this.snapshots, this.miny, this.lesserBoundaryCorner, this.greaterBoundaryCorner, this.player);
|
||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task);
|
||||
}
|
||||
|
||||
private void resetLeaves()
|
||||
private void removePlayerLeaves()
|
||||
{
|
||||
for(int x = 1; x < snapshots.length - 1; x++)
|
||||
{
|
||||
|
|
@ -162,13 +162,9 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
{
|
||||
//note: see minecraft wiki data values for leaves
|
||||
BlockSnapshot block = snapshots[x][y][z];
|
||||
if(block.typeId == Material.LEAVES.getId())
|
||||
if(block.typeId == Material.LEAVES.getId() && (block.data & 0x4) != 0)
|
||||
{
|
||||
//clear "player placed" bit
|
||||
block.data = (byte)(block.data & ~(1<<2));
|
||||
|
||||
//set the "check for natural decay" bit
|
||||
block.data = (byte)(block.data | (1<<3));
|
||||
block.typeId = Material.AIR.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -708,6 +704,19 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
playerBlocks.add(Material.WOOD_STEP.getId());
|
||||
playerBlocks.add(Material.WOOD_DOUBLE_STEP.getId());
|
||||
playerBlocks.add(Material.ENDER_CHEST.getId());
|
||||
playerBlocks.add(Material.SANDSTONE_STAIRS.getId());
|
||||
playerBlocks.add(Material.SPRUCE_WOOD_STAIRS.getId());
|
||||
playerBlocks.add(Material.JUNGLE_WOOD_STAIRS.getId());
|
||||
playerBlocks.add(Material.COMMAND.getId());
|
||||
playerBlocks.add(Material.BEACON.getId());
|
||||
playerBlocks.add(Material.COBBLE_WALL.getId());
|
||||
playerBlocks.add(Material.FLOWER_POT.getId());
|
||||
playerBlocks.add(Material.CARROT.getId());
|
||||
playerBlocks.add(Material.POTATO.getId());
|
||||
playerBlocks.add(Material.WOOD_BUTTON.getId());
|
||||
playerBlocks.add(Material.SKULL.getId());
|
||||
playerBlocks.add(Material.ANVIL.getId());
|
||||
|
||||
|
||||
//these are unnatural in the standard world, but not in the nether
|
||||
if(environment != Environment.NETHER)
|
||||
|
|
|
|||
|
|
@ -220,6 +220,8 @@ public class Visualization
|
|||
block.getType() == Material.LEAVES ||
|
||||
block.getType() == Material.RED_ROSE ||
|
||||
block.getType() == Material.CHEST ||
|
||||
block.getType() == Material.TORCH ||
|
||||
block.getType() == Material.VINE ||
|
||||
block.getType() == Material.YELLOW_FLOWER );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user