Now vertically auto-extending claims on creation.

Should effectively protect basements and other underground bits of
surface-level structures from the moment of creation, provided the
underground bits connect to the above ground bits via player block types
(those which don't abundantly generate in the world).
This commit is contained in:
ryanhamshire 2015-09-21 20:23:57 -07:00
parent 864e6ad672
commit a77572a017
2 changed files with 116 additions and 0 deletions

View File

@ -0,0 +1,95 @@
package me.ryanhamshire.GriefPrevention;
import java.util.ArrayList;
import org.bukkit.Bukkit;
import org.bukkit.ChunkSnapshot;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
//automatically extends a claim downward based on block types detected
class AutoExtendClaimTask implements Runnable
{
private Claim claim;
private ArrayList<ChunkSnapshot> chunks;
private Environment worldType;
public AutoExtendClaimTask(Claim claim, ArrayList<ChunkSnapshot> chunks, Environment worldType)
{
this.claim = claim;
this.chunks = chunks;
this.worldType = worldType;
}
@Override
public void run()
{
int newY = this.getLowestBuiltY();
if(newY < this.claim.getLesserBoundaryCorner().getBlockY())
{
Bukkit.getScheduler().runTask(GriefPrevention.instance, new ExecuteExtendClaimTask(claim, newY));
}
}
private int getLowestBuiltY()
{
int y = this.claim.getLesserBoundaryCorner().getBlockY();
if(this.yTooSmall(y)) return y;
for(ChunkSnapshot chunk : this.chunks)
{
Biome biome = chunk.getBiome(0, 0);
ArrayList<Integer> playerBlockIDs = RestoreNatureProcessingTask.getPlayerBlocks(this.worldType, biome);
boolean ychanged = true;
while(!this.yTooSmall(y) && ychanged)
{
ychanged = false;
for(int x = 0; x < 16; x++)
{
for(int z = 0; z < 16; z++)
{
int blockType = chunk.getBlockTypeId(x, y, z);
while(!this.yTooSmall(y) && playerBlockIDs.contains(blockType))
{
ychanged = true;
blockType = chunk.getBlockTypeId(x, --y, z);
}
if(this.yTooSmall(y)) return y;
}
}
}
if(this.yTooSmall(y)) return y;
}
return y;
}
private boolean yTooSmall(int y)
{
return y == 0 || y <= GriefPrevention.instance.config_claims_maxDepth;
}
//runs in the main execution thread, where it can safely change claims and save those changes
private class ExecuteExtendClaimTask implements Runnable
{
private Claim claim;
private int newY;
public ExecuteExtendClaimTask(Claim claim, int newY)
{
this.claim = claim;
this.newY = newY;
}
@Override
public void run()
{
GriefPrevention.instance.dataStore.extendClaim(claim, newY);
}
}
}

View File

@ -36,12 +36,14 @@ import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.TravelAgent;
import org.bukkit.BanList.Type;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
@ -2493,6 +2495,25 @@ class PlayerEventHandler implements Listener
GriefPrevention.sendMessage(player, TextMode.Info, Messages.BecomeMayor, 200L);
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SubdivisionVideo2, 201L, DataStore.SUBDIVISION_VIDEO_URL);
}
//auto-extend it downward to cover anything already built underground
Claim newClaim = result.claim;
Location lesserCorner = newClaim.getLesserBoundaryCorner();
Location greaterCorner = newClaim.getGreaterBoundaryCorner();
World world = lesserCorner.getWorld();
ArrayList<ChunkSnapshot> snapshots = new ArrayList<ChunkSnapshot>();
for(int chunkx = lesserCorner.getBlockX() / 16; chunkx <= greaterCorner.getBlockX() / 16; chunkx++)
{
for(int chunkz = lesserCorner.getBlockZ() / 16; chunkz <= greaterCorner.getBlockZ() / 16; chunkz++)
{
if(world.isChunkLoaded(chunkx, chunkz))
{
snapshots.add(world.getChunkAt(chunkx, chunkz).getChunkSnapshot(true, true, true));
}
}
}
Bukkit.getScheduler().runTaskAsynchronously(GriefPrevention.instance, new AutoExtendClaimTask(newClaim, snapshots, world.getEnvironment()));
}
}
}