From a77572a0172f1e576a4d6393e3044029e9cbd900 Mon Sep 17 00:00:00 2001 From: ryanhamshire Date: Mon, 21 Sep 2015 20:23:57 -0700 Subject: [PATCH] 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). --- .../GriefPrevention/AutoExtendClaimTask.java | 95 +++++++++++++++++++ .../GriefPrevention/PlayerEventHandler.java | 21 ++++ 2 files changed, 116 insertions(+) create mode 100644 src/me/ryanhamshire/GriefPrevention/AutoExtendClaimTask.java diff --git a/src/me/ryanhamshire/GriefPrevention/AutoExtendClaimTask.java b/src/me/ryanhamshire/GriefPrevention/AutoExtendClaimTask.java new file mode 100644 index 0000000..fb85730 --- /dev/null +++ b/src/me/ryanhamshire/GriefPrevention/AutoExtendClaimTask.java @@ -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 chunks; + private Environment worldType; + + public AutoExtendClaimTask(Claim claim, ArrayList 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 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); + } + } + +} diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java index 19f3d56..85ec33f 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java @@ -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 snapshots = new ArrayList(); + 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())); } } }