From 1b670a1c98d851dbaa4647812ddb9a28dd22e244 Mon Sep 17 00:00:00 2001 From: sk89q Date: Sat, 12 Mar 2011 16:37:07 -0800 Subject: [PATCH] Added //regen to regenerate an area. --- plugin.yml | 133 +++++++++--------- src/com/sk89q/worldedit/EditSession.java | 16 ++- src/com/sk89q/worldedit/LocalWorld.java | 10 ++ .../sk89q/worldedit/bukkit/BukkitWorld.java | 56 ++++++++ .../worldedit/commands/ChunkCommands.java | 1 + .../worldedit/commands/RegionCommands.java | 17 +++ 6 files changed, 167 insertions(+), 66 deletions(-) diff --git a/plugin.yml b/plugin.yml index 48fc682a9..47db61f03 100644 --- a/plugin.yml +++ b/plugin.yml @@ -11,6 +11,9 @@ commands: delchunks: description: Delete chunks that your selection includes usage: / + clearclipboard: + description: Clear your clipboard + usage: / /load: description: Load a schematic into your clipboard usage: / @@ -32,12 +35,6 @@ commands: /paste: description: Paste the clipboard's contents usage: / [-ao] - clearclipboard: - description: Clear your clipboard - usage: / - /limit: - description: Modify block change limit - usage: / we: description: WorldEdit commands usage: / @@ -49,6 +46,9 @@ commands: description: Search for an item usage: / [-bi] aliases: ['/l', 'search'] + /limit: + description: Modify block change limit + usage: / /hcyl: description: Generate a hollow cylinder usage: / [height] @@ -67,17 +67,17 @@ commands: pumpkins: description: Generate pumpkin patches usage: / [size] - /undo: - description: Undoes the last action - usage: / [times] - aliases: ['undo'] + clearhistory: + description: Clear your history + usage: / /redo: description: Redoes the last action (from history) usage: / [times] aliases: ['redo'] - clearhistory: - description: Clear your history - usage: / + /undo: + description: Undoes the last action + usage: / [times] + aliases: ['undo'] unstuck: description: Escape from being stuck inside a block usage: / @@ -87,27 +87,18 @@ commands: descend: description: Go down a floor usage: / - ceil: - description: Go to the celing - usage: / [clearance] thru: description: Passthrough walls usage: / jumpto: description: Teleport to a location usage: / + ceil: + description: Go to the celing + usage: / [clearance] up: description: Go upwards some distance usage: / - /replace: - description: Replace all blocks in the selection with another - usage: / [from-block] - /stack: - description: Repeat the contents of the selection - usage: / [-a] [count] [direction] - /set: - description: Set all the blocks inside the selection to a block - usage: / /overlay: description: Set a block on top of blocks in the region usage: / @@ -121,24 +112,27 @@ commands: /smooth: description: Smooth the elevation in the selection usage: / [iterations] + /regen: + description: Regenerates the contents of the selection + usage: / + /replace: + description: Replace all blocks in the selection with another + usage: / [from-block] + /stack: + description: Repeat the contents of the selection + usage: / [-a] [count] [direction] + /set: + description: Set all the blocks inside the selection to a block + usage: / /move: description: Move the contents of the selection usage: / [count] [direction] [leave-id] - cs: - description: Execute a CraftScript - usage: / [args...] .s: description: Execute last CraftScript usage: / [args...] - /count: - description: Counts the number of a certain type of block - usage: / - /size: - description: Get information about the selection - usage: / - /shift: - description: Shift the selection area - usage: / [direction] + cs: + description: Execute a CraftScript + usage: / [args...] /chunk: description: Set the selection to your current chunk usage: / @@ -160,25 +154,34 @@ commands: toggleeditwand: description: Toggle functionality of the edit wand usage: / - /expand: - description: Expand the selection area - usage: / [reverse-amount] /contract: description: Contract the selection area usage: / [reverse-amount] [direction] /outset: description: Outset the selection area usage: / [-hv] - /inset: - description: Inset the selection area - usage: / [-hv] /distr: description: Get the distribution of blocks in the selection usage: / [-c] + /count: + description: Counts the number of a certain type of block + usage: / + /size: + description: Get information about the selection + usage: / + /shift: + description: Shift the selection area + usage: / [direction] + /expand: + description: Expand the selection area + usage: / [reverse-amount] /sel: description: Choose a region selector usage: / [type] aliases: [','] + /inset: + description: Inset the selection area + usage: / [-hv] snapshot: description: Snapshot commands usage: / @@ -187,12 +190,6 @@ commands: description: Restore the selection from a snapshot usage: / [snapshot] aliases: ['/restore'] - size: - description: Set the brush size - usage: / [pattern] - mask: - description: Set the brush mask - usage: / [mask] /: description: Toggle the super pickaxe pickaxe function usage: / @@ -208,15 +205,15 @@ commands: description: Set the brush material usage: / [pattern] aliases: ['material', 'fill'] - info: - description: Block information tool - usage: / + size: + description: Set the brush size + usage: / [pattern] + mask: + description: Set the brush mask + usage: / [mask] none: description: Turn off all superpickaxe alternate modes usage: / - tree: - description: Tree generator tool - usage: / [type] repl: description: Block replacer tool usage: / @@ -227,19 +224,15 @@ commands: description: Brush tool usage: / aliases: ['br'] - remove: - description: Remove all entities of a type - usage: / - aliases: ['rem', 'rement'] - /fill: - description: Fill a hole - usage: / [depth] + info: + description: Block information tool + usage: / + tree: + description: Tree generator tool + usage: / [type] /fillr: description: Fill a hole recursively usage: / [depth] - /drain: - description: Drain a pool - usage: / fixlava: description: Fix lava to be stationary usage: / @@ -271,3 +264,13 @@ commands: butcher: description: Kill all or nearby mobs usage: / [radius] + remove: + description: Remove all entities of a type + usage: / + aliases: ['rem', 'rement'] + /fill: + description: Fill a hole + usage: / [depth] + /drain: + description: Drain a pool + usage: / diff --git a/src/com/sk89q/worldedit/EditSession.java b/src/com/sk89q/worldedit/EditSession.java index 2d94fb349..1e50bba2f 100755 --- a/src/com/sk89q/worldedit/EditSession.java +++ b/src/com/sk89q/worldedit/EditSession.java @@ -249,6 +249,20 @@ public class EditSession { return smartSetBlock(pt, block); } + /** + * Insert a contrived block change into the history. + * + * @param pt + * @param existing + * @param block + */ + public void rememberChange(Vector pt, BaseBlock existing, BaseBlock block) { + BlockVector blockPt = pt.toBlockVector(); + + original.put(blockPt, existing); + current.put(pt.toBlockVector(), block); + } + /** * Set a block with a pattern. * @@ -286,7 +300,7 @@ public class EditSession { * @param block * @return */ - private boolean smartSetBlock(Vector pt, BaseBlock block) { + public boolean smartSetBlock(Vector pt, BaseBlock block) { if (queued) { // Place torches, etc. last if (BlockType.shouldPlaceLast(block.getType())) { diff --git a/src/com/sk89q/worldedit/LocalWorld.java b/src/com/sk89q/worldedit/LocalWorld.java index e8ae993a9..fbec2d47c 100644 --- a/src/com/sk89q/worldedit/LocalWorld.java +++ b/src/com/sk89q/worldedit/LocalWorld.java @@ -22,6 +22,7 @@ package com.sk89q.worldedit; import java.util.Random; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.regions.Region; /** * Represents a world. @@ -78,6 +79,15 @@ public abstract class LocalWorld { * @return */ public abstract int getBlockData(Vector pt); + + /** + * Regenerate an area. + * + * @param region + * @param editSession + * @return + */ + public abstract boolean regenerate(Region region, EditSession editSession); /** * Attempts to accurately copy a BaseBlock's extra data to the world. diff --git a/src/com/sk89q/worldedit/bukkit/BukkitWorld.java b/src/com/sk89q/worldedit/bukkit/BukkitWorld.java index 5b0ef6c65..303428172 100644 --- a/src/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/src/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -43,7 +43,9 @@ import org.bukkit.World; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.blocks.*; +import com.sk89q.worldedit.regions.Region; public class BukkitWorld extends LocalWorld { private World world; @@ -111,6 +113,60 @@ public class BukkitWorld extends LocalWorld { return world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getData(); } + /** + * Regenerate an area. + * + * @param region + * @param editSession + * @return + */ + @Override + public boolean regenerate(Region region, EditSession editSession) { + BaseBlock[] history = new BaseBlock[16 * 16 * 128]; + + for (Vector2D chunk : region.getChunks()) { + Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16); + Vector max = min.add(15, 127, 15); + + // First save all the blocks inside + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 128; y++) { + for (int z = 0; z < 16; z++) { + Vector pt = min.add(x, y, z); + int index = y * 16 * 16 + z * 16 + x; + history[index] = editSession.getBlock(pt); + } + } + } + + try { + world.regenerateChunk(chunk.getBlockX(), chunk.getBlockZ()); + } catch (Throwable t) { + t.printStackTrace(); + } + + // Then restore + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 128; y++) { + for (int z = 0; z < 16; z++) { + Vector pt = min.add(x, y, z); + int index = y * 16 * 16 + z * 16 + x; + + // We have to restore the block if it was outside + if (!region.contains(pt)) { + editSession.smartSetBlock(pt, history[index]); + } else { // Otherwise fool with history + editSession.rememberChange(pt, history[index], + editSession.rawGetBlock(pt)); + } + } + } + } + } + + return true; + } + /** * Attempts to accurately copy a BaseBlock's extra data to the world. * diff --git a/src/com/sk89q/worldedit/commands/ChunkCommands.java b/src/com/sk89q/worldedit/commands/ChunkCommands.java index 3dac26653..81753b279 100644 --- a/src/com/sk89q/worldedit/commands/ChunkCommands.java +++ b/src/com/sk89q/worldedit/commands/ChunkCommands.java @@ -26,6 +26,7 @@ import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.worldedit.*; import com.sk89q.worldedit.data.LegacyChunkStore; +import com.sk89q.worldedit.regions.Region; /** * Chunk tools. diff --git a/src/com/sk89q/worldedit/commands/RegionCommands.java b/src/com/sk89q/worldedit/commands/RegionCommands.java index 646d06a2b..bab30907c 100644 --- a/src/com/sk89q/worldedit/commands/RegionCommands.java +++ b/src/com/sk89q/worldedit/commands/RegionCommands.java @@ -230,4 +230,21 @@ public class RegionCommands { dir, count, !args.hasFlag('a')); player.print(affected + " blocks changed. Undo with //undo"); } + + @Command( + aliases = {"/regen"}, + usage = "", + desc = "Regenerates the contents of the selection", + min = 0, + max = 0 + ) + @CommandPermissions({"worldedit.regen"}) + public static void regenerateChunk(CommandContext args, WorldEdit we, + LocalSession session, LocalPlayer player, EditSession editSession) + throws WorldEditException { + + Region region = session.getSelection(player.getWorld()); + player.getWorld().regenerate(region, editSession); + player.print("Region regenerated."); + } }