3
0
Mirror von https://github.com/IntellectualSites/FastAsyncWorldEdit.git synchronisiert 2024-11-12 22:20:08 +01:00
Dieser Commit ist enthalten in:
Jesse Boyd 2018-08-23 06:02:04 +10:00
Ursprung 9927cde616
Commit f43faae917
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 59F1DE6293AF6E1F
178 geänderte Dateien mit 24721 neuen und 32 gelöschten Zeilen

24
favs/build.gradle Normale Datei
Datei anzeigen

@ -0,0 +1,24 @@
repositories {
maven {url "http://vault.voxelmodpack.com/content/repositories/central/"}
}
dependencies {
compile project(':worldedit-bukkit')
compile 'com.martiansoftware:jsap:2.1'
}
processResources {
from('src/main/resources') {
include 'plugin.yml'
expand(
name: project.parent.name,
version: project.parent.version
)
}
}
jar.destinationDir = file '../target'
jar.archiveName = "FastAsyncVoxelSniper-${project.name}-${parent.version}.jar"
jar.doLast { task ->
ant.checksum file: task.archivePath
}

Datei anzeigen

@ -0,0 +1,30 @@
package com.boydti.fawe.bukkit.favs;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FawePlayer;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class PatternUtil {
public static Pattern parsePattern(Player player, SnipeData snipeData, String arg) {
ParserContext context = new ParserContext();
FawePlayer<Object> fp = FawePlayer.wrap(player);
context.setActor(fp.getPlayer());
context.setWorld(fp.getWorld());
context.setSession(fp.getSession());
try {
Pattern pattern = WorldEdit.getInstance().getPatternFactory().parseFromInput(arg, context);
snipeData.setPattern(pattern, arg);
snipeData.sendMessage(ChatColor.GOLD + "Voxel: " + ChatColor.RED + arg);
return pattern;
} catch (InputParseException e) {
fp.sendMessage(BBC.getPrefix() + e.getMessage());
return null;
}
}
}

Datei anzeigen

@ -0,0 +1,92 @@
package com.thevoxelbox.voxelsniper;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.thevoxelbox.voxelsniper.brush.IBrush;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Brush registration manager.
*/
public class Brushes
{
private Multimap<Class<? extends IBrush>, String> brushes = HashMultimap.create();
/**
* Register a brush for VoxelSniper to be able to use.
*
* @param clazz Brush implementing IBrush interface.
* @param handles Handles under which the brush can be accessed ingame.
*/
public void registerSniperBrush(Class<? extends IBrush> clazz, String... handles)
{
Preconditions.checkNotNull(clazz, "Cannot register null as a class.");
for (String handle : handles)
{
brushes.put(clazz, handle.toLowerCase());
}
}
/**
* Retrieve Brush class via handle Lookup.
*
* @param handle Case insensitive brush handle
* @return Brush class
*/
public Class<? extends IBrush> getBrushForHandle(String handle)
{
Preconditions.checkNotNull(handle, "Brushhandle can not be null.");
if (!brushes.containsValue(handle.toLowerCase()))
{
return null;
}
for (Map.Entry<Class<? extends IBrush>, String> entry : brushes.entries())
{
if (entry.getValue().equalsIgnoreCase(handle))
{
return entry.getKey();
}
}
return null;
}
/**
* @return Amount of IBrush classes registered with the system under Sniper visibility.
*/
public int registeredSniperBrushes()
{
return brushes.keySet().size();
}
/**
* @return Amount of handles registered with the system under Sniper visibility.
*/
public int registeredSniperBrushHandles()
{
return brushes.size();
}
/**
*
* @param clazz Brush class
* @return All Sniper registered handles for the brush.
*/
public Set<String> getSniperBrushHandles(Class<? extends IBrush> clazz)
{
return new HashSet<String>(brushes.get(clazz));
}
/**
* @return Immutable Multimap copy of all the registered brushes
*/
public Multimap<Class<?extends IBrush>, String> getRegisteredBrushesMultimap()
{
return ImmutableMultimap.copyOf(brushes);
}
}

Datei anzeigen

@ -0,0 +1,169 @@
package com.thevoxelbox.voxelsniper;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import org.bukkit.ChatColor;
import org.bukkit.Material;
/**
*
*/
public class Message
{
private static final int BRUSH_SIZE_WARNING_THRESHOLD = 20;
private final SnipeData snipeData;
/**
* @param snipeData
*/
public Message(SnipeData snipeData)
{
this.snipeData = snipeData;
}
/**
* Send a brush message styled message to the player.
*
* @param brushMessage
*/
public void brushMessage(String brushMessage)
{
snipeData.sendMessage(ChatColor.LIGHT_PURPLE + brushMessage);
}
/**
* Display Brush Name.
*
* @param brushName
*/
public void brushName(String brushName)
{
snipeData.sendMessage(ChatColor.AQUA + "Brush Type: " + ChatColor.LIGHT_PURPLE + brushName);
}
/**
* Display Center Parameter.
*/
public void center()
{
snipeData.sendMessage(ChatColor.DARK_BLUE + "Brush Center: " + ChatColor.DARK_RED + snipeData.getcCen());
}
/**
* Display custom message.
*
* @param message
*/
public void custom(String message)
{
snipeData.sendMessage(message);
}
/**
* Display data value.
*/
public void data()
{
snipeData.sendMessage(ChatColor.BLUE + "Data Variable: " + ChatColor.DARK_RED + snipeData.getPropertyId());
}
/**
* Display voxel height.
*/
public void height()
{
snipeData.sendMessage(ChatColor.DARK_AQUA + "Brush Height: " + ChatColor.DARK_RED + snipeData.getVoxelHeight());
}
/**
* Display performer.
*
* @param performerName
*/
public void performerName(String performerName)
{
this.snipeData.sendMessage(ChatColor.DARK_PURPLE + "Performer: " + ChatColor.DARK_GREEN + performerName);
}
/**
* Displaye replace material.
*/
@SuppressWarnings("deprecation")
public void replace()
{
snipeData.sendMessage(ChatColor.AQUA + "Replace Material: " + ChatColor.RED + snipeData.getReplaceId() + ChatColor.GRAY + " (" + BlockTypes.get(snipeData.getReplaceId()).toString() + ")");
}
/**
* Display replace data value.
*/
public void replaceData()
{
snipeData.sendMessage(ChatColor.DARK_GRAY + "Replace Data Variable: " + ChatColor.DARK_RED + snipeData.getReplaceData());
}
/**
* Display brush size.
*/
public void size()
{
snipeData.sendMessage(ChatColor.GREEN + "Brush Size: " + ChatColor.DARK_RED + snipeData.getBrushSize());
if (snipeData.getBrushSize() >= BRUSH_SIZE_WARNING_THRESHOLD)
{
snipeData.sendMessage(ChatColor.RED + "WARNING: Large brush size selected!");
}
}
/**
* Display toggle lightning message.
*/
public void toggleLightning()
{
snipeData.sendMessage(ChatColor.GOLD + "Lightning mode has been toggled " + ChatColor.DARK_RED + ((snipeData.owner().getSnipeData(snipeData.owner().getCurrentToolId()).isLightningEnabled()) ? "on" : "off"));
}
/**
* Display toggle printout message.
*/
public final void togglePrintout()
{
snipeData.sendMessage(ChatColor.GOLD + "Brush info printout mode has been toggled " + ChatColor.DARK_RED + ((snipeData.owner().getSnipeData(snipeData.owner().getCurrentToolId()).isLightningEnabled()) ? "on" : "off"));
}
/**
* Display toggle range message.
*/
public void toggleRange()
{
snipeData.sendMessage(ChatColor.GOLD + "Distance Restriction toggled " + ChatColor.DARK_RED + ((snipeData.owner().getSnipeData(snipeData.owner().getCurrentToolId()).isRanged()) ? "on" : "off") + ChatColor.GOLD + ". Range is " + ChatColor.LIGHT_PURPLE + (double) snipeData.owner().getSnipeData(snipeData.owner().getCurrentToolId()).getRange());
}
/**
* Display voxel type.
*/
@SuppressWarnings("deprecation")
public void voxel()
{
snipeData.sendMessage(ChatColor.GOLD + "Voxel: " + ChatColor.RED + snipeData.getVoxelId() + ChatColor.GRAY + " (" + BlockTypes.get(snipeData.getVoxelId()).toString() + ")");
}
/**
* Display voxel list.
*/
public void voxelList()
{
if (snipeData.getVoxelList().isEmpty())
{
snipeData.sendMessage(ChatColor.DARK_GREEN + "No blocks selected!");
}
else
{
StringBuilder returnValueBuilder = new StringBuilder();
returnValueBuilder.append(ChatColor.DARK_GREEN);
returnValueBuilder.append("Block Types Selected: ");
returnValueBuilder.append(ChatColor.AQUA);
returnValueBuilder.append(snipeData.getVoxelList());
snipeData.sendMessage(returnValueBuilder.toString());
}
}
}

Datei anzeigen

@ -0,0 +1,102 @@
package com.thevoxelbox.voxelsniper;
import org.bukkit.Art;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Player;
import java.util.Set;
/**
* Painting state change handler.
*
* @author Piotr
*/
public final class PaintingWrapper
{
private PaintingWrapper()
{
}
/**
* The paint method used to scroll or set a painting to a specific type.
*
* @param p
* The player executing the method
* @param auto
* Scroll automatically? If false will use 'choice' to try and set the painting
* @param back
* Scroll in reverse?
* @param choice
* Chosen index to set the painting to
*/
@SuppressWarnings("deprecation")
public static void paint(final Player p, final boolean auto, final boolean back, final int choice)
{
Location targetLocation = p.getTargetBlock((Set<Material>) null, 4).getLocation();
Chunk paintingChunk = p.getTargetBlock((Set<Material>) null, 4).getLocation().getChunk();
Double bestDistanceMatch = 50D;
Painting bestMatch = null;
for (Entity entity : paintingChunk.getEntities())
{
if (entity.getType() == EntityType.PAINTING)
{
Double distance = targetLocation.distanceSquared(entity.getLocation());
if (distance <= 4 && distance < bestDistanceMatch)
{
bestDistanceMatch = distance;
bestMatch = (Painting) entity;
}
}
}
if (bestMatch != null)
{
if (auto)
{
try
{
final int i = bestMatch.getArt().getId() + (back ? -1 : 1) + Art.values().length % Art.values().length;
Art art = Art.getById(i);
if (art == null)
{
p.sendMessage(ChatColor.RED + "This is the final painting, try scrolling to the other direction.");
return;
}
bestMatch.setArt(art);
p.sendMessage(ChatColor.GREEN + "Painting set to ID: " + (i));
}
catch (final Exception e)
{
p.sendMessage(ChatColor.RED + "Oops. Something went wrong.");
}
}
else
{
try
{
Art art = Art.getById(choice);
bestMatch.setArt(art);
p.sendMessage(ChatColor.GREEN + "Painting set to ID: " + choice);
}
catch (final Exception exception)
{
p.sendMessage(ChatColor.RED + "Your input was invalid somewhere.");
}
}
}
}
}

Datei anzeigen

@ -0,0 +1,303 @@
/**
This file is part of VoxelSniper, licensed under the MIT License (MIT).
Copyright (c) The VoxelBox <http://thevoxelbox.com>
Copyright (c) contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package com.thevoxelbox.voxelsniper;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
public class RangeBlockHelper {
private static final int MAXIMUM_WORLD_HEIGHT = 255;
private static final double DEFAULT_PLAYER_VIEW_HEIGHT = 1.65D;
private static final double DEFAULT_LOCATION_VIEW_HEIGHT = 0.0D;
private static final double DEFAULT_STEP = 0.2D;
private static final int DEFAULT_RANGE = 250;
private Location playerLoc;
private double rotX;
private double rotY;
private double viewHeight;
private double rotXSin;
private double rotXCos;
private double rotYSin;
private double rotYCos;
private double length;
private double hLength;
private double step;
private double range;
private double playerX;
private double playerY;
private double playerZ;
private double xOffset;
private double yOffset;
private double zOffset;
private int lastX;
private int lastY;
private int lastZ;
private int targetX;
private int targetY;
private int targetZ;
private AsyncWorld world;
public RangeBlockHelper(Location location) {
this.init(location, 250.0D, 0.2D, 0.0D);
}
public RangeBlockHelper(Location location, int range, double step) {
this.world = (AsyncWorld) location.getWorld();
this.init(location, (double)range, step, 0.0D);
}
public RangeBlockHelper(Player player, int range, double step) {
if (player != null) {
this.world = VoxelSniper.getInstance().getSniperManager().getSniperForPlayer(player).getWorld();
}
this.init(player.getLocation(), (double)range, step, 1.65D);
}
public RangeBlockHelper(Player player, AsyncWorld world) {
if (player != null && (world == null || player.getWorld().getName().equals(world.getName()))) {
this.world = VoxelSniper.getInstance().getSniperManager().getSniperForPlayer(player).getWorld();
} else {
this.world = world;
}
this.init(player.getLocation(), 250.0D, 0.2D, 1.65D);
}
public RangeBlockHelper(Player player, AsyncWorld world, double range) {
if (player != null && (world == null || player.getWorld().getName().equals(world.getName()))) {
this.world = VoxelSniper.getInstance().getSniperManager().getSniperForPlayer(player).getWorld();
} else {
this.world = world;
}
this.init(player.getLocation(), range, 0.2D, 1.65D);
this.fromOffworld();
}
public final void fromOffworld() {
if(this.targetY <= 255) {
if(this.targetY < 0) {
while(this.targetY < 0 && this.length <= this.range) {
this.lastX = this.targetX;
this.lastY = this.targetY;
this.lastZ = this.targetZ;
while(true) {
this.length += this.step;
this.hLength = this.length * this.rotYCos;
this.yOffset = this.length * this.rotYSin;
this.xOffset = this.hLength * this.rotXCos;
this.zOffset = this.hLength * this.rotXSin;
this.targetX = (int)Math.floor(this.xOffset + this.playerX);
this.targetY = (int)Math.floor(this.yOffset + this.playerY);
this.targetZ = (int)Math.floor(this.zOffset + this.playerZ);
if(this.length > this.range || this.targetX != this.lastX || this.targetY != this.lastY || this.targetZ != this.lastZ) {
break;
}
}
}
}
} else {
while(this.targetY > 255 && this.length <= this.range) {
this.lastX = this.targetX;
this.lastY = this.targetY;
this.lastZ = this.targetZ;
while(true) {
this.length += this.step;
this.hLength = this.length * this.rotYCos;
this.yOffset = this.length * this.rotYSin;
this.xOffset = this.hLength * this.rotXCos;
this.zOffset = this.hLength * this.rotXSin;
this.targetX = (int)Math.floor(this.xOffset + this.playerX);
this.targetY = (int)Math.floor(this.yOffset + this.playerY);
this.targetZ = (int)Math.floor(this.zOffset + this.playerZ);
if(this.length > this.range || this.targetX != this.lastX || this.targetY != this.lastY || this.targetZ != this.lastZ) {
break;
}
}
}
}
}
public final AsyncBlock getCurBlock() {
return this.length <= this.range && this.targetY <= 255 && this.targetY >= 0?this.world.getBlockAt(this.targetX, this.targetY, this.targetZ):null;
}
private boolean isAir(Material m) {
switch (m) {
case AIR:
case CAVE_AIR:
case VOID_AIR:
return true;
default:
return false;
}
}
public final AsyncBlock getFaceBlock() {
while(this.getNextBlock() != null && isAir(this.getCurBlock().getType())) {
;
}
if(this.getCurBlock() != null) {
return this.getLastBlock();
} else {
return null;
}
}
public final AsyncBlock getLastBlock() {
return this.lastY <= 255 && this.lastY >= 0?this.world.getBlockAt(this.lastX, this.lastY, this.lastZ):null;
}
public final AsyncBlock getNextBlock() {
this.lastX = this.targetX;
this.lastY = this.targetY;
this.lastZ = this.targetZ;
do {
this.length += this.step;
this.hLength = this.length * this.rotYCos;
this.yOffset = this.length * this.rotYSin;
this.xOffset = this.hLength * this.rotXCos;
this.zOffset = this.hLength * this.rotXSin;
this.targetX = (int)Math.floor(this.xOffset + this.playerX);
this.targetY = (int)Math.floor(this.yOffset + this.playerY);
this.targetZ = (int)Math.floor(this.zOffset + this.playerZ);
} while(this.length <= this.range && this.targetX == this.lastX && this.targetY == this.lastY && this.targetZ == this.lastZ);
return this.length <= this.range && this.targetY <= 255 && this.targetY >= 0?this.world.getBlockAt(this.targetX, this.targetY, this.targetZ):null;
}
public final AsyncBlock getRangeBlock() {
this.fromOffworld();
return this.length > this.range?null:this.getRange();
}
public final AsyncBlock getTargetBlock() {
this.fromOffworld();
while(this.getNextBlock() != null && isAir(this.getCurBlock().getType())) {
;
}
return this.getCurBlock();
}
public final void setCurBlock(int type) {
if(this.getCurBlock() != null) {
this.world.getBlockAt(this.targetX, this.targetY, this.targetZ).setType(getType(type));
}
}
public final void setFaceBlock(int type) {
while(this.getNextBlock() != null && isAir(this.getCurBlock().getType())) {
;
}
if(this.getCurBlock() != null) {
this.world.getBlockAt(this.targetX, this.targetY, this.targetZ).setType(getType(type));
}
}
private Material getType(int id) {
return BukkitAdapter.adapt(LegacyMapper.getInstance().getBlockFromLegacy(id).getBlockType());
}
public final void setLastBlock(int type) {
if(this.getLastBlock() != null) {
this.world.getBlockAt(this.lastX, this.lastY, this.lastZ).setType(getType(type));
}
}
public final void setTargetBlock(int type) {
while(this.getNextBlock() != null && isAir(this.getCurBlock().getType())) {
;
}
if(this.getCurBlock() != null) {
this.world.getBlockAt(this.targetX, this.targetY, this.targetZ).setType(getType(type));
}
}
private AsyncBlock getRange() {
this.lastX = this.targetX;
this.lastY = this.targetY;
this.lastZ = this.targetZ;
do {
this.length += this.step;
this.hLength = this.length * this.rotYCos;
this.yOffset = this.length * this.rotYSin;
this.xOffset = this.hLength * this.rotXCos;
this.zOffset = this.hLength * this.rotXSin;
this.targetX = (int)Math.floor(this.xOffset + this.playerX);
this.targetY = (int)Math.floor(this.yOffset + this.playerY);
this.targetZ = (int)Math.floor(this.zOffset + this.playerZ);
} while(this.length <= this.range && this.targetX == this.lastX && this.targetY == this.lastY && this.targetZ == this.lastZ);
AsyncBlock block = world.getBlockAt(this.targetX, this.targetY, this.targetZ);
Material type = block.getType();
return !isAir(type) ? block : (this.length <= this.range && this.targetY <= 255 && this.targetY >= 0?this.getRange():this.world.getBlockAt(this.lastX, this.lastY, this.lastZ));
}
private void init(Location location, double range, double step, double viewHeight) {
this.playerLoc = location;
this.viewHeight = viewHeight;
this.playerX = this.playerLoc.getX();
this.playerY = this.playerLoc.getY() + this.viewHeight;
this.playerZ = this.playerLoc.getZ();
this.range = range;
this.step = step;
this.length = 0.0D;
this.rotX = (double)((this.playerLoc.getYaw() + 90.0F) % 360.0F);
this.rotY = (double)(this.playerLoc.getPitch() * -1.0F);
this.rotYCos = Math.cos(Math.toRadians(this.rotY));
this.rotYSin = Math.sin(Math.toRadians(this.rotY));
this.rotXCos = Math.cos(Math.toRadians(this.rotX));
this.rotXSin = Math.sin(Math.toRadians(this.rotX));
this.targetX = (int)Math.floor(this.playerLoc.getX());
this.targetY = (int)Math.floor(this.playerLoc.getY() + this.viewHeight);
this.targetZ = (int)Math.floor(this.playerLoc.getZ());
this.lastX = this.targetX;
this.lastY = this.targetY;
this.lastZ = this.targetZ;
}
public static Class<?> inject() {
return RangeBlockHelper.class;
}
}

Datei anzeigen

@ -0,0 +1,9 @@
package com.thevoxelbox.voxelsniper;
/**
*
*/
public enum SnipeAction
{
ARROW, GUNPOWDER
}

Datei anzeigen

@ -0,0 +1,328 @@
/**
This file is part of VoxelSniper, licensed under the MIT License (MIT).
Copyright (c) The VoxelBox <http://thevoxelbox.com>
Copyright (c) contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package com.thevoxelbox.voxelsniper;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.util.VoxelList;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.entity.Player;
/**
* @author Piotr
*/
public class SnipeData {
public static final int DEFAULT_REPLACE_DATA_VALUE = 0;
public static final int DEFAULT_CYLINDER_CENTER = 0;
public static final int DEFAULT_VOXEL_HEIGHT = 1;
public static final int DEFAULT_BRUSH_SIZE = 3;
public static final int DEFAULT_DATA_VALUE = 0;
public static final int DEFAULT_REPLACE_ID = BlockTypes.AIR.getInternalId();
public static final int DEFAULT_VOXEL_ID = BlockTypes.AIR.getInternalId();
private final Sniper owner;
private Message voxelMessage;
/**
* Brush size -- set blockPositionY /b #.
*/
private int brushSize = SnipeData.DEFAULT_BRUSH_SIZE;
/**
* Voxel Id -- set blockPositionY /v (#,name).
*/
private int voxelId = SnipeData.DEFAULT_VOXEL_ID;
/**
* Voxel Replace Id -- set blockPositionY /vr #.
*/
private int replaceId = SnipeData.DEFAULT_REPLACE_ID;
/**
* Voxel 'ink' -- set blockPositionY /vi #.
*/
private int data = SnipeData.DEFAULT_DATA_VALUE;
/**
* Voxel 'ink' Replace -- set blockPositionY /vir #.
*/
private int replaceData = SnipeData.DEFAULT_REPLACE_DATA_VALUE;
/**
* Voxel List of ID's -- set blockPositionY /vl # # # -#.
*/
private VoxelList voxelList = new VoxelList();
/**
* Voxel 'heigth' -- set blockPositionY /vh #.
*/
private int voxelHeight = SnipeData.DEFAULT_VOXEL_HEIGHT;
/**
* Voxel centroid -- set Cylynder center /vc #.
*/
private int cCen = SnipeData.DEFAULT_CYLINDER_CENTER;
private int range = 0;
private boolean ranged = false;
private boolean lightning = false;
private Extent extent;
private Pattern pattern;
private String patternInfo;
/**
* @param vs
*/
public SnipeData(final Sniper vs) {
this.owner = vs;
}
/**
* Get the extent currently being used to set blocks
* @return
*/
public Extent getExtent() {
return extent;
}
/**
* Set the extent currently being used to set blocks
* @param extent
*/
public void setExtent(Extent extent) {
this.extent = extent;
}
public void setPattern(Pattern pattern, String info) {
if (pattern != null) {
if (info == null) info = "";
} else {
info = null;
}
this.pattern = pattern;
this.patternInfo = info;
}
public Pattern getPattern() {
return pattern;
}
public String getPatternInfo() {
return patternInfo;
}
/**
* @return the brushSize
*/
public final int getBrushSize() {
return this.brushSize;
}
/**
* @return the cCen
*/
public final int getcCen() {
return this.cCen;
}
/**
* @return the data
*/
public final int getPropertyId() {
return this.data;
}
/**
* @return the replaceData
*/
public final int getReplaceData() {
return this.replaceData;
}
/**
* @return the replaceId
*/
public final int getReplaceId() {
return this.replaceId;
}
/**
* @return the voxelHeight
*/
public final int getVoxelHeight() {
return this.voxelHeight;
}
/**
* @return the voxelId
*/
public final int getVoxelId() {
return this.voxelId;
}
/**
* @return the voxelList
*/
public final VoxelList getVoxelList() {
return this.voxelList;
}
/**
* @return the voxelMessage
*/
public final Message getVoxelMessage() {
return this.voxelMessage;
}
/**
* @return World
*/
public final World getWorld() {
return this.owner.getWorld(); // Changed
}
/**
* @return Sniper
*/
public final Sniper owner() {
return this.owner;
}
/**
* Reset to default values.
*/
public final void reset() {
this.voxelId = SnipeData.DEFAULT_VOXEL_ID;
this.replaceId = SnipeData.DEFAULT_REPLACE_ID;
this.data = SnipeData.DEFAULT_DATA_VALUE;
this.brushSize = SnipeData.DEFAULT_BRUSH_SIZE;
this.voxelHeight = SnipeData.DEFAULT_VOXEL_HEIGHT;
this.cCen = SnipeData.DEFAULT_CYLINDER_CENTER;
this.replaceData = SnipeData.DEFAULT_REPLACE_DATA_VALUE;
this.voxelList = new VoxelList();
}
/**
* @param message
*/
public final void sendMessage(final String message) {
this.owner.getPlayer().sendMessage(message);
}
/**
* @param brushSize the brushSize to set
*/
public final void setBrushSize(final int brushSize) {
this.brushSize = brushSize;
}
/**
* @param cCen the cCen to set
*/
public final void setcCen(final int cCen) {
this.cCen = cCen;
}
/**
* @param data the data to set
*/
public final void setData(final int data) {
this.data = data;
}
/**
* @param replaceData the replaceData to set
*/
public final void setReplaceData(final int replaceData) {
this.replaceData = replaceData;
}
/**
* @param replaceId the replaceId to set
*/
public final void setReplaceId(final int replaceId) {
this.replaceId = replaceId;
}
/**
* @param voxelHeight the voxelHeight to set
*/
public final void setVoxelHeight(final int voxelHeight) {
this.voxelHeight = voxelHeight;
}
/**
* @param voxelId the voxelId to set
*/
public final void setVoxelId(final int voxelId) {
if (WorldEdit.getInstance().getConfiguration().disallowedBlocks.contains(voxelId)) {
if (owner != null) {
Player plr = owner.getPlayer();
if (plr != null) {
plr.sendMessage(ChatColor.RED + "You are not allowed to use '" + voxelId + "'");
return;
}
}
}
this.voxelId = voxelId;
}
/**
* @param voxelList the voxelList to set
*/
public final void setVoxelList(final VoxelList voxelList) {
this.voxelList = voxelList;
}
/**
* @param voxelMessage the voxelMessage to set
*/
public final void setVoxelMessage(final Message voxelMessage) {
this.voxelMessage = voxelMessage;
}
public int getRange() {
return range;
}
public void setRange(int range) {
this.range = range;
}
public boolean isRanged() {
return ranged;
}
public void setRanged(boolean ranged) {
this.ranged = ranged;
}
public boolean isLightningEnabled() {
return lightning;
}
public void setLightningEnabled(boolean lightning) {
this.lightning = lightning;
}
public static Class<?> inject() {
return SnipeData.class;
}
}

Datei anzeigen

@ -0,0 +1,679 @@
/**
This file is part of VoxelSniper, licensed under the MIT License (MIT).
Copyright (c) The VoxelBox <http://thevoxelbox.com>
Copyright (c) contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package com.thevoxelbox.voxelsniper;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.logging.LoggingChangeSet;
import com.boydti.fawe.object.*;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.boydti.fawe.object.extent.ResettableExtent;
import com.boydti.fawe.object.extent.SourceMaskExtent;
import com.boydti.fawe.object.queue.FaweQueueDelegateExtent;
import com.boydti.fawe.util.MaskTraverser;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager;
import com.boydti.fawe.util.WEManager;
import com.google.common.base.Preconditions;
import com.google.common.collect.*;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extent.MaskingExtent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.brush.IBrush;
import com.thevoxelbox.voxelsniper.brush.SnipeBrush;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import com.thevoxelbox.voxelsniper.brush.perform.Performer;
import com.thevoxelbox.voxelsniper.event.SniperMaterialChangedEvent;
import com.thevoxelbox.voxelsniper.event.SniperReplaceMaterialChangedEvent;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.block.Action;
import org.bukkit.material.MaterialData;
import org.bukkit.plugin.PluginManager;
public class Sniper {
private VoxelSniper plugin;
private final UUID player;
private boolean enabled = true;
// private LinkedList<FaweChangeSet> undoList = new LinkedList<>();
private Map<String, SniperTool> tools = new HashMap<>();
public Sniper(VoxelSniper plugin, Player player) {
Preconditions.checkNotNull(plugin);
Preconditions.checkNotNull(player);
this.plugin = plugin;
this.player = player.getUniqueId();
SniperTool sniperTool = new SniperTool(this);
sniperTool.assignAction(SnipeAction.ARROW, Material.ARROW);
sniperTool.assignAction(SnipeAction.GUNPOWDER, Material.GUNPOWDER);
tools.put(null, sniperTool);
}
public String getCurrentToolId() {
return getToolId((getPlayer().getItemInHand() != null) ? getPlayer().getItemInHand().getType() : null);
}
public String getToolId(Material itemInHand) {
if (itemInHand == null) {
return null;
}
for (Map.Entry<String, SniperTool> entry : tools.entrySet()) {
if (entry.getValue().hasToolAssigned(itemInHand)) {
return entry.getKey();
}
}
return null;
}
// Added
private AsyncWorld permanentWorld;
public void storeUndo(Undo undo) {
}
// Added
public AsyncWorld getWorld() {
AsyncWorld world = permanentWorld;
if (world == null) {
Player bukkitPlayer = getPlayer();
World bukkitWorld = bukkitPlayer.getWorld();
world = AsyncWorld.wrap(bukkitWorld);
permanentWorld = world;
}
return world;
}
public Player getPlayer() {
return Bukkit.getPlayer(player);
}
/**
* Sniper execution call.
*
* @param action Action player performed
* @param itemInHand Item in hand of player
* @param clickedBlock Block that the player targeted/interacted with
* @param clickedFace Face of that targeted Block
* @return true if command visibly processed, false otherwise.
*/
public boolean snipe(final Action action, final Material itemInHand, final Block clickedBlock, final BlockFace clickedFace) {
switch (action) {
case LEFT_CLICK_AIR:
case LEFT_CLICK_BLOCK:
case RIGHT_CLICK_AIR:
case RIGHT_CLICK_BLOCK:
break;
default:
return false;
}
if (tools.isEmpty()) {
return false;
}
String toolId = getToolId(itemInHand);
SniperTool sniperTool = tools.get(toolId);
if (sniperTool == null) {
return false;
}
if (!sniperTool.hasToolAssigned(itemInHand)) {
return false;
}
if (sniperTool.getCurrentBrush() == null) {
getPlayer().sendMessage("No Brush selected.");
return false;
}
try {
Player player = getPlayer();
final FawePlayer<Player> fp = FawePlayer.wrap(player);
TaskManager.IMP.taskNow(new Runnable() {
@Override
public void run() {
if (!fp.runAction(new Runnable() {
@Override
public void run() {
snipeOnCurrentThread(fp, action, itemInHand, clickedBlock, clickedFace, sniperTool, toolId);
}
}, false, true)) {
BBC.WORLDEDIT_COMMAND_LIMIT.send(fp);
}
}
}, Fawe.isMainThread());
return true;
} catch (Throwable e) {
e.printStackTrace();
}
return false;
}
// Old method (plus world arg)
public synchronized boolean snipeOnCurrentThread(FawePlayer fp, final Action action, final Material itemInHand, Block clickedBlock, final BlockFace clickedFace, SniperTool sniperTool, String toolId) {
try {
Player bukkitPlayer = getPlayer();
World bukkitWorld = bukkitPlayer.getWorld();
FaweQueue baseQueue = fp.getFaweQueue(false);
Region[] mask = WEManager.IMP.getMask(fp);
if (mask.length == 0) {
BBC.NO_REGION.send(fp);
return false;
}
MaskedFaweQueue maskQueue = new MaskedFaweQueue(baseQueue, mask);
com.sk89q.worldedit.world.World worldEditWorld = fp.getWorld();
FaweChangeSet changeSet = FaweChangeSet.getDefaultChangeSet(worldEditWorld, fp.getUUID());
if (Fawe.imp().getBlocksHubApi() != null) {
changeSet = LoggingChangeSet.wrap(fp, changeSet);
}
FaweQueue changeQueue;
if (Settings.IMP.HISTORY.COMBINE_STAGES) {
changeQueue = maskQueue;
changeSet.addChangeTask(baseQueue);
} else {
changeQueue = new ChangeSetFaweQueue(changeSet, maskQueue);
}
LocalSession session = fp.getSession();
{ // Set mask etc
Mask destMask = session.getMask();
if (!Masks.isNull(destMask)) {
new MaskTraverser(destMask).reset(changeQueue);
changeQueue = new FaweQueueDelegateExtent(changeQueue, new MaskingExtent(changeQueue, destMask));
}
Mask sourceMask = session.getSourceMask();
if (!Masks.isNull(sourceMask)) {
new MaskTraverser(sourceMask).reset(changeQueue);
changeQueue = new FaweQueueDelegateExtent(changeQueue, new SourceMaskExtent(changeQueue, sourceMask));
}
ResettableExtent transform = session.getTransform();
if (transform != null) {
transform.setExtent(changeQueue);
changeQueue = new FaweQueueDelegateExtent(changeQueue, transform);
}
}
AsyncWorld world = getWorld();
world.changeWorld(bukkitWorld, changeQueue);
AsyncBlock asyncBlock = null;
if (clickedBlock != null) {
asyncBlock = world.getBlockAt(clickedBlock.getX(), clickedBlock.getY(), clickedBlock.getZ());
}
if (!getPlayer().hasPermission(sniperTool.getCurrentBrush().getPermissionNode())) {
getPlayer().sendMessage("You are not allowed to use this brush. You're missing the permission node '" + sniperTool.getCurrentBrush().getPermissionNode() + "'");
return true;
}
final SnipeData snipeData = sniperTool.getSnipeData();
if (getPlayer().isSneaking()) {
AsyncBlock targetBlock;
SnipeAction snipeAction = sniperTool.getActionAssigned(itemInHand);
switch (action) {
case LEFT_CLICK_BLOCK:
case LEFT_CLICK_AIR:
if (asyncBlock != null) {
targetBlock = asyncBlock;
} else {
RangeBlockHelper rangeBlockHelper = snipeData.isRanged() ? new RangeBlockHelper(getPlayer(), world, snipeData.getRange()) : new RangeBlockHelper(getPlayer(), world);
targetBlock = snipeData.isRanged() ? rangeBlockHelper.getRangeBlock() : rangeBlockHelper.getTargetBlock();
}
switch (snipeAction) {
case ARROW:
if (targetBlock != null) {
int originalVoxel = snipeData.getVoxelId();
snipeData.setVoxelId(targetBlock.getTypeId());
// SniperMaterialChangedEvent event = new SniperMaterialChangedEvent(this, toolId, BukkitAdapter.adapt(BlockState.get((originalVoxel << BlockTypes.BIT_OFFSET) + snipeData.getPropertyId())), BukkitAdapter.adapt(BlockState.get(snipeData.getVoxelId() + snipeData.getPropertyId())));
// callEvent(event);
snipeData.getVoxelMessage().voxel();
return true;
} else {
int originalVoxel = snipeData.getVoxelId();
snipeData.setVoxelId(BlockTypes.AIR.getInternalId());
// SniperMaterialChangedEvent event = new SniperMaterialChangedEvent(this, toolId, BukkitAdapter.adapt(BlockState.get((originalVoxel << BlockTypes.BIT_OFFSET) + snipeData.getPropertyId())), BukkitAdapter.adapt(BlockState.get(snipeData.getVoxelId() + snipeData.getPropertyId())));
// callEvent(event);
snipeData.getVoxelMessage().voxel();
return true;
}
case GUNPOWDER:
if (targetBlock != null) {
int originalData = snipeData.getPropertyId();
snipeData.setData(targetBlock.getPropertyId());
// SniperMaterialChangedEvent event = new SniperMaterialChangedEvent(this, toolId, BukkitAdapter.adapt(BlockState.get(snipeData.getVoxelId() + originalData)), BukkitAdapter.adapt(BlockState.get(snipeData.getVoxelId() + snipeData.getPropertyId())));
// callEvent(event);
snipeData.getVoxelMessage().data();
return true;
} else {
int originalData = snipeData.getPropertyId();
snipeData.setData(0);
// SniperMaterialChangedEvent event = new SniperMaterialChangedEvent(this, toolId, BukkitAdapter.adapt(BlockState.get(snipeData.getVoxelId() + originalData)), BukkitAdapter.adapt(BlockState.get(snipeData.getVoxelId() + snipeData.getPropertyId())));
// callEvent(event);
snipeData.getVoxelMessage().data();
return true;
}
default:
break;
}
break;
case RIGHT_CLICK_AIR:
case RIGHT_CLICK_BLOCK:
if (asyncBlock != null) {
targetBlock = asyncBlock;
} else {
RangeBlockHelper rangeBlockHelper = snipeData.isRanged() ? new RangeBlockHelper(getPlayer(), world, snipeData.getRange()) : new RangeBlockHelper(getPlayer(), world);
targetBlock = snipeData.isRanged() ? rangeBlockHelper.getRangeBlock() : rangeBlockHelper.getTargetBlock();
}
switch (snipeAction) {
case ARROW:
if (targetBlock != null) {
int originalId = snipeData.getReplaceId();
snipeData.setReplaceId(targetBlock.getTypeId());
// SniperReplaceMaterialChangedEvent event = new SniperReplaceMaterialChangedEvent(this, toolId, BukkitAdapter.adapt(BlockState.get((originalId << BlockTypes.BIT_OFFSET) + snipeData.getReplaceData())), BukkitAdapter.adapt(BlockState.get((snipeData.getReplaceId() << BlockTypes.BIT_OFFSET) + snipeData.getReplaceData())));
// callEvent(event);
snipeData.getVoxelMessage().replace();
return true;
} else {
int originalId = snipeData.getReplaceId();
snipeData.setReplaceId(BlockTypes.AIR.getInternalId());
// SniperReplaceMaterialChangedEvent event = new SniperReplaceMaterialChangedEvent(this, toolId, BukkitAdapter.adapt(BlockState.get((originalId << BlockTypes.BIT_OFFSET) + snipeData.getReplaceData())), BukkitAdapter.adapt(BlockState.get((snipeData.getReplaceId() << BlockTypes.BIT_OFFSET) + snipeData.getReplaceData())));
// callEvent(event);
snipeData.getVoxelMessage().replace();
return true;
}
case GUNPOWDER:
if (targetBlock != null) {
int originalData = snipeData.getReplaceData();
snipeData.setReplaceData(targetBlock.getPropertyId());
// SniperReplaceMaterialChangedEvent event = new SniperReplaceMaterialChangedEvent(this, toolId, BukkitAdapter.adapt(BlockState.get((snipeData.getReplaceId() << BlockTypes.BIT_OFFSET) + originalData)), BukkitAdapter.adapt(BlockState.get((snipeData.getReplaceId() << BlockTypes.BIT_OFFSET) + snipeData.getReplaceData())));
// callEvent(event);
snipeData.getVoxelMessage().replaceData();
return true;
} else {
int originalData = snipeData.getReplaceData();
snipeData.setReplaceData(BlockTypes.AIR.getInternalId());
// SniperReplaceMaterialChangedEvent event = new SniperReplaceMaterialChangedEvent(this, toolId, BukkitAdapter.adapt(BlockState.get((snipeData.getReplaceId() << BlockTypes.BIT_OFFSET) + originalData)), BukkitAdapter.adapt(BlockState.get((snipeData.getReplaceId() << BlockTypes.BIT_OFFSET) + snipeData.getReplaceData())));
// callEvent(event);
snipeData.getVoxelMessage().replaceData();
return true;
}
default:
break;
}
break;
default:
return false;
}
} else {
final AsyncBlock targetBlock;
final AsyncBlock lastBlock;
final SnipeAction snipeAction = sniperTool.getActionAssigned(itemInHand);
switch (action) {
case RIGHT_CLICK_AIR:
case RIGHT_CLICK_BLOCK:
break;
default:
return false;
}
if (asyncBlock != null) {
targetBlock = asyncBlock;
lastBlock = asyncBlock.getRelative(clickedFace);
if (lastBlock == null || targetBlock == null) {
getPlayer().sendMessage(ChatColor.RED + "Snipe target block must be visible.");
return true;
}
} else {
RangeBlockHelper rangeBlockHelper = snipeData.isRanged() ? new RangeBlockHelper(getPlayer(), world, snipeData.getRange()) : new RangeBlockHelper(getPlayer(), world);
targetBlock = snipeData.isRanged() ? rangeBlockHelper.getRangeBlock() : rangeBlockHelper.getTargetBlock();
lastBlock = rangeBlockHelper.getLastBlock();
if (targetBlock == null || lastBlock == null) {
getPlayer().sendMessage(ChatColor.RED + "Snipe target block must be visible.");
return true;
}
}
final IBrush brush = sniperTool.getCurrentBrush();
try {
snipeData.setExtent(world);
Request.reset();
Request.request().setExtent(world);
switch (brush.getClass().getSimpleName()) {
case "JockeyBrush":
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
brush.perform(snipeAction, snipeData, targetBlock, lastBlock);
}
});
break;
default:
if (sniperTool.getCurrentBrush() instanceof PerformBrush) {
PerformBrush performerBrush = (PerformBrush) sniperTool.getCurrentBrush();
performerBrush.initP(snipeData);
}
brush.perform(snipeAction, snipeData, targetBlock, lastBlock);
break;
}
} finally {
snipeData.setExtent(null);
Request.reset();
}
if (Fawe.isMainThread()) {
SetQueue.IMP.flush(changeQueue);
} else {
changeQueue.flush();
}
if (changeSet != null) {
if (Settings.IMP.HISTORY.COMBINE_STAGES) {
changeSet.closeAsync();
} else {
changeSet.close();
}
session.remember(changeSet.toEditSession(fp));
}
return true;
}
return false;
} catch (Throwable e) {
e.printStackTrace();
}
return false;
}
private void callEvent(Event event) {
if (Fawe.isMainThread()) {
Bukkit.getPluginManager().callEvent(event);
} else {
if (event.isAsynchronous()) {
Bukkit.getPluginManager().callEvent(event);
} else {
try {
PluginManager plm = Bukkit.getPluginManager();
Class<? extends PluginManager> clazz = plm.getClass();
Method methodFireEvent = clazz.getDeclaredMethod("fireEvent", Event.class);
methodFireEvent.setAccessible(true);
methodFireEvent.invoke(plm, event);
} catch (Throwable ignore) {}
}
}
}
public IBrush setBrush(String toolId, Class<? extends IBrush> brush) {
if (!tools.containsKey(toolId)) {
return null;
}
return tools.get(toolId).setCurrentBrush(brush);
}
public IBrush getBrush(String toolId) {
if (!tools.containsKey(toolId)) {
return null;
}
return tools.get(toolId).getCurrentBrush();
}
public IBrush previousBrush(String toolId) {
if (!tools.containsKey(toolId)) {
return null;
}
return tools.get(toolId).previousBrush();
}
public boolean setTool(String toolId, SnipeAction action, Material itemInHand) {
for (Map.Entry<String, SniperTool> entry : tools.entrySet()) {
if (entry.getKey() != toolId && entry.getValue().hasToolAssigned(itemInHand)) {
return false;
}
}
if (!tools.containsKey(toolId)) {
SniperTool tool = new SniperTool(this);
tools.put(toolId, tool);
}
tools.get(toolId).assignAction(action, itemInHand);
return true;
}
public void removeTool(String toolId, Material itemInHand) {
if (!tools.containsKey(toolId)) {
SniperTool tool = new SniperTool(this);
tools.put(toolId, tool);
}
tools.get(toolId).unassignAction(itemInHand);
}
public void removeTool(String toolId) {
if (toolId == null) {
return;
}
tools.remove(toolId);
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public void undo() {
undo(1);
}
public void undo(int amount) {
FawePlayer<Object> fp = FawePlayer.wrap(getPlayer());
if (!fp.runAction(new Runnable() {
@Override
public void run() {
int count = 0;
for (int i = 0; i < amount; i++) {
EditSession es = fp.getSession().undo(null, fp.getPlayer());
if (es == null) {
break;
} else {
es.flushQueue();
}
count++;
}
if (count > 0) {
BBC.COMMAND_UNDO_SUCCESS.send(fp);
} else {
BBC.COMMAND_UNDO_ERROR.send(fp);
}
}
}, true, false));
}
public void reset(String toolId) {
SniperTool backup = tools.remove(toolId);
SniperTool newTool = new SniperTool(this);
for (Map.Entry<SnipeAction, Material> entry : backup.getActionTools().entrySet()) {
newTool.assignAction(entry.getKey(), entry.getValue());
}
tools.put(toolId, newTool);
}
public SnipeData getSnipeData(String toolId) {
return tools.containsKey(toolId) ? tools.get(toolId).getSnipeData() : null;
}
public void displayInfo() {
String currentToolId = getCurrentToolId();
SniperTool sniperTool = tools.get(currentToolId);
IBrush brush = sniperTool.getCurrentBrush();
getPlayer().sendMessage("Current Tool: " + ((currentToolId != null) ? currentToolId : "Default Tool"));
if (brush == null) {
getPlayer().sendMessage("No brush selected.");
return;
}
brush.info(sniperTool.getMessageHelper());
if (brush instanceof Performer) {
((Performer) brush).showInfo(sniperTool.getMessageHelper());
}
}
public SniperTool getSniperTool(String toolId) {
return tools.get(toolId);
}
public class SniperTool {
private BiMap<SnipeAction, Material> actionTools = HashBiMap.create();
private ClassToInstanceMap<IBrush> brushes = MutableClassToInstanceMap.create();
private Class<? extends IBrush> currentBrush;
private Class<? extends IBrush> previousBrush;
private SnipeData snipeData;
private Message messageHelper;
private SniperTool(Sniper owner) {
this(SnipeBrush.class, new SnipeData(owner));
}
private SniperTool(Class<? extends IBrush> currentBrush, SnipeData snipeData) {
Preconditions.checkNotNull(currentBrush);
Preconditions.checkNotNull(snipeData);
this.snipeData = snipeData;
messageHelper = new Message(snipeData);
snipeData.setVoxelMessage(messageHelper);
IBrush newBrushInstance = instantiateBrush(currentBrush);
if (snipeData.owner().getPlayer().hasPermission(newBrushInstance.getPermissionNode())) {
brushes.put(currentBrush, newBrushInstance);
this.currentBrush = currentBrush;
}
}
public boolean hasToolAssigned(Material material) {
return actionTools.containsValue(material);
}
public SnipeAction getActionAssigned(Material itemInHand) {
return actionTools.inverse().get(itemInHand);
}
public Material getToolAssigned(SnipeAction action) {
return actionTools.get(action);
}
public void assignAction(SnipeAction action, Material itemInHand) {
actionTools.forcePut(action, itemInHand);
}
public void unassignAction(Material itemInHand) {
actionTools.inverse().remove(itemInHand);
}
public BiMap<SnipeAction, Material> getActionTools() {
return ImmutableBiMap.copyOf(actionTools);
}
public SnipeData getSnipeData() {
return snipeData;
}
public Message getMessageHelper() {
return messageHelper;
}
public IBrush getCurrentBrush() {
if (currentBrush == null) {
return null;
}
return brushes.getInstance(currentBrush);
}
public IBrush setCurrentBrush(Class<? extends IBrush> brush) {
Preconditions.checkNotNull(brush, "Can't set brush to null.");
IBrush brushInstance = brushes.get(brush);
if (brushInstance == null) {
brushInstance = instantiateBrush(brush);
Preconditions.checkNotNull(brushInstance, "Could not instanciate brush class.");
if (snipeData.owner().getPlayer().hasPermission(brushInstance.getPermissionNode())) {
brushes.put(brush, brushInstance);
previousBrush = currentBrush;
currentBrush = brush;
return brushInstance;
}
}
if (snipeData.owner().getPlayer().hasPermission(brushInstance.getPermissionNode())) {
previousBrush = currentBrush;
currentBrush = brush;
return brushInstance;
}
return null;
}
public IBrush previousBrush() {
if (previousBrush == null) {
return null;
}
return setCurrentBrush(previousBrush);
}
private IBrush instantiateBrush(Class<? extends IBrush> brush) {
try {
return brush.newInstance();
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
}
public static Class<?> inject() {
return Sniper.class;
}
}

Datei anzeigen

@ -0,0 +1,30 @@
package com.thevoxelbox.voxelsniper;
import com.google.common.collect.Maps;
import org.bukkit.entity.Player;
import java.util.Map;
import java.util.UUID;
/**
*
*/
public class SniperManager
{
private Map<UUID, Sniper> sniperInstances = Maps.newHashMap();
private VoxelSniper plugin;
public SniperManager(VoxelSniper plugin)
{
this.plugin = plugin;
}
public Sniper getSniperForPlayer(Player player)
{
if (sniperInstances.get(player.getUniqueId()) == null)
{
sniperInstances.put(player.getUniqueId(), new Sniper(plugin, player));
}
return sniperInstances.get(player.getUniqueId());
}
}

Datei anzeigen

@ -0,0 +1,70 @@
/**
This file is part of VoxelSniper, licensed under the MIT License (MIT).
Copyright (c) The VoxelBox <http://thevoxelbox.com>
Copyright (c) contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package com.thevoxelbox.voxelsniper;
import org.bukkit.World;
import org.bukkit.block.Block;
/**
* Holds {@link org.bukkit.block.BlockState}s that can be later on used to reset those block
* locations back to the recorded states.
*/
public class Undo {
int size;
private World world;
/**
* Default constructor of a Undo container.
*/
public Undo() {}
/**
* Get the number of blocks in the collection.
*
* @return size of the Undo collection
*/
public int getSize() {
return size;
}
/**
* Adds a Block to the collection.
*
* @param block Block to be added
*/
public void put(Block block) {
size++;
}
/**
* Set the blockstates of all recorded blocks back to the state when they
* were inserted.
*/
public void undo() {
}
}

Datei anzeigen

@ -0,0 +1,227 @@
package com.thevoxelbox.voxelsniper;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.BukkitCommand;
import com.boydti.fawe.object.FaweCommand;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.util.Jars;
import com.boydti.fawe.util.MainUtil;
import com.google.common.base.Preconditions;
import com.thevoxelbox.voxelsniper.brush.*;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import com.thevoxelbox.voxelsniper.command.VoxelVoxelCommand;
import com.thevoxelbox.voxelsniper.event.SniperBrushChangedEvent;
import com.thevoxelbox.voxelsniper.event.SniperMaterialChangedEvent;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
/**
* Bukkit extension point.
*/
public class VoxelSniper extends JavaPlugin
{
private static VoxelSniper instance;
private SniperManager sniperManager = new SniperManager(this);
private final VoxelSniperListener voxelSniperListener = new VoxelSniperListener(this);
private VoxelSniperConfiguration voxelSniperConfiguration;
/**
* Returns {@link com.thevoxelbox.voxelsniper.Brushes} for current instance.
*
* @return Brush Manager for current instance.
*/
public Brushes getBrushManager()
{
return brushManager;
}
private Brushes brushManager = new Brushes();
/**
* @return {@link VoxelSniper}
*/
public static VoxelSniper getInstance()
{
return VoxelSniper.instance;
}
/**
* Returns object for accessing global VoxelSniper options.
*
* @return {@link VoxelSniperConfiguration} object for accessing global VoxelSniper options.
*/
public VoxelSniperConfiguration getVoxelSniperConfiguration()
{
return voxelSniperConfiguration;
}
/**
* Returns {@link com.thevoxelbox.voxelsniper.SniperManager} for current instance.
*
* @return SniperManager
*/
public SniperManager getSniperManager()
{
return sniperManager;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args)
{
if (sender instanceof Player)
{
String[] arguments = args;
if (arguments == null)
{
arguments = new String[0];
}
return voxelSniperListener.onCommand((Player) sender, arguments, command.getName());
}
getLogger().info("Only Players can execute commands.");
return true;
}
@Override
public void onEnable()
{
VoxelSniper.instance = this;
registerBrushes();
getLogger().info("Registered " + brushManager.registeredSniperBrushes() + " Sniper Brushes with " + brushManager.registeredSniperBrushHandles() + " handles.");
saveDefaultConfig();
voxelSniperConfiguration = new VoxelSniperConfiguration(getConfig());
Bukkit.getPluginManager().registerEvents(this.voxelSniperListener, this);
getLogger().info("Registered Sniper Listener.");
try {
setupCommand("/p", new FaweCommand("voxelsniper.sniper") {
@Override
public boolean execute(FawePlayer fp, String... args) {
Player player = (Player) fp.parent;
return (Bukkit.getPluginManager().getPlugin("VoxelSniper")).onCommand(player, new Command("p") {
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
return false;
}
}, null, args);
}
});
setupCommand("/d", new FaweCommand("voxelsniper.sniper") {
@Override
public boolean execute(FawePlayer fp, String... args) {
Player player = (Player) fp.parent;
return (Bukkit.getPluginManager().getPlugin("VoxelSniper")).onCommand(player, new Command("d") {
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
return false;
}
}, null, args);
}
});
} catch (Throwable ignore) {}
}
/**
* Registers all brushes.
*/
public void registerBrushes()
{
brushManager.registerSniperBrush(BallBrush.class, "b", "ball");
brushManager.registerSniperBrush(BiomeBrush.class, "bio", "biome");
brushManager.registerSniperBrush(BlendBallBrush.class, "bb", "blendball");
brushManager.registerSniperBrush(BlendDiscBrush.class, "bd", "blenddisc");
brushManager.registerSniperBrush(BlendVoxelBrush.class, "bv", "blendvoxel");
brushManager.registerSniperBrush(BlendVoxelDiscBrush.class, "bvd", "blendvoxeldisc");
brushManager.registerSniperBrush(BlobBrush.class, "blob", "splatblob");
brushManager.registerSniperBrush(BlockResetBrush.class, "brb", "blockresetbrush");
brushManager.registerSniperBrush(BlockResetSurfaceBrush.class, "brbs", "blockresetbrushsurface");
brushManager.registerSniperBrush(CanyonBrush.class, "ca", "canyon");
brushManager.registerSniperBrush(CanyonSelectionBrush.class, "cas", "canyonselection");
brushManager.registerSniperBrush(CheckerVoxelDiscBrush.class, "cvd", "checkervoxeldisc");
brushManager.registerSniperBrush(CleanSnowBrush.class, "cls", "cleansnow");
brushManager.registerSniperBrush(CloneStampBrush.class, "cs", "clonestamp");
brushManager.registerSniperBrush(CometBrush.class, "com", "comet");
brushManager.registerSniperBrush(CopyPastaBrush.class, "cp", "copypasta");
brushManager.registerSniperBrush(CylinderBrush.class, "c", "cylinder");
brushManager.registerSniperBrush(DiscBrush.class, "d", "disc");
brushManager.registerSniperBrush(DiscFaceBrush.class, "df", "discface");
brushManager.registerSniperBrush(DomeBrush.class, "dome", "domebrush");
brushManager.registerSniperBrush(DrainBrush.class, "drain");
brushManager.registerSniperBrush(EllipseBrush.class, "el", "ellipse");
brushManager.registerSniperBrush(EllipsoidBrush.class, "elo", "ellipsoid");
brushManager.registerSniperBrush(EntityBrush.class, "en", "entity");
brushManager.registerSniperBrush(EntityRemovalBrush.class, "er", "entityremoval");
brushManager.registerSniperBrush(EraserBrush.class, "erase", "eraser");
brushManager.registerSniperBrush(ErodeBrush.class, "e", "erode");
brushManager.registerSniperBrush(ExtrudeBrush.class, "ex", "extrude");
brushManager.registerSniperBrush(FillDownBrush.class, "fd", "filldown");
brushManager.registerSniperBrush(FlatOceanBrush.class, "fo", "flatocean");
brushManager.registerSniperBrush(GenerateTreeBrush.class, "gt", "generatetree");
brushManager.registerSniperBrush(HeatRayBrush.class, "hr", "heatray");
brushManager.registerSniperBrush(JaggedLineBrush.class, "j", "jagged");
brushManager.registerSniperBrush(JockeyBrush.class, "jockey");
brushManager.registerSniperBrush(LightningBrush.class, "light", "lightning");
brushManager.registerSniperBrush(LineBrush.class, "l", "line");
brushManager.registerSniperBrush(MoveBrush.class, "mv", "move");
brushManager.registerSniperBrush(OceanBrush.class, "o", "ocean");
brushManager.registerSniperBrush(OverlayBrush.class, "over", "overlay");
brushManager.registerSniperBrush(PaintingBrush.class, "paint", "painting");
brushManager.registerSniperBrush(PullBrush.class, "pull");
brushManager.registerSniperBrush(PunishBrush.class, "p", "punish");
brushManager.registerSniperBrush(RandomErodeBrush.class, "re", "randomerode");
brushManager.registerSniperBrush(RegenerateChunkBrush.class, "gc", "generatechunk");
brushManager.registerSniperBrush(RingBrush.class, "ri", "ring");
brushManager.registerSniperBrush(Rot2DBrush.class, "rot2", "rotation2d");
brushManager.registerSniperBrush(Rot2DvertBrush.class, "rot2v", "rotation2dvertical");
brushManager.registerSniperBrush(Rot3DBrush.class, "rot3", "rotation3d");
brushManager.registerSniperBrush(RulerBrush.class, "r", "ruler");
brushManager.registerSniperBrush(ScannerBrush.class, "sc", "scanner");
brushManager.registerSniperBrush(SetBrush.class, "set");
brushManager.registerSniperBrush(SetRedstoneFlipBrush.class, "setrf", "setredstoneflip");
brushManager.registerSniperBrush(ShellBallBrush.class, "shb", "shellball");
brushManager.registerSniperBrush(ShellSetBrush.class, "shs", "shellset");
brushManager.registerSniperBrush(ShellVoxelBrush.class, "shv", "shellvoxel");
brushManager.registerSniperBrush(SignOverwriteBrush.class, "sio", "signoverwriter");
brushManager.registerSniperBrush(SnipeBrush.class, "s", "snipe");
brushManager.registerSniperBrush(SnowConeBrush.class, "snow", "snowcone");
brushManager.registerSniperBrush(SpiralStaircaseBrush.class, "sstair", "spiralstaircase");
brushManager.registerSniperBrush(SplatterBallBrush.class, "sb", "splatball");
brushManager.registerSniperBrush(SplatterDiscBrush.class, "sd", "splatdisc");
brushManager.registerSniperBrush(SplatterOverlayBrush.class, "sover", "splatteroverlay");
brushManager.registerSniperBrush(SplatterVoxelBrush.class, "sv", "splattervoxel");
brushManager.registerSniperBrush(SplatterDiscBrush.class, "svd", "splatvoxeldisc");
brushManager.registerSniperBrush(SplineBrush.class, "sp", "spline");
brushManager.registerSniperBrush(StencilBrush.class, "st", "stencil");
brushManager.registerSniperBrush(StencilListBrush.class, "sl", "stencillist");
brushManager.registerSniperBrush(ThreePointCircleBrush.class, "tpc", "threepointcircle");
brushManager.registerSniperBrush(TreeSnipeBrush.class, "t", "tree", "treesnipe");
brushManager.registerSniperBrush(TriangleBrush.class, "tri", "triangle");
brushManager.registerSniperBrush(UnderlayBrush.class, "under", "underlay");
brushManager.registerSniperBrush(VoltMeterBrush.class, "volt", "voltmeter");
brushManager.registerSniperBrush(VoxelBrush.class, "v", "voxel");
brushManager.registerSniperBrush(VoxelDiscBrush.class, "vd", "voxeldisc");
brushManager.registerSniperBrush(VoxelDiscFaceBrush.class, "vdf", "voxeldiscface");
brushManager.registerSniperBrush(WarpBrush.class, "w", "warp");
}
public void setupCommand(final String label, final FaweCommand cmd) {
this.getCommand(label).setExecutor(new BukkitCommand(cmd));
}
}

Datei anzeigen

@ -0,0 +1,110 @@
package com.thevoxelbox.voxelsniper;
import com.google.common.base.Preconditions;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.List;
/**
* Configuration storage defining global configurations for VoxelSniper.
*/
public class VoxelSniperConfiguration
{
public static final String CONFIG_IDENTIFIER_LITESNIPER_MAX_BRUSH_SIZE = "litesniper-max-brush-size";
public static final String CONFIG_IDENTIFIER_UNDO_CACHE_SIZE = "undo-cache-size";
public static final String CONFIG_IDENTIFIER_LITESNIPER_RESTRICTED_ITEMS = "litesniper-restricted-items";
public static final String CONFIG_IDENTIFIER_MESSAGE_ON_LOGIN_ENABLED = "message-on-login-enabled";
public static final int DEFAULT_LITESNIPER_MAX_BRUSH_SIZE = 5;
public static final int DEFAULT_UNDO_CACHE_SIZE = 20;
public static final boolean DEFAULT_MESSAGE_ON_LOGIN_ENABLED = true;
private FileConfiguration configuration;
/**
* @param configuration Configuration that is going to be used.
*/
public VoxelSniperConfiguration(FileConfiguration configuration)
{
this.configuration = configuration;
}
/**
* Returns the maximum amount of snipes stored in the undo cache of snipers.
*
* @return the maximum amount of snipes stored in the undo cache of snipers
*/
public int getUndoCacheSize()
{
return configuration.getInt(CONFIG_IDENTIFIER_UNDO_CACHE_SIZE, DEFAULT_UNDO_CACHE_SIZE);
}
/**
* Set the maximum amount of snipes stored in the undo cache of snipers.
*
* @param size size of undo cache
*/
public void setUndoCacheSize(int size)
{
configuration.set(CONFIG_IDENTIFIER_UNDO_CACHE_SIZE, size);
}
/**
* Returns maximum size of brushes that LiteSnipers can use.
*
* @return maximum size
*/
public int getLiteSniperMaxBrushSize()
{
return configuration.getInt(CONFIG_IDENTIFIER_LITESNIPER_MAX_BRUSH_SIZE, DEFAULT_LITESNIPER_MAX_BRUSH_SIZE);
}
/**
* Set maximum size of brushes that LiteSnipers can use.
*
* @param size maximum size
*/
public void setLiteSniperMaxBrushSize(int size)
{
configuration.set(CONFIG_IDENTIFIER_LITESNIPER_MAX_BRUSH_SIZE, size);
}
/**
* Returns List of restricted Litesniper Items.
*
* @return List of restricted Litesniper Items
*/
public List<Integer> getLiteSniperRestrictedItems()
{
return configuration.getIntegerList(CONFIG_IDENTIFIER_LITESNIPER_RESTRICTED_ITEMS);
}
/**
* Set new list of restricted Litesniper Items.
*
* @param restrictedItems List of restricted Litesniper Items
*/
public void setLitesniperRestrictedItems(List<Integer> restrictedItems)
{
Preconditions.checkNotNull(restrictedItems, "Restricted items must be a list.");
configuration.set(CONFIG_IDENTIFIER_LITESNIPER_RESTRICTED_ITEMS, restrictedItems);
}
/**
* Returns if the login message is enabled.
*
* @return true if message on login is enabled, false otherwise.
*/
public boolean isMessageOnLoginEnabled()
{
return configuration.getBoolean(CONFIG_IDENTIFIER_MESSAGE_ON_LOGIN_ENABLED, DEFAULT_MESSAGE_ON_LOGIN_ENABLED);
}
/**
* Set the message on login to be enabled or disabled.
*
* @param enabled Message on Login enabled
*/
public void setMessageOnLoginEnabled(boolean enabled)
{
configuration.set(CONFIG_IDENTIFIER_MESSAGE_ON_LOGIN_ENABLED, enabled);
}
}

Datei anzeigen

@ -0,0 +1,138 @@
package com.thevoxelbox.voxelsniper;
import com.thevoxelbox.voxelsniper.api.command.VoxelCommand;
import com.thevoxelbox.voxelsniper.command.*;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import java.util.HashMap;
import java.util.Map;
/**
* @author Voxel
*/
public class VoxelSniperListener implements Listener
{
private static final String SNIPER_PERMISSION = "voxelsniper.sniper";
private final VoxelSniper plugin;
private Map<String, VoxelCommand> commands = new HashMap<String, VoxelCommand>();
/**
* @param plugin
*/
public VoxelSniperListener(final VoxelSniper plugin)
{
this.plugin = plugin;
addCommand(new VoxelBrushCommand(plugin));
addCommand(new VoxelBrushToolCommand(plugin));
addCommand(new VoxelCenterCommand(plugin));
addCommand(new VoxelChunkCommand(plugin));
addCommand(new VoxelDefaultCommand(plugin));
addCommand(new VoxelGoToCommand(plugin));
addCommand(new VoxelHeightCommand(plugin));
addCommand(new VoxelInkCommand(plugin));
addCommand(new VoxelInkReplaceCommand(plugin));
addCommand(new VoxelListCommand(plugin));
addCommand(new VoxelPaintCommand(plugin));
addCommand(new VoxelPerformerCommand(plugin));
addCommand(new VoxelReplaceCommand(plugin));
addCommand(new VoxelSniperCommand(plugin));
addCommand(new VoxelUndoCommand(plugin));
addCommand(new VoxelUndoUserCommand(plugin));
addCommand(new VoxelVoxelCommand(plugin));
}
private void addCommand(final VoxelCommand command)
{
this.commands.put(command.getIdentifier().toLowerCase(), command);
}
/**
* @param player
* @param split
* @param command
* @return boolean Success.
*/
public boolean onCommand(final Player player, final String[] split, final String command)
{
VoxelCommand found = this.commands.get(command.toLowerCase());
if (found == null)
{
return false;
}
if (!hasPermission(found, player))
{
player.sendMessage(ChatColor.RED + "Insufficient Permissions.");
return true;
}
return found.onCommand(player, split);
}
private boolean hasPermission(final VoxelCommand command, final Player player)
{
if (command == null || player == null)
{
// Just a usual check for nulls
return false;
}
else if (command.getPermission() == null || command.getPermission().isEmpty())
{
// This is for commands that do not require a permission node to be executed
return true;
}
else
{
// Should utilize Vault for permission checks if available
return player.hasPermission(command.getPermission());
}
}
/**
* @param event
*/
@EventHandler(ignoreCancelled = false)
public final void onPlayerInteract(final PlayerInteractEvent event)
{
Player player = event.getPlayer();
if (!player.hasPermission(SNIPER_PERMISSION))
{
return;
}
try
{
Sniper sniper = plugin.getSniperManager().getSniperForPlayer(player);
if (sniper.isEnabled() && sniper.snipe(event.getAction(), event.getMaterial(), event.getClickedBlock(), event.getBlockFace()))
{
event.setCancelled(true);
}
}
catch (final Throwable ignored)
{
ignored.printStackTrace();
}
}
/**
* @param event
*/
@EventHandler
public final void onPlayerJoin(final PlayerJoinEvent event)
{
Player player = event.getPlayer();
Sniper sniper = plugin.getSniperManager().getSniperForPlayer(player);
if (player.hasPermission(SNIPER_PERMISSION) && plugin.getVoxelSniperConfiguration().isMessageOnLoginEnabled())
{
sniper.displayInfo();
}
}
}

Datei anzeigen

@ -0,0 +1,81 @@
package com.thevoxelbox.voxelsniper.api.command;
import com.thevoxelbox.voxelsniper.VoxelSniper;
import org.bukkit.entity.Player;
public abstract class VoxelCommand
{
private final String name;
private String description = "";
private String permission = "";
private String identifier = "";
protected final VoxelSniper plugin;
public VoxelCommand(String name, final VoxelSniper plugin)
{
this.name = name;
this.plugin = plugin;
}
public abstract boolean onCommand(final Player player, final String[] args);
public String getDescription()
{
return description;
}
public String getPermission()
{
return this.permission;
}
public String getName()
{
return this.name;
}
public void setDescription(String description)
{
this.description = description;
}
public void setPermission(String permission)
{
this.permission = permission;
}
public String getIdentifier()
{
return this.identifier;
}
public void setIdentifier(String identifier)
{
this.identifier = identifier;
}
public boolean isIdentifier(String offered)
{
return this.identifier.isEmpty() || this.identifier.equalsIgnoreCase(offered);
}
/**
* Padds an empty String to the front of the array.
*
* @param args Array to pad empty string in front of
* @return padded array
*/
protected String[] hackTheArray(String[] args)
{
String[] returnValue = new String[args.length + 1];
returnValue[0] = "";
for (int i = 0, argsLength = args.length; i < argsLength; i++)
{
String arg = args[i];
returnValue[i + 1] = arg;
}
return returnValue;
}
}

Datei anzeigen

@ -0,0 +1,146 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* A brush that creates a solid ball.
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Ball_Brush
*
* @author Piotr
*/
public class BallBrush extends PerformBrush
{
public static final double TRUE_CIRCLE_ON_VALUE = 0.5;
public static final int TRUE_CIRCLE_OFF_VALUE = 0;
private double trueCircle = 0;
/**
*
*/
public BallBrush()
{
this.setName("Ball");
}
private void ball(final SnipeData v, AsyncBlock targetBlock)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
int blockPositionX = targetBlock.getX();
int blockPositionY = targetBlock.getY();
int blockPositionZ = targetBlock.getZ();
this.current.perform(targetBlock);
for (int z = 1; z <= brushSize; z++)
{
final double zSquared = Math.pow(z, 2);
this.current.perform(this.clampY(blockPositionX + z, blockPositionY, blockPositionZ));
this.current.perform(this.clampY(blockPositionX - z, blockPositionY, blockPositionZ));
this.current.perform(this.clampY(blockPositionX, blockPositionY + z, blockPositionZ));
this.current.perform(this.clampY(blockPositionX, blockPositionY - z, blockPositionZ));
this.current.perform(this.clampY(blockPositionX, blockPositionY, blockPositionZ + z));
this.current.perform(this.clampY(blockPositionX, blockPositionY, blockPositionZ - z));
for (int x = 1; x <= brushSize; x++)
{
final double xSquared = Math.pow(x, 2);
if (zSquared + xSquared <= brushSizeSquared)
{
this.current.perform(this.clampY(blockPositionX + z, blockPositionY, blockPositionZ + x));
this.current.perform(this.clampY(blockPositionX + z, blockPositionY, blockPositionZ - x));
this.current.perform(this.clampY(blockPositionX - z, blockPositionY, blockPositionZ + x));
this.current.perform(this.clampY(blockPositionX - z, blockPositionY, blockPositionZ - x));
this.current.perform(this.clampY(blockPositionX + z, blockPositionY + x, blockPositionZ));
this.current.perform(this.clampY(blockPositionX + z, blockPositionY - x, blockPositionZ));
this.current.perform(this.clampY(blockPositionX - z, blockPositionY + x, blockPositionZ));
this.current.perform(this.clampY(blockPositionX - z, blockPositionY - x, blockPositionZ));
this.current.perform(this.clampY(blockPositionX, blockPositionY + z, blockPositionZ + x));
this.current.perform(this.clampY(blockPositionX, blockPositionY + z, blockPositionZ - x));
this.current.perform(this.clampY(blockPositionX, blockPositionY - z, blockPositionZ + x));
this.current.perform(this.clampY(blockPositionX, blockPositionY - z, blockPositionZ - x));
}
for (int y = 1; y <= brushSize; y++)
{
if ((xSquared + Math.pow(y, 2) + zSquared) <= brushSizeSquared)
{
this.current.perform(this.clampY(blockPositionX + x, blockPositionY + y, blockPositionZ + z));
this.current.perform(this.clampY(blockPositionX + x, blockPositionY + y, blockPositionZ - z));
this.current.perform(this.clampY(blockPositionX - x, blockPositionY + y, blockPositionZ + z));
this.current.perform(this.clampY(blockPositionX - x, blockPositionY + y, blockPositionZ - z));
this.current.perform(this.clampY(blockPositionX + x, blockPositionY - y, blockPositionZ + z));
this.current.perform(this.clampY(blockPositionX + x, blockPositionY - y, blockPositionZ - z));
this.current.perform(this.clampY(blockPositionX - x, blockPositionY - y, blockPositionZ + z));
this.current.perform(this.clampY(blockPositionX - x, blockPositionY - y, blockPositionZ - z));
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.ball(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.ball(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Ball Brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b b true -- will use a true sphere algorithm instead of the skinnier version with classic sniper nubs. /b b false will switch back. (false is default)");
return;
}
else if (parameter.startsWith("true"))
{
this.trueCircle = TRUE_CIRCLE_ON_VALUE;
v.sendMessage(ChatColor.AQUA + "True circle mode ON.");
}
else if (parameter.startsWith("false"))
{
this.trueCircle = TRUE_CIRCLE_OFF_VALUE;
v.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.ball";
}
}

Datei anzeigen

@ -0,0 +1,126 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
/**
*
*/
public class BiomeBrush extends Brush
{
private Biome selectedBiome = Biome.PLAINS;
/**
*
*/
public BiomeBrush()
{
this.setName("Biome (/b biome [Biome Name])");
}
private void biome(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize, 2);
for (int x = -brushSize; x <= brushSize; x++)
{
final double xSquared = Math.pow(x, 2);
for (int z = -brushSize; z <= brushSize; z++)
{
if ((xSquared + Math.pow(z, 2)) <= brushSizeSquared)
{
this.getWorld().setBiome(this.getTargetBlock().getX() + x, this.getTargetBlock().getZ() + z, this.selectedBiome);
}
}
}
final Block block1 = this.getWorld().getBlockAt(this.getTargetBlock().getX() - brushSize, 0, this.getTargetBlock().getZ() - brushSize);
final Block block2 = this.getWorld().getBlockAt(this.getTargetBlock().getX() + brushSize, 0, this.getTargetBlock().getZ() + brushSize);
final int lowChunkX = (block1.getX() <= block2.getX()) ? block1.getChunk().getX() : block2.getChunk().getX();
final int lowChunkZ = (block1.getZ() <= block2.getZ()) ? block1.getChunk().getZ() : block2.getChunk().getZ();
final int highChunkX = (block1.getX() >= block2.getX()) ? block1.getChunk().getX() : block2.getChunk().getX();
final int highChunkZ = (block1.getZ() >= block2.getZ()) ? block1.getChunk().getZ() : block2.getChunk().getZ();
for (int x = lowChunkX; x <= highChunkX; x++)
{
for (int z = lowChunkZ; z <= highChunkZ; z++)
{
this.getWorld().refreshChunk(x, z);
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.biome(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.biome(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.custom(ChatColor.GOLD + "Currently selected biome type: " + ChatColor.DARK_GREEN + this.selectedBiome.name());
}
@Override
public final void parameters(final String[] args, final SnipeData v)
{
if (args[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Biome Brush Parameters:");
String availableBiomes = "";
for (final Biome biome : Biome.values())
{
if (availableBiomes.isEmpty())
{
availableBiomes = ChatColor.DARK_GREEN + biome.name();
continue;
}
availableBiomes += ChatColor.RED + ", " + ChatColor.DARK_GREEN + biome.name();
}
v.sendMessage(ChatColor.DARK_BLUE + "Available biomes: " + availableBiomes);
}
else
{
// allows biome names with spaces in their name
String biomeName = args[1];
for (int i = 2; i < args.length; i++)
{
biomeName += " " + args[i];
}
for (final Biome biome : Biome.values())
{
if (biome.name().equalsIgnoreCase(biomeName))
{
this.selectedBiome = biome;
break;
}
}
v.sendMessage(ChatColor.GOLD + "Currently selected biome type: " + ChatColor.DARK_GREEN + this.selectedBiome.name());
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.biome";
}
}

Datei anzeigen

@ -0,0 +1,162 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Blend_Brushes
*/
public class BlendBallBrush extends BlendBrushBase
{
/**
*
*/
public BlendBallBrush()
{
this.setName("Blend Ball");
}
@SuppressWarnings("deprecation")
@Override
protected final void blend(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final int brushSizeDoubled = 2 * brushSize;
// Array that holds the original materials plus a buffer
final int[][][] oldMaterials = new int[2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1];
// Array that holds the blended materials
final int[][][] newMaterials = new int[brushSizeDoubled + 1][brushSizeDoubled + 1][brushSizeDoubled + 1];
// Log current materials into oldmats
for (int x = 0; x <= 2 * (brushSize + 1); x++)
{
for (int y = 0; y <= 2 * (brushSize + 1); y++)
{
for (int z = 0; z <= 2 * (brushSize + 1); z++)
{
oldMaterials[x][y][z] = this.getBlockIdAt(this.getTargetBlock().getX() - brushSize - 1 + x, this.getTargetBlock().getY() - brushSize - 1 + y, this.getTargetBlock().getZ() - brushSize - 1 + z);
}
}
}
// Log current materials into newmats
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int y = 0; y <= brushSizeDoubled; y++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
newMaterials[x][y][z] = oldMaterials[x + 1][y + 1][z + 1];
}
}
}
// Blend materials
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int y = 0; y <= brushSizeDoubled; y++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
final int[] materialFrequency = new int[BlockTypes.size()]; // Array that tracks frequency of materials neighboring given block
int modeMatCount = 0;
int modeMatId = 0;
boolean tiecheck = true;
for (int m = -1; m <= 1; m++)
{
for (int n = -1; n <= 1; n++)
{
for (int o = -1; o <= 1; o++)
{
if (!(m == 0 && n == 0 && o == 0))
{
materialFrequency[oldMaterials[x + 1 + m][y + 1 + n][z + 1 + o]]++;
}
}
}
}
// Find most common neighboring material.
for (BlockTypes type : BlockTypes.values)
{
int i = type.getInternalId();
if (materialFrequency[i] > modeMatCount && !(this.excludeAir && type.getMaterial().isAir()) && !(this.excludeWater && (type == BlockTypes.WATER)))
{
modeMatCount = materialFrequency[i];
modeMatId = i;
}
}
// Make sure there'world not a tie for most common
for (int i = 0; i < modeMatId; i++)
{
BlockTypes type = BlockTypes.get(i);
if (materialFrequency[i] == modeMatCount && !(this.excludeAir && type.getMaterial().isAir()) && !(this.excludeWater && (type == BlockTypes.WATER)))
{
tiecheck = false;
}
}
// Record most common neighbor material for this block
if (tiecheck)
{
newMaterials[x][y][z] = modeMatId;
}
}
}
}
final Undo undo = new Undo();
final double rSquared = Math.pow(brushSize + 1, 2);
// Make the changes
for (int x = brushSizeDoubled; x >= 0; x--)
{
final double xSquared = Math.pow(x - brushSize - 1, 2);
for (int y = 0; y <= brushSizeDoubled; y++)
{
final double ySquared = Math.pow(y - brushSize - 1, 2);
for (int z = brushSizeDoubled; z >= 0; z--)
{
if (xSquared + ySquared + Math.pow(z - brushSize - 1, 2) <= rSquared)
{
if (!(this.excludeAir && BlockTypes.get(newMaterials[x][y][z]).getMaterial().isAir()) && !(this.excludeWater && (newMaterials[x][y][z] == BlockTypes.WATER.getInternalId())))
{
if (this.getBlockIdAt(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY() - brushSize + y, this.getTargetBlock().getZ() - brushSize + z) != newMaterials[x][y][z])
{
undo.put(this.clampY(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY() - brushSize + y, this.getTargetBlock().getZ() - brushSize + z));
}
this.setBlockIdAt(this.getTargetBlock().getZ() - brushSize + z, this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY() - brushSize + y, newMaterials[x][y][z]);
}
}
}
}
}
v.owner().storeUndo(undo);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Blend Ball Parameters:");
v.sendMessage(ChatColor.AQUA + "/b bb water -- toggle include or exclude (default: exclude) water");
return;
}
super.parameters(par, v);
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.blendball";
}
}

Datei anzeigen

@ -0,0 +1,93 @@
package com.thevoxelbox.voxelsniper.brush;
import com.bekvon.bukkit.residence.commands.material;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
import org.bukkit.Material;
/**
* @author Monofraps
*/
@SuppressWarnings("deprecation")
public abstract class BlendBrushBase extends Brush
{
protected boolean excludeAir = true;
protected boolean excludeWater = true;
/**
* @param v
*/
protected abstract void blend(final SnipeData v);
@Override
protected final void arrow(final SnipeData v)
{
this.excludeAir = false;
this.blend(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.excludeAir = true;
this.blend(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.voxel();
vm.custom(ChatColor.BLUE + "Water Mode: " + (this.excludeWater ? "exclude" : "include"));
}
@Override
public void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; ++i)
{
if (par[i].equalsIgnoreCase("water"))
{
this.excludeWater = !this.excludeWater;
v.sendMessage(ChatColor.AQUA + "Water Mode: " + (this.excludeWater ? "exclude" : "include"));
}
}
}
/**
* @return
*/
protected final boolean isExcludeAir()
{
return excludeAir;
}
/**
* @param excludeAir
*/
protected final void setExcludeAir(boolean excludeAir)
{
this.excludeAir = excludeAir;
}
/**
* @return
*/
protected final boolean isExcludeWater()
{
return excludeWater;
}
/**
* @param excludeWater
*/
protected final void setExcludeWater(boolean excludeWater)
{
this.excludeWater = excludeWater;
}
}

Datei anzeigen

@ -0,0 +1,143 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Blend_Brushes
*/
public class BlendDiscBrush extends BlendBrushBase
{
/**
*
*/
public BlendDiscBrush()
{
this.setName("Blend Disc");
}
@SuppressWarnings("deprecation")
@Override
protected final void blend(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final int brushSizeDoubled = 2 * brushSize;
final int[][] oldMaterials = new int[2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1]; // Array that holds the original materials plus a buffer
final int[][] newMaterials = new int[brushSizeDoubled + 1][brushSizeDoubled + 1]; // Array that holds the blended materials
// Log current materials into oldmats
for (int x = 0; x <= 2 * (brushSize + 1); x++)
{
for (int z = 0; z <= 2 * (brushSize + 1); z++)
{
oldMaterials[x][z] = this.getBlockIdAt(this.getTargetBlock().getX() - brushSize - 1 + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - brushSize - 1 + z);
}
}
// Log current materials into newmats
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
newMaterials[x][z] = oldMaterials[x + 1][z + 1];
}
}
// Blend materials
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
final int[] materialFrequency = new int[BlockTypes.size()]; // Array that tracks frequency of materials neighboring given block
int modeMatCount = 0;
int modeMatId = 0;
boolean tiecheck = true;
for (int m = -1; m <= 1; m++)
{
for (int n = -1; n <= 1; n++)
{
if (!(m == 0 && n == 0))
{
materialFrequency[oldMaterials[x + 1 + m][z + 1 + n]]++;
}
}
}
// Find most common neighboring material.
for (BlockTypes type : BlockTypes.values)
{
int i = type.getInternalId();
if (materialFrequency[i] > modeMatCount && !(this.excludeAir && type.getMaterial().isAir()) && !(this.excludeWater && (type == BlockTypes.WATER)))
{
modeMatCount = materialFrequency[i];
modeMatId = i;
}
}
// Make sure there'world not a tie for most common
for (int i = 0; i < modeMatId; i++)
{
BlockTypes type = BlockTypes.get(i);
if (materialFrequency[i] == modeMatCount && !(this.excludeAir && type.getMaterial().isAir()) && !(this.excludeWater && (type == BlockTypes.WATER)))
{
tiecheck = false;
}
}
// Record most common neighbor material for this block
if (tiecheck)
{
newMaterials[x][z] = modeMatId;
}
}
}
final Undo undo = new Undo();
final double rSquared = Math.pow(brushSize + 1, 2);
// Make the changes
for (int x = brushSizeDoubled; x >= 0; x--)
{
final double xSquared = Math.pow(x - brushSize - 1, 2);
for (int z = brushSizeDoubled; z >= 0; z--)
{
if (xSquared + Math.pow(z - brushSize - 1, 2) <= rSquared)
{
if (!(this.excludeAir && BlockTypes.get(newMaterials[x][z]).getMaterial().isAir()) && !(this.excludeWater && (newMaterials[x][z] == BlockTypes.WATER.getInternalId())))
{
if (this.getBlockIdAt(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - brushSize + z) != newMaterials[x][z])
{
undo.put(this.clampY(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - brushSize + z));
}
this.setBlockIdAt(this.getTargetBlock().getZ() - brushSize + z, this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY(), newMaterials[x][z]);
}
}
}
}
v.owner().storeUndo(undo);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Blend Disc Parameters:");
v.sendMessage(ChatColor.AQUA + "/b bd water -- toggle include or exclude (default) water");
return;
}
super.parameters(par, v);
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.blenddisc";
}
}

Datei anzeigen

@ -0,0 +1,155 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Blend_Brushes
*/
public class BlendVoxelBrush extends BlendBrushBase
{
/**
*
*/
public BlendVoxelBrush()
{
this.setName("Blend Voxel");
}
@SuppressWarnings("deprecation")
@Override
protected final void blend(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final int brushSizeDoubled = 2 * brushSize;
// Array that holds the original materials plus a buffer
final int[][][] oldMaterials = new int[2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1];
// Array that holds the blended materials
final int[][][] newMaterials = new int[brushSizeDoubled + 1][brushSizeDoubled + 1][brushSizeDoubled + 1];
// Log current materials into oldmats
for (int x = 0; x <= 2 * (brushSize + 1); x++)
{
for (int y = 0; y <= 2 * (brushSize + 1); y++)
{
for (int z = 0; z <= 2 * (brushSize + 1); z++)
{
oldMaterials[x][y][z] = this.getBlockIdAt(this.getTargetBlock().getX() - brushSize - 1 + x, this.getTargetBlock().getY() - brushSize - 1 + y, this.getTargetBlock().getZ() - brushSize - 1 + z);
}
}
}
// Log current materials into newmats
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int y = 0; y <= brushSizeDoubled; y++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
newMaterials[x][y][z] = oldMaterials[x + 1][y + 1][z + 1];
}
}
}
// Blend materials
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int y = 0; y <= brushSizeDoubled; y++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
final int[] materialFrequency = new int[BlockTypes.size()]; // Array that tracks frequency of materials neighboring given block
int modeMatCount = 0;
int modeMatId = 0;
boolean tiecheck = true;
for (int m = -1; m <= 1; m++)
{
for (int n = -1; n <= 1; n++)
{
for (int o = -1; o <= 1; o++)
{
if (!(m == 0 && n == 0 && o == 0))
{
materialFrequency[oldMaterials[x + 1 + m][y + 1 + n][z + 1 + o]]++;
}
}
}
}
// Find most common neighboring material.
for (BlockTypes type : BlockTypes.values)
{
int i = type.getInternalId();
if (materialFrequency[i] > modeMatCount && !(this.excludeAir && type.getMaterial().isAir()) && !(this.excludeWater && (type == BlockTypes.WATER)))
{
modeMatCount = materialFrequency[i];
modeMatId = i;
}
}
// Make sure there'world not a tie for most common
for (int i = 0; i < modeMatId; i++)
{
BlockTypes type = BlockTypes.get(i);
if (materialFrequency[i] == modeMatCount && !(this.excludeAir && type.getMaterial().isAir()) && !(this.excludeWater && (type == BlockTypes.WATER)))
{
tiecheck = false;
}
}
// Record most common neighbor material for this block
if (tiecheck)
{
newMaterials[x][y][z] = modeMatId;
}
}
}
}
final Undo undo = new Undo();
// Make the changes
for (int x = brushSizeDoubled; x >= 0; x--)
{
for (int y = 0; y <= brushSizeDoubled; y++)
{
for (int z = brushSizeDoubled; z >= 0; z--)
{
if (!(this.excludeAir && BlockTypes.get(newMaterials[x][y][z]).getMaterial().isAir()) && !(this.excludeWater && (newMaterials[x][y][z] == BlockTypes.WATER.getInternalId())))
{
if (this.getBlockIdAt(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY() - brushSize + y, this.getTargetBlock().getZ() - brushSize + z) != newMaterials[x][y][z])
{
undo.put(this.clampY(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY() - brushSize + y, this.getTargetBlock().getZ() - brushSize + z));
}
this.setBlockIdAt(this.getTargetBlock().getZ() - brushSize + z, this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY() - brushSize + y, newMaterials[x][y][z]);
}
}
}
}
v.owner().storeUndo(undo);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Blend Voxel Parameters:");
v.sendMessage(ChatColor.AQUA + "/b bv water -- toggle include or exclude (default) water");
return;
}
super.parameters(par, v);
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.blendvoxel";
}
}

Datei anzeigen

@ -0,0 +1,139 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Blend_Brushes
*/
public class BlendVoxelDiscBrush extends BlendBrushBase
{
/**
*
*/
public BlendVoxelDiscBrush()
{
this.setName("Blend Voxel Disc");
}
@SuppressWarnings("deprecation")
@Override
protected final void blend(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final int brushSizeDoubled = 2 * brushSize;
final int[][] oldMaterials = new int[2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1]; // Array that holds the original materials plus a buffer
final int[][] newMaterials = new int[brushSizeDoubled + 1][brushSizeDoubled + 1]; // Array that holds the blended materials
// Log current materials into oldmats
for (int x = 0; x <= 2 * (brushSize + 1); x++)
{
for (int z = 0; z <= 2 * (brushSize + 1); z++)
{
oldMaterials[x][z] = this.getBlockIdAt(this.getTargetBlock().getX() - brushSize - 1 + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - brushSize - 1 + z);
}
}
// Log current materials into newmats
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
newMaterials[x][z] = oldMaterials[x + 1][z + 1];
}
}
// Blend materials
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
final int[] materialFrequency = new int[BlockTypes.size()]; // Array that tracks frequency of materials neighboring given block
int modeMatCount = 0;
int modeMatId = 0;
boolean tiecheck = true;
for (int m = -1; m <= 1; m++)
{
for (int n = -1; n <= 1; n++)
{
if (!(m == 0 && n == 0))
{
materialFrequency[oldMaterials[x + 1 + m][z + 1 + n]]++;
}
}
}
// Find most common neighboring material.
for (BlockTypes type : BlockTypes.values)
{
int i = type.getInternalId();
if (materialFrequency[i] > modeMatCount && !(this.excludeAir && type.getMaterial().isAir()) && !(this.excludeWater && (type == BlockTypes.WATER)))
{
modeMatCount = materialFrequency[i];
modeMatId = i;
}
}
// Make sure there'world not a tie for most common
for (int i = 0; i < modeMatId; i++)
{
BlockTypes type = BlockTypes.get(i);
if (materialFrequency[i] == modeMatCount && !(this.excludeAir && type.getMaterial().isAir()) && !(this.excludeWater && (type == BlockTypes.WATER)))
{
tiecheck = false;
}
}
// Record most common neighbor material for this block
if (tiecheck)
{
newMaterials[x][z] = modeMatId;
}
}
}
final Undo undo = new Undo();
// Make the changes
for (int x = brushSizeDoubled; x >= 0; x--)
{
for (int z = brushSizeDoubled; z >= 0; z--)
{
if (!(this.excludeAir && BlockTypes.get(newMaterials[x][z]).getMaterial().isAir()) && !(this.excludeWater && (newMaterials[x][z] == BlockTypes.WATER.getInternalId())))
{
if (this.getBlockIdAt(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - brushSize + z) != newMaterials[x][z])
{
undo.put(this.clampY(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - brushSize + z));
}
this.setBlockIdAt(this.getTargetBlock().getZ() - brushSize + z, this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY(), newMaterials[x][z]);
}
}
}
v.owner().storeUndo(undo);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Blend Voxel Disc Parameters:");
v.sendMessage(ChatColor.AQUA + "/b bvd water -- toggle include or exclude (default) water");
return;
}
super.parameters(par, v);
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.blendvoxeldisc";
}
}

Datei anzeigen

@ -0,0 +1,313 @@
package com.thevoxelbox.voxelsniper.brush;
import java.util.Random;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Blob_Brush
*
* @author Giltwist
*/
public class BlobBrush extends PerformBrush
{
private static final int GROW_PERCENT_DEFAULT = 1000;
private static final int GROW_PERCENT_MIN = 1;
private static final int GROW_PERCENT_MAX = 9999;
private Random randomGenerator = new Random();
private int growPercent = GROW_PERCENT_DEFAULT; // chance block on recursion pass is made active
/**
*
*/
public BlobBrush()
{
this.setName("Blob");
}
private void checkValidGrowPercent(final SnipeData v)
{
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
this.growPercent = GROW_PERCENT_DEFAULT;
v.sendMessage(ChatColor.BLUE + "Growth percent set to: 10%");
}
}
private void digBlob(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final int brushSizeDoubled = 2 * brushSize;
final int[][][] splat = new int[brushSizeDoubled + 1][brushSizeDoubled + 1][brushSizeDoubled + 1];
final int[][][] tempSplat = new int[brushSizeDoubled + 1][brushSizeDoubled + 1][brushSizeDoubled + 1];
this.checkValidGrowPercent(v);
// Seed the array
for (int x = brushSizeDoubled; x >= 0; x--)
{
for (int y = brushSizeDoubled; y >= 0; y--)
{
for (int z = brushSizeDoubled; z >= 0; z--)
{
if ((x == 0 || y == 0 | z == 0 || x == brushSizeDoubled || y == brushSizeDoubled || z == brushSizeDoubled) && this.randomGenerator.nextInt(GROW_PERCENT_MAX + 1) <= this.growPercent)
{
splat[x][y][z] = 0;
}
else
{
splat[x][y][z] = 1;
}
}
}
}
// Grow the seed
for (int r = 0; r < brushSize; r++)
{
for (int x = brushSizeDoubled; x >= 0; x--)
{
for (int y = brushSizeDoubled; y >= 0; y--)
{
for (int z = brushSizeDoubled; z >= 0; z--)
{
tempSplat[x][y][z] = splat[x][y][z];
double growCheck = 0;
if (splat[x][y][z] == 1)
{
if (x != 0 && splat[x - 1][y][z] == 0)
{
growCheck++;
}
if (y != 0 && splat[x][y - 1][z] == 0)
{
growCheck++;
}
if (z != 0 && splat[x][y][z - 1] == 0)
{
growCheck++;
}
if (x != 2 * brushSize && splat[x + 1][y][z] == 0)
{
growCheck++;
}
if (y != 2 * brushSize && splat[x][y + 1][z] == 0)
{
growCheck++;
}
if (z != 2 * brushSize && splat[x][y][z + 1] == 0)
{
growCheck++;
}
}
if (growCheck >= 1 && this.randomGenerator.nextInt(GROW_PERCENT_MAX + 1) <= this.growPercent)
{
tempSplat[x][y][z] = 0; // prevent bleed into splat
}
}
}
}
// shouldn't this just be splat = tempsplat;? -Gavjenks
// integrate tempsplat back into splat at end of iteration
for (int x = brushSizeDoubled; x >= 0; x--)
{
for (int y = brushSizeDoubled; y >= 0; y--)
{
for (int z = brushSizeDoubled; z >= 0; z--)
{
splat[x][y][z] = tempSplat[x][y][z];
}
}
}
}
final double rSquared = Math.pow(brushSize + 1, 2);
// Make the changes
for (int x = brushSizeDoubled; x >= 0; x--)
{
final double xSquared = Math.pow(x - brushSize - 1, 2);
for (int y = brushSizeDoubled; y >= 0; y--)
{
final double ySquared = Math.pow(y - brushSize - 1, 2);
for (int z = brushSizeDoubled; z >= 0; z--)
{
if (splat[x][y][z] == 1 && xSquared + ySquared + Math.pow(z - brushSize - 1, 2) <= rSquared)
{
this.current.perform(this.clampY(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY() - brushSize + z, this.getTargetBlock().getZ() - brushSize + y));
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
private void growBlob(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final int brushSizeDoubled = 2 * brushSize;
final int[][][] splat = new int[brushSizeDoubled + 1][brushSizeDoubled + 1][brushSizeDoubled + 1];
final int[][][] tempSplat = new int[brushSizeDoubled + 1][brushSizeDoubled + 1][brushSizeDoubled + 1];
this.checkValidGrowPercent(v);
// Seed the array
splat[brushSize][brushSize][brushSize] = 1;
// Grow the seed
for (int r = 0; r < brushSize; r++)
{
for (int x = brushSizeDoubled; x >= 0; x--)
{
for (int y = brushSizeDoubled; y >= 0; y--)
{
for (int z = brushSizeDoubled; z >= 0; z--)
{
tempSplat[x][y][z] = splat[x][y][z];
int growCheck = 0;
if (splat[x][y][z] == 0)
{
if (x != 0 && splat[x - 1][y][z] == 1)
{
growCheck++;
}
if (y != 0 && splat[x][y - 1][z] == 1)
{
growCheck++;
}
if (z != 0 && splat[x][y][z - 1] == 1)
{
growCheck++;
}
if (x != 2 * brushSize && splat[x + 1][y][z] == 1)
{
growCheck++;
}
if (y != 2 * brushSize && splat[x][y + 1][z] == 1)
{
growCheck++;
}
if (z != 2 * brushSize && splat[x][y][z + 1] == 1)
{
growCheck++;
}
}
if (growCheck >= 1 && this.randomGenerator.nextInt(GROW_PERCENT_MAX + 1) <= this.growPercent)
{
// prevent bleed into splat
tempSplat[x][y][z] = 1;
}
}
}
}
// integrate tempsplat back into splat at end of iteration
for (int x = brushSizeDoubled; x >= 0; x--)
{
for (int y = brushSizeDoubled; y >= 0; y--)
{
for (int z = brushSizeDoubled; z >= 0; z--)
{
splat[x][y][z] = tempSplat[x][y][z];
}
}
}
}
final double rSquared = Math.pow(brushSize + 1, 2);
// Make the changes
for (int x = brushSizeDoubled; x >= 0; x--)
{
final double xSquared = Math.pow(x - brushSize - 1, 2);
for (int y = brushSizeDoubled; y >= 0; y--)
{
final double ySquared = Math.pow(y - brushSize - 1, 2);
for (int z = brushSizeDoubled; z >= 0; z--)
{
if (splat[x][y][z] == 1 && xSquared + ySquared + Math.pow(z - brushSize - 1, 2) <= rSquared)
{
this.current.perform(this.clampY(this.getTargetBlock().getX() - brushSize + x, this.getTargetBlock().getY() - brushSize + z, this.getTargetBlock().getZ() - brushSize + y));
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.growBlob(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.digBlob(v);
}
@Override
public final void info(final Message vm)
{
this.checkValidGrowPercent(null);
vm.brushName(this.getName());
vm.size();
vm.custom(ChatColor.BLUE + "Growth percent set to: " + this.growPercent / 100 + "%");
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Blob brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b blob g[int] -- set a growth percentage (" + GROW_PERCENT_MIN + "-" + GROW_PERCENT_MAX + "). Default is " + GROW_PERCENT_DEFAULT);
return;
}
if (parameter.startsWith("g"))
{
final int temp = Integer.parseInt(parameter.replace("g", ""));
if (temp >= GROW_PERCENT_MIN && temp <= GROW_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Growth percent set to: " + (float) temp / 100 + "%");
this.growPercent = temp;
}
else
{
v.sendMessage(ChatColor.RED + "Growth percent must be an integer " + GROW_PERCENT_MIN + "-" + GROW_PERCENT_MAX + "!");
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.blob";
}
}

Datei anzeigen

@ -0,0 +1,90 @@
package com.thevoxelbox.voxelsniper.brush;
import java.util.ArrayList;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.Material;
import org.bukkit.block.Block;
/**
* @author MikeMatrix
*/
public class BlockResetBrush extends Brush
{
private static final ArrayList<Material> DENIED_UPDATES = new ArrayList<Material>();
static
{
BlockResetBrush.DENIED_UPDATES.add(Material.SIGN);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_SIGN_POST);
BlockResetBrush.DENIED_UPDATES.add(Material.WALL_SIGN);
BlockResetBrush.DENIED_UPDATES.add(Material.CHEST);
BlockResetBrush.DENIED_UPDATES.add(Material.FURNACE);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_BURNING_FURNACE);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_REDSTONE_TORCH_OFF);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_REDSTONE_TORCH_ON);
BlockResetBrush.DENIED_UPDATES.add(Material.REDSTONE_WIRE);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_DIODE_BLOCK_OFF);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_DIODE_BLOCK_ON);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_WOODEN_DOOR);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_WOOD_DOOR);
BlockResetBrush.DENIED_UPDATES.add(Material.IRON_DOOR);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_IRON_DOOR_BLOCK);
BlockResetBrush.DENIED_UPDATES.add(Material.LEGACY_FENCE_GATE);
}
/**
*
*/
public BlockResetBrush()
{
this.setName("Block Reset Brush");
}
@SuppressWarnings("deprecation")
private void applyBrush(final SnipeData v)
{
for (int z = -v.getBrushSize(); z <= v.getBrushSize(); z++)
{
for (int x = -v.getBrushSize(); x <= v.getBrushSize(); x++)
{
for (int y = -v.getBrushSize(); y <= v.getBrushSize(); y++)
{
final Block block = this.getWorld().getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z);
if (BlockResetBrush.DENIED_UPDATES.contains(block.getType()))
{
continue;
}
block.setBlockData(block.getType().createBlockData(), true);
}
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
applyBrush(v);
}
@Override
protected final void powder(final SnipeData v)
{
applyBrush(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.blockreset";
}
}

Datei anzeigen

@ -0,0 +1,154 @@
package com.thevoxelbox.voxelsniper.brush;
import java.util.ArrayList;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
/**
* This brush only looks for solid blocks, and then changes those plus any air blocks touching them. If it works, this brush should be faster than the original
* blockPositionY an amount proportional to the volume of a snipe selection area / the number of blocks touching air in the selection. This is because every solid block
* surrounded blockPositionY others should take equally long to check and not change as it would take MC to change them and then check and find no lighting to update. For
* air blocks surrounded blockPositionY other air blocks, this brush saves about 80-100 checks blockPositionY not updating them or their lighting. And for air blocks touching solids,
* this brush is slower, because it replaces the air once per solid block it is touching. I assume on average this is about 2 blocks. So every air block
* touching a solid negates one air block floating in air. Thus, for selections that have more air blocks surrounded blockPositionY air than air blocks touching solids,
* this brush will be faster, which is almost always the case, especially for undeveloped terrain and for larger brush sizes (unlike the original brush, this
* should only slow down blockPositionY the square of the brush size, not the cube of the brush size). For typical terrain, blockPositionY my calculations, overall speed increase is
* about a factor of 5-6 for a size 20 brush. For a complicated city or ship, etc., this may be only a factor of about 2. In a hypothetical worst case scenario
* of a 3d checkerboard of stone and air every other block, this brush should only be about 1.5x slower than the original brush. Savings increase for larger
* brushes.
*
* @author GavJenks
*/
public class BlockResetSurfaceBrush extends Brush
{
/**
*
*/
public BlockResetSurfaceBrush()
{
this.setName("Block Reset Brush Surface Only");
}
@SuppressWarnings("deprecation")
private void applyBrush(final SnipeData v)
{
final AsyncWorld world = this.getWorld();
for (int z = -v.getBrushSize(); z <= v.getBrushSize(); z++)
{
for (int x = -v.getBrushSize(); x <= v.getBrushSize(); x++)
{
for (int y = -v.getBrushSize(); y <= v.getBrushSize(); y++)
{
AsyncBlock block = world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z);
Material type = block.getType();
BlockMaterial mat = BukkitAdapter.adapt(type).getMaterial();
if (!mat.isSolid() || !mat.isFullCube() || mat.hasContainer())
{
continue;
}
boolean airFound = false;
if (world.getBlockAt(this.getTargetBlock().getX() + x + 1, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z).isEmpty())
{
block = world.getBlockAt(this.getTargetBlock().getX() + x + 1, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z);
final int oldData = block.getPropertyId();
resetBlock(block, oldData);
airFound = true;
}
if (world.getBlockAt(this.getTargetBlock().getX() + x - 1, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z).isEmpty())
{
block = world.getBlockAt(this.getTargetBlock().getX() + x - 1, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z);
final int oldData = block.getPropertyId();
resetBlock(block, oldData);
airFound = true;
}
if (world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y + 1, this.getTargetBlock().getZ() + z).isEmpty())
{
block = world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y + 1, this.getTargetBlock().getZ() + z);
final int oldData = block.getPropertyId();
resetBlock(block, oldData);
airFound = true;
}
if (world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y - 1, this.getTargetBlock().getZ() + z).isEmpty())
{
block = world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y - 1, this.getTargetBlock().getZ() + z);
final int oldData = block.getPropertyId();
resetBlock(block, oldData);
airFound = true;
}
if (world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z + 1).isEmpty())
{
block = world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z + 1);
final int oldData = block.getPropertyId();
resetBlock(block, oldData);
airFound = true;
}
if (world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z - 1).isEmpty())
{
block = world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z - 1);
final int oldData = block.getPropertyId();
resetBlock(block, oldData);
airFound = true;
}
if (airFound)
{
block = world.getBlockAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z);
final int oldData = block.getPropertyId();
resetBlock(block, oldData);
}
}
}
}
}
@SuppressWarnings("deprecation")
private void resetBlock(AsyncBlock block, final int oldData)
{
block.setTypeIdAndPropertyId(block.getTypeId(), ((block.getPropertyId() + 1) & 0xf), true);
block.setTypeIdAndPropertyId(block.getTypeId(), oldData, true);
}
@Override
protected final void arrow(final SnipeData v)
{
applyBrush(v);
}
@Override
protected final void powder(final SnipeData v)
{
applyBrush(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.blockresetsurface";
}
}

Datei anzeigen

@ -0,0 +1,311 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.RangeBlockHelper;
import com.thevoxelbox.voxelsniper.SnipeAction;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import com.thevoxelbox.voxelsniper.util.BlockWrapper;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
/**
* Abstract implementation of the {@link IBrush} interface.
*/
public abstract class Brush implements IBrush
{
protected static final int CHUNK_SIZE = 16;
/**
* Targeted Block.
*/
private AsyncBlock targetBlock;
/**
* Last Block before targeted Block.
*/
private AsyncBlock lastBlock;
/**
* Brush name.
*/
private String name = "Undefined";
/**
* @param x
* @param y
* @param z
* @return {@link Block}
*/
public final AsyncBlock clampY(final int x, final int y, final int z)
{
int clampedY = y;
if (clampedY < 0)
{
clampedY = 0;
}
else if (clampedY > this.getWorld().getMaxHeight())
{
clampedY = this.getWorld().getMaxHeight();
}
return this.getWorld().getBlockAt(x, clampedY, z);
}
private boolean preparePerform(final SnipeData v, final AsyncBlock clickedBlock, final BlockFace clickedFace)
{
if (this.getTarget(v, clickedBlock, clickedFace))
{
if (this instanceof PerformBrush)
{
((PerformBrush) this).initP(v);
}
return true;
}
return false;
}
@Override
public boolean perform(SnipeAction action, SnipeData data, AsyncBlock targetBlock, AsyncBlock lastBlock)
{
this.setTargetBlock(targetBlock);
this.setLastBlock(lastBlock);
switch (action)
{
case ARROW:
this.arrow(data);
return true;
case GUNPOWDER:
this.powder(data);
return true;
default:
return false;
}
}
/**
* The arrow action. Executed when a player RightClicks with an Arrow
*
* @param v Sniper caller
*/
protected void arrow(final SnipeData v)
{
}
/**
* The powder action. Executed when a player RightClicks with Gunpowder
*
* @param v Sniper caller
*/
protected void powder(final SnipeData v)
{
}
@Override
public abstract void info(Message vm);
@Override
public void parameters(final String[] par, final SnipeData v)
{
v.sendMessage(ChatColor.RED + "This brush does not accept additional parameters.");
}
/**
* Overridable getTarget method.
*
* @param v
* @param clickedBlock
* @param clickedFace
* @return boolean
*/
protected final boolean getTarget(final SnipeData v, final AsyncBlock clickedBlock, final BlockFace clickedFace)
{
if (clickedBlock != null)
{
this.setTargetBlock(clickedBlock);
this.setLastBlock(clickedBlock.getRelative(clickedFace));
if (this.getLastBlock() == null)
{
v.sendMessage(ChatColor.RED + "Snipe target block must be visible.");
return false;
}
if (v.owner().getSnipeData(v.owner().getCurrentToolId()).isLightningEnabled())
{
this.getWorld().strikeLightning(this.getTargetBlock().getLocation());
}
return true;
}
else
{
RangeBlockHelper rangeBlockHelper;
if (v.owner().getSnipeData(v.owner().getCurrentToolId()).isRanged())
{
rangeBlockHelper = new RangeBlockHelper(v.owner().getPlayer(), v.owner().getWorld(), (double) v.owner().getSnipeData(v.owner().getCurrentToolId()).getRange());
this.setTargetBlock(rangeBlockHelper.getRangeBlock());
}
else
{
rangeBlockHelper = new RangeBlockHelper(v.owner().getPlayer(), v.owner().getWorld());
this.setTargetBlock(rangeBlockHelper.getTargetBlock());
}
if (this.getTargetBlock() != null)
{
this.setLastBlock(rangeBlockHelper.getLastBlock());
if (this.getLastBlock() == null)
{
v.sendMessage(ChatColor.RED + "Snipe target block must be visible.");
return false;
}
if (v.owner().getSnipeData(v.owner().getCurrentToolId()).isLightningEnabled())
{
this.getWorld().strikeLightning(this.getTargetBlock().getLocation());
}
return true;
}
else
{
v.sendMessage(ChatColor.RED + "Snipe target block must be visible.");
return false;
}
}
}
@Override
public final String getName()
{
return this.name;
}
@Override
public final void setName(final String name)
{
this.name = name;
}
@Override
public String getBrushCategory()
{
return "General";
}
/**
* @return the targetBlock
*/
protected final AsyncBlock getTargetBlock()
{
return this.targetBlock;
}
/**
* @param targetBlock the targetBlock to set
*/
protected final void setTargetBlock(final AsyncBlock targetBlock)
{
this.targetBlock = targetBlock;
}
/**
* @return the world
*/
protected final AsyncWorld getWorld()
{
return targetBlock.getWorld();
}
/**
* Looks up Type ID of Block at given coordinates in the world of the targeted Block.
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @return Type ID of Block at given coordinates in the world of the targeted Block.
*/
@SuppressWarnings("deprecation")
protected int getBlockIdAt(int x, int y, int z)
{
return getWorld().getBlockAt(x, y, z).getTypeId();
}
protected Block getBlockAt(int x, int y, int z)
{
return getWorld().getBlockAt(x, y, z);
}
protected Material getBlockType(int x, int y, int z)
{
return getWorld().getBlockAt(x, y, z).getType();
}
/**
* Looks up Block Data Value of Block at given coordinates in the world of the targeted Block.
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @return Block Data Value of Block at given coordinates in the world of the targeted Block.
*/
@SuppressWarnings("deprecation")
protected int getBlockDataAt(int x, int y, int z)
{
return this.getWorld().getBlockAt(x, y, z).getPropertyId();
}
/**
* @return Block before target Block.
*/
protected final AsyncBlock getLastBlock()
{
return this.lastBlock;
}
/**
* @param lastBlock Last Block before target Block.
*/
protected final void setLastBlock(AsyncBlock lastBlock)
{
this.lastBlock = lastBlock;
}
/**
* Set block data with supplied data over BlockWrapper.
*
* @param blockWrapper Block data wrapper
*/
@Deprecated
protected final void setBlock(BlockWrapper blockWrapper)
{
this.getWorld().getBlockAt(blockWrapper.getX(), blockWrapper.getY(), blockWrapper.getZ()).setTypeId(blockWrapper.getId());
}
/**
* Sets the Id of the block at the passed coordinate.
*
* @param z Z coordinate
* @param x X coordinate
* @param y Y coordinate
* @param id The id the block will be set to
*/
@SuppressWarnings("deprecation")
protected final void setBlockIdAt(int z, int x, int y, int id)
{
this.getWorld().getBlockAt(x, y, z).setTypeId(id);
}
/**
* Sets the id and data value of the block at the passed coordinate.
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @param id The id the block will be set to
* @param data The data value the block will be set to
*/
@SuppressWarnings("deprecation")
protected final void setBlockIdAndDataAt(int x, int y, int z, int id, int data)
{
this.getWorld().getBlockAt(x, y, z).setTypeIdAndPropertyId(id, data, true);
}
}

Datei anzeigen

@ -0,0 +1,146 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncChunk;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_CANYONATOR
*
* @author Voxel
*/
public class CanyonBrush extends Brush
{
private static final int SHIFT_LEVEL_MIN = 10;
private static final int SHIFT_LEVEL_MAX = 60;
private int yLevel = 10;
/**
*
*/
public CanyonBrush()
{
this.setName("Canyon");
}
/**
* @param chunk
* @param undo
*/
@SuppressWarnings("deprecation")
protected final void canyon(final AsyncChunk chunk, final Undo undo)
{
for (int x = 0; x < CHUNK_SIZE; x++)
{
for (int z = 0; z < CHUNK_SIZE; z++)
{
int currentYLevel = this.yLevel;
for (int y = 63; y < this.getWorld().getMaxHeight(); y++)
{
final AsyncBlock block = chunk.getBlock(x, y, z);
final AsyncBlock currentYLevelBlock = chunk.getBlock(x, currentYLevel, z);
undo.put(block);
undo.put(currentYLevelBlock);
currentYLevelBlock.setTypeId(block.getTypeId());
block.setType(Material.AIR);
currentYLevel++;
}
final AsyncBlock block = chunk.getBlock(x, 0, z);
undo.put(block);
block.setTypeId(BlockTypes.BEDROCK.getInternalId());
for (int y = 1; y < SHIFT_LEVEL_MIN; y++)
{
final Block currentBlock = chunk.getBlock(x, y, z);
undo.put(currentBlock);
currentBlock.setType(Material.STONE);
}
}
}
}
@Override
protected void arrow(final SnipeData v)
{
final Undo undo = new Undo();
canyon(getTargetBlock().getChunk(), undo);
v.owner().storeUndo(undo);
}
@Override
protected void powder(final SnipeData v)
{
final Undo undo = new Undo();
Chunk targetChunk = getTargetBlock().getChunk();
for (int x = targetChunk.getX() - 1; x <= targetChunk.getX() + 1; x++)
{
for (int z = targetChunk.getX() - 1; z <= targetChunk.getX() + 1; z++)
{
canyon(getWorld().getChunkAt(x, z), undo);
}
}
v.owner().storeUndo(undo);
}
@Override
public void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.GREEN + "Shift Level set to " + this.yLevel);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GREEN + "y[number] to set the Level to which the land will be shifted down");
}
if (par[1].startsWith("y"))
{
int _i = Integer.parseInt(par[1].replace("y", ""));
if (_i < SHIFT_LEVEL_MIN)
{
_i = SHIFT_LEVEL_MIN;
}
else if (_i > SHIFT_LEVEL_MAX)
{
_i = SHIFT_LEVEL_MAX;
}
this.yLevel = _i;
v.sendMessage(ChatColor.GREEN + "Shift Level set to " + this.yLevel);
}
}
protected final int getYLevel()
{
return yLevel;
}
protected final void setYLevel(int yLevel)
{
this.yLevel = yLevel;
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.canyon";
}
}

Datei anzeigen

@ -0,0 +1,88 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Canyon_Selection_Brush
*
* @author Voxel
*/
public class CanyonSelectionBrush extends CanyonBrush
{
private boolean first = true;
private int fx;
private int fz;
/**
*
*/
public CanyonSelectionBrush()
{
this.setName("Canyon Selection");
}
private void execute(final SnipeData v)
{
final Chunk chunk = getTargetBlock().getChunk();
if (this.first)
{
this.fx = chunk.getX();
this.fz = chunk.getZ();
v.sendMessage(ChatColor.YELLOW + "First point selected!");
this.first = !this.first;
}
else
{
v.sendMessage(ChatColor.YELLOW + "Second point selected!");
selection(Math.min(fx, chunk.getX()), Math.min(fz, chunk.getZ()), Math.max(fx, chunk.getX()), Math.max(fz, chunk.getZ()), v);
this.first = !this.first;
}
}
private void selection(final int lowX, final int lowZ, final int highX, final int highZ, final SnipeData v)
{
final Undo undo = new Undo();
for (int x = lowX; x <= highX; x++)
{
for (int z = lowZ; z <= highZ; z++)
{
canyon(getWorld().getChunkAt(x, z), undo);
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
execute(v);
}
@Override
protected final void powder(final SnipeData v)
{
execute(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.GREEN + "Shift Level set to " + this.getYLevel());
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.canyonselection";
}
}

Datei anzeigen

@ -0,0 +1,101 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* @author MikeMatrix
*/
public class CheckerVoxelDiscBrush extends PerformBrush
{
private boolean useWorldCoordinates = true;
/**
* Default constructor.
*/
public CheckerVoxelDiscBrush()
{
this.setName("Checker Voxel Disc");
}
/**
* @param v
* @param target
*/
private void applyBrush(final SnipeData v, final Block target)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = v.getBrushSize(); y >= -v.getBrushSize(); y--)
{
final int sum = this.useWorldCoordinates ? target.getX() + x + target.getZ() + y : x + y;
if (sum % 2 != 0)
{
this.current.perform(this.clampY(target.getX() + x, target.getY(), target.getZ() + y));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.applyBrush(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.applyBrush(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int x = 1; x < par.length; x++)
{
final String parameter = par[x].toLowerCase();
if (parameter.equals("info"))
{
v.sendMessage(ChatColor.GOLD + this.getName() + " Parameters:");
v.sendMessage(ChatColor.AQUA + "true -- Enables using World Coordinates.");
v.sendMessage(ChatColor.AQUA + "false -- Disables using World Coordinates.");
return;
}
if (parameter.startsWith("true"))
{
this.useWorldCoordinates = true;
v.sendMessage(ChatColor.AQUA + "Enabled using World Coordinates.");
}
else if (parameter.startsWith("false"))
{
this.useWorldCoordinates = false;
v.sendMessage(ChatColor.AQUA + "Disabled using World Coordinates.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
break;
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.checkervoxeldisc";
}
}

Datei anzeigen

@ -0,0 +1,113 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Clean_Snow_Brush
*
* @author psanker
*/
public class CleanSnowBrush extends Brush
{
private double trueCircle = 0;
/**
*
*/
public CleanSnowBrush()
{
this.setName("Clean Snow");
}
private void cleanSnow(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
final Undo undo = new Undo();
for (int y = (brushSize + 1) * 2; y >= 0; y--)
{
final double ySquared = Math.pow(y - brushSize, 2);
for (int x = (brushSize + 1) * 2; x >= 0; x--)
{
final double xSquared = Math.pow(x - brushSize, 2);
for (int z = (brushSize + 1) * 2; z >= 0; z--)
{
if ((xSquared + Math.pow(z - brushSize, 2) + ySquared) <= brushSizeSquared)
{
if ((this.clampY(this.getTargetBlock().getX() + x - brushSize, this.getTargetBlock().getY() + z - brushSize, this.getTargetBlock().getZ() + y - brushSize).getType() == Material.SNOW) && ((this.clampY(this.getTargetBlock().getX() + x - brushSize, this.getTargetBlock().getY() + z - brushSize - 1, this.getTargetBlock().getZ() + y - brushSize).getType() == Material.SNOW) || (this.clampY(this.getTargetBlock().getX() + x - brushSize, this.getTargetBlock().getY() + z - brushSize - 1, this.getTargetBlock().getZ() + y - brushSize).isEmpty())))
{
undo.put(this.clampY(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + z, this.getTargetBlock().getZ() + y));
this.setBlockIdAt(this.getTargetBlock().getZ() + y - brushSize, this.getTargetBlock().getX() + x - brushSize, this.getTargetBlock().getY() + z - brushSize, 0);
}
}
}
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
this.cleanSnow(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.cleanSnow(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Clean Snow Brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b cls true -- will use a true sphere algorithm instead of the skinnier version with classic sniper nubs. /b cls false will switch back. (false is default)");
return;
}
else if (parameter.startsWith("true"))
{
this.trueCircle = 0.5;
v.sendMessage(ChatColor.AQUA + "True circle mode ON.");
}
else if (parameter.startsWith("false"))
{
this.trueCircle = 0;
v.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.cleansnow";
}
}

Datei anzeigen

@ -0,0 +1,172 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
/**
* The CloneStamp class is used to create a collection of blocks in a cylinder shape according to the selection the player has set.
* http://www.voxelwiki.com/minecraft/Voxelsniper#Clone_and_CopyPasta_Brushes
*
* @author Voxel
*/
public class CloneStampBrush extends StampBrush
{
/**
*
*/
public CloneStampBrush()
{
this.setName("Clone");
}
/**
* The clone method is used to grab a snapshot of the selected area dictated blockPositionY targetBlock.x y z v.brushSize v.voxelHeight and v.cCen.
* <p/>
* x y z -- initial center of the selection v.brushSize -- the radius of the cylinder v.voxelHeight -- the heigth of the cylinder c.cCen -- the offset on
* the Y axis of the selection ( bottom of the cylinder ) as blockPositionY: Bottom_Y = targetBlock.y + v.cCen;
*
* @param v
* the caller
*/
private void clone(final SnipeData v)
{
final int brushSize = v.getBrushSize();
this.clone.clear();
this.fall.clear();
this.drop.clear();
this.solid.clear();
this.sorted = false;
int yStartingPoint = this.getTargetBlock().getY() + v.getcCen();
int yEndPoint = this.getTargetBlock().getY() + v.getVoxelHeight() + v.getcCen();
if (yStartingPoint < 0)
{
yStartingPoint = 0;
v.sendMessage(ChatColor.DARK_PURPLE + "Warning: off-world start position.");
}
else if (yStartingPoint > this.getWorld().getMaxHeight() - 1)
{
yStartingPoint = this.getWorld().getMaxHeight() - 1;
v.sendMessage(ChatColor.DARK_PURPLE + "Warning: off-world start position.");
}
if (yEndPoint < 0)
{
yEndPoint = 0;
v.sendMessage(ChatColor.DARK_PURPLE + "Warning: off-world end position.");
}
else if (yEndPoint > this.getWorld().getMaxHeight() - 1)
{
yEndPoint = this.getWorld().getMaxHeight() - 1;
v.sendMessage(ChatColor.DARK_PURPLE + "Warning: off-world end position.");
}
final double bSquared = Math.pow(brushSize, 2);
for (int z = yStartingPoint; z < yEndPoint; z++)
{
this.clone.add(new BlockWrapper(this.clampY(this.getTargetBlock().getX(), z, this.getTargetBlock().getZ()), 0, z - yStartingPoint, 0));
for (int y = 1; y <= brushSize; y++)
{
this.clone.add(new BlockWrapper(this.clampY(this.getTargetBlock().getX(), z, this.getTargetBlock().getZ() + y), 0, z - yStartingPoint, y));
this.clone.add(new BlockWrapper(this.clampY(this.getTargetBlock().getX(), z, this.getTargetBlock().getZ() - y), 0, z - yStartingPoint, -y));
this.clone.add(new BlockWrapper(this.clampY(this.getTargetBlock().getX() + y, z, this.getTargetBlock().getZ()), y, z - yStartingPoint, 0));
this.clone.add(new BlockWrapper(this.clampY(this.getTargetBlock().getX() - y, z, this.getTargetBlock().getZ()), -y, z - yStartingPoint, 0));
}
for (int x = 1; x <= brushSize; x++)
{
final double xSquared = Math.pow(x, 2);
for (int y = 1; y <= brushSize; y++)
{
if ((xSquared + Math.pow(y, 2)) <= bSquared)
{
this.clone.add(new BlockWrapper(this.clampY(this.getTargetBlock().getX() + x, z, this.getTargetBlock().getZ() + y), x, z - yStartingPoint, y));
this.clone.add(new BlockWrapper(this.clampY(this.getTargetBlock().getX() + x, z, this.getTargetBlock().getZ() - y), x, z - yStartingPoint, -y));
this.clone.add(new BlockWrapper(this.clampY(this.getTargetBlock().getX() - x, z, this.getTargetBlock().getZ() + y), -x, z - yStartingPoint, y));
this.clone.add(new BlockWrapper(this.clampY(this.getTargetBlock().getX() - x, z, this.getTargetBlock().getZ() - y), -x, z - yStartingPoint, -y));
}
}
}
}
v.sendMessage(ChatColor.GREEN + String.valueOf(this.clone.size()) + ChatColor.AQUA + " blocks copied sucessfully.");
}
@Override
protected final void powder(final SnipeData v)
{
this.clone(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.height();
vm.center();
switch (this.stamp)
{
case DEFAULT:
vm.brushMessage("Default Stamp");
break;
case NO_AIR:
vm.brushMessage("No-Air Stamp");
break;
case FILL:
vm.brushMessage("Fill Stamp");
break;
default:
vm.custom(ChatColor.DARK_RED + "Error while stamping! Report");
break;
}
}
@Override
public final void parameters(final String[] par, final com.thevoxelbox.voxelsniper.SnipeData v)
{
final String parameter = par[1];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Clone / Stamp Cylinder brush parameters");
v.sendMessage(ChatColor.GREEN + "cs f -- Activates Fill mode");
v.sendMessage(ChatColor.GREEN + "cs a -- Activates No-Air mode");
v.sendMessage(ChatColor.GREEN + "cs d -- Activates Default mode");
}
if (parameter.equalsIgnoreCase("a"))
{
this.setStamp(StampType.NO_AIR);
this.reSort();
v.sendMessage(ChatColor.AQUA + "No-Air stamp brush");
}
else if (parameter.equalsIgnoreCase("f"))
{
this.setStamp(StampType.FILL);
this.reSort();
v.sendMessage(ChatColor.AQUA + "Fill stamp brush");
}
else if (parameter.equalsIgnoreCase("d"))
{
this.setStamp(StampType.DEFAULT);
this.reSort();
v.sendMessage(ChatColor.AQUA + "Default stamp brush");
}
else if (parameter.startsWith("c"))
{
v.setcCen(Integer.parseInt(parameter.replace("c", "")));
v.sendMessage(ChatColor.BLUE + "Center set to " + v.getcCen());
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.clonestamp";
}
}

Datei anzeigen

@ -0,0 +1,108 @@
package com.thevoxelbox.voxelsniper.brush;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.LargeFireball;
import org.bukkit.entity.SmallFireball;
import org.bukkit.util.Vector;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
/**
* @author Gavjenks Heavily revamped from ruler brush blockPositionY
* @author Giltwist
* @author Monofraps (Merged Meteor brush)
*/
public class CometBrush extends Brush
{
private boolean useBigBalls = false;
/**
*
*/
public CometBrush()
{
this.setName("Comet");
}
private void doFireball(final SnipeData v)
{
final Vector targetCoords = new Vector(this.getTargetBlock().getX() + .5 * this.getTargetBlock().getX() / Math.abs(this.getTargetBlock().getX()), this.getTargetBlock().getY() + .5, this.getTargetBlock().getZ() + .5 * this.getTargetBlock().getZ() / Math.abs(this.getTargetBlock().getZ()));
final Location playerLocation = v.owner().getPlayer().getEyeLocation();
final Vector slope = targetCoords.subtract(playerLocation.toVector());
if (useBigBalls)
{
v.owner().getPlayer().launchProjectile(LargeFireball.class).setVelocity(slope.normalize());
}
else
{
v.owner().getPlayer().launchProjectile(SmallFireball.class).setVelocity(slope.normalize());
}
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 0; i < par.length; ++i)
{
String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage("Parameters:");
v.sendMessage("balls [big|small] -- Sets your ball size.");
}
if (parameter.equalsIgnoreCase("balls"))
{
if (i + 1 >= par.length)
{
v.sendMessage("The balls parameter expects a ball size after it.");
}
String newBallSize = par[++i];
if (newBallSize.equalsIgnoreCase("big"))
{
useBigBalls = true;
v.sendMessage("Your balls are " + ChatColor.DARK_RED + ("BIG"));
}
else if (newBallSize.equalsIgnoreCase("small"))
{
useBigBalls = false;
v.sendMessage("Your balls are " + ChatColor.DARK_RED + ("small"));
}
else
{
v.sendMessage("Unknown ball size.");
}
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.doFireball(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.doFireball(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.voxel();
vm.custom("Your balls are " + ChatColor.DARK_RED + (useBigBalls ? "BIG" : "small"));
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.comet";
}
}

Datei anzeigen

@ -0,0 +1,222 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#CopyPasta_Brush
*
* @author giltwist
*/
public class CopyPastaBrush extends Brush
{
private static final int BLOCK_LIMIT = 10000;
private boolean pasteAir = true; // False = no air, true = air
private int points = 0; //
private int numBlocks = 0;
private int[] firstPoint = new int[3];
private int[] secondPoint = new int[3];
private int[] pastePoint = new int[3];
private int[] minPoint = new int[3];
private int[] offsetPoint = new int[3];
private int[] blockArray;
private int[] arraySize = new int[3];
private int pivot = 0; // ccw degrees
/**
*
*/
public CopyPastaBrush()
{
this.setName("CopyPasta");
}
@SuppressWarnings("deprecation")
private void doCopy(final SnipeData v)
{
for (int i = 0; i < 3; i++)
{
this.arraySize[i] = Math.abs(this.firstPoint[i] - this.secondPoint[i]) + 1;
this.minPoint[i] = Math.min(this.firstPoint[i], this.secondPoint[i]);
this.offsetPoint[i] = this.minPoint[i] - this.firstPoint[i]; // will always be negative or zero
}
this.numBlocks = (this.arraySize[0]) * (this.arraySize[1]) * (this.arraySize[2]);
if (this.numBlocks > 0 && this.numBlocks < CopyPastaBrush.BLOCK_LIMIT)
{
this.blockArray = new int[this.numBlocks];
for (int i = 0; i < this.arraySize[0]; i++)
{
for (int j = 0; j < this.arraySize[1]; j++)
{
for (int k = 0; k < this.arraySize[2]; k++)
{
final int currentPosition = i + this.arraySize[0] * j + this.arraySize[0] * this.arraySize[1] * k;
this.blockArray[currentPosition] = this.getWorld().getBlockAt(this.minPoint[0] + i, this.minPoint[1] + j, this.minPoint[2] + k).getCombinedId();
}
}
}
v.sendMessage(ChatColor.AQUA + "" + this.numBlocks + " blocks copied.");
}
else
{
v.sendMessage(ChatColor.RED + "Copy area too big: " + this.numBlocks + "(Limit: " + CopyPastaBrush.BLOCK_LIMIT + ")");
}
}
@SuppressWarnings("deprecation")
private void doPasta(final SnipeData v)
{
final Undo undo = new Undo();
for (int i = 0; i < this.arraySize[0]; i++)
{
for (int j = 0; j < this.arraySize[1]; j++)
{
for (int k = 0; k < this.arraySize[2]; k++)
{
final int currentPosition = i + this.arraySize[0] * j + this.arraySize[0] * this.arraySize[1] * k;
AsyncBlock block;
switch (this.pivot)
{
case 180:
block = this.clampY(this.pastePoint[0] - this.offsetPoint[0] - i, this.pastePoint[1] + this.offsetPoint[1] + j, this.pastePoint[2] - this.offsetPoint[2] - k);
break;
case 270:
block = this.clampY(this.pastePoint[0] + this.offsetPoint[2] + k, this.pastePoint[1] + this.offsetPoint[1] + j, this.pastePoint[2] - this.offsetPoint[0] - i);
break;
case 90:
block = this.clampY(this.pastePoint[0] - this.offsetPoint[2] - k, this.pastePoint[1] + this.offsetPoint[1] + j, this.pastePoint[2] + this.offsetPoint[0] + i);
break;
default: // assume no rotation
block = this.clampY(this.pastePoint[0] + this.offsetPoint[0] + i, this.pastePoint[1] + this.offsetPoint[1] + j, this.pastePoint[2] + this.offsetPoint[2] + k);
break;
}
if (!(BlockTypes.getFromStateId(this.blockArray[currentPosition]).getMaterial().isAir() && !this.pasteAir))
{
if (block.getCombinedId() != this.blockArray[currentPosition])
{
undo.put(block);
}
block.setCombinedId(this.blockArray[currentPosition]);
}
}
}
}
v.sendMessage(ChatColor.AQUA + "" + this.numBlocks + " blocks pasted.");
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final com.thevoxelbox.voxelsniper.SnipeData v)
{
switch (this.points)
{
case 0:
this.firstPoint[0] = this.getTargetBlock().getX();
this.firstPoint[1] = this.getTargetBlock().getY();
this.firstPoint[2] = this.getTargetBlock().getZ();
v.sendMessage(ChatColor.GRAY + "First point");
this.points = 1;
break;
case 1:
this.secondPoint[0] = this.getTargetBlock().getX();
this.secondPoint[1] = this.getTargetBlock().getY();
this.secondPoint[2] = this.getTargetBlock().getZ();
v.sendMessage(ChatColor.GRAY + "Second point");
this.points = 2;
break;
default:
this.firstPoint = new int[3];
this.secondPoint = new int[3];
this.numBlocks = 0;
this.blockArray = new int[1];
this.points = 0;
v.sendMessage(ChatColor.GRAY + "Points cleared.");
break;
}
}
@Override
protected final void powder(final com.thevoxelbox.voxelsniper.SnipeData v)
{
if (this.points == 2)
{
if (this.numBlocks == 0)
{
this.doCopy(v);
}
else if (this.numBlocks > 0 && this.numBlocks < CopyPastaBrush.BLOCK_LIMIT)
{
this.pastePoint[0] = this.getTargetBlock().getX();
this.pastePoint[1] = this.getTargetBlock().getY();
this.pastePoint[2] = this.getTargetBlock().getZ();
this.doPasta(v);
}
else
{
v.sendMessage(ChatColor.RED + "Error");
}
}
else
{
v.sendMessage(ChatColor.RED + "You must select exactly two points.");
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.GOLD + "Paste air: " + this.pasteAir);
vm.custom(ChatColor.GOLD + "Pivot angle: " + this.pivot);
}
@Override
public final void parameters(final String[] par, final com.thevoxelbox.voxelsniper.SnipeData v)
{
final String parameter = par[1];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "CopyPasta Parameters:");
v.sendMessage(ChatColor.AQUA + "/b cp air -- toggle include (default) or exclude air during paste");
v.sendMessage(ChatColor.AQUA + "/b cp 0|90|180|270 -- toggle rotation (0 default)");
return;
}
if (parameter.equalsIgnoreCase("air"))
{
this.pasteAir = !this.pasteAir;
v.sendMessage(ChatColor.GOLD + "Paste air: " + this.pasteAir);
return;
}
if (parameter.equalsIgnoreCase("90") || parameter.equalsIgnoreCase("180") || parameter.equalsIgnoreCase("270") || parameter.equalsIgnoreCase("0"))
{
this.pivot = Integer.parseInt(parameter);
v.sendMessage(ChatColor.GOLD + "Pivot angle: " + this.pivot);
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.copypasta";
}
}

Datei anzeigen

@ -0,0 +1,146 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* @author Kavutop
*/
public class CylinderBrush extends PerformBrush
{
private double trueCircle = 0;
/**
*
*/
public CylinderBrush()
{
this.setName("Cylinder");
}
private void cylinder(final SnipeData v, Block targetBlock)
{
final int brushSize = v.getBrushSize();
int yStartingPoint = targetBlock.getY() + v.getcCen();
int yEndPoint = targetBlock.getY() + v.getVoxelHeight() + v.getcCen();
if (yEndPoint < yStartingPoint)
{
yEndPoint = yStartingPoint;
}
if (yStartingPoint < 0)
{
yStartingPoint = 0;
v.sendMessage(ChatColor.DARK_PURPLE + "Warning: off-world start position.");
}
else if (yStartingPoint > this.getWorld().getMaxHeight() - 1)
{
yStartingPoint = this.getWorld().getMaxHeight() - 1;
v.sendMessage(ChatColor.DARK_PURPLE + "Warning: off-world start position.");
}
if (yEndPoint < 0)
{
yEndPoint = 0;
v.sendMessage(ChatColor.DARK_PURPLE + "Warning: off-world end position.");
}
else if (yEndPoint > this.getWorld().getMaxHeight() - 1)
{
yEndPoint = this.getWorld().getMaxHeight() - 1;
v.sendMessage(ChatColor.DARK_PURPLE + "Warning: off-world end position.");
}
final double bSquared = Math.pow(brushSize + this.trueCircle, 2);
for (int y = yEndPoint; y >= yStartingPoint; y--)
{
for (int x = brushSize; x >= 0; x--)
{
final double xSquared = Math.pow(x, 2);
for (int z = brushSize; z >= 0; z--)
{
if ((xSquared + Math.pow(z, 2)) <= bSquared)
{
this.current.perform(this.clampY(targetBlock.getX() + x, y, targetBlock.getZ() + z));
this.current.perform(this.clampY(targetBlock.getX() + x, y, targetBlock.getZ() - z));
this.current.perform(this.clampY(targetBlock.getX() - x, y, targetBlock.getZ() + z));
this.current.perform(this.clampY(targetBlock.getX() - x, y, targetBlock.getZ() - z));
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.cylinder(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.cylinder(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.height();
vm.center();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Cylinder Brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b c h[number] -- set the cylinder v.voxelHeight. Default is 1.");
v.sendMessage(ChatColor.DARK_AQUA + "/b c true -- will use a true circle algorithm instead of the skinnier version with classic sniper nubs. /b b false will switch back. (false is default)");
v.sendMessage(ChatColor.DARK_BLUE + "/b c c[number] -- set the origin of the cylinder compared to the target block. Positive numbers will move the cylinder upward, negative will move it downward.");
return;
}
if (parameter.startsWith("true"))
{
this.trueCircle = 0.5;
v.sendMessage(ChatColor.AQUA + "True circle mode ON.");
}
else if (parameter.startsWith("false"))
{
this.trueCircle = 0;
v.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
}
else if (parameter.startsWith("h"))
{
v.setVoxelHeight((int) Double.parseDouble(parameter.replace("h", "")));
v.sendMessage(ChatColor.AQUA + "Cylinder v.voxelHeight set to: " + v.getVoxelHeight());
}
else if (parameter.startsWith("c"))
{
v.setcCen((int) Double.parseDouble(parameter.replace("c", "")));
v.sendMessage(ChatColor.AQUA + "Cylinder origin set to: " + v.getcCen());
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.cylinder";
}
}

Datei anzeigen

@ -0,0 +1,108 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.util.Vector;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Disc_Brush
*
* @author Voxel
*/
public class DiscBrush extends PerformBrush
{
private double trueCircle = 0;
/**
* Default Constructor.
*/
public DiscBrush()
{
this.setName("Disc");
}
/**
* Disc executor.
*
* @param v
*/
private void disc(final SnipeData v, final Block targetBlock)
{
final double radiusSquared = (v.getBrushSize() + this.trueCircle) * (v.getBrushSize() + this.trueCircle);
final Vector centerPoint = targetBlock.getLocation().toVector();
final Vector currentPoint = centerPoint.clone();
for (int x = -v.getBrushSize(); x <= v.getBrushSize(); x++)
{
currentPoint.setX(centerPoint.getX() + x);
for (int z = -v.getBrushSize(); z <= v.getBrushSize(); z++)
{
currentPoint.setZ(centerPoint.getZ() + z);
if (centerPoint.distanceSquared(currentPoint) <= radiusSquared)
{
this.current.perform(this.clampY(currentPoint.getBlockX(), currentPoint.getBlockY(), currentPoint.getBlockZ()));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.disc(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.disc(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i].toLowerCase();
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Disc Brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b d true|false" + " -- toggles useing the true circle algorithm instead of the skinnier version with classic sniper nubs. (false is default)");
return;
}
else if (parameter.startsWith("true"))
{
this.trueCircle = 0.5;
v.sendMessage(ChatColor.AQUA + "True circle mode ON.");
}
else if (parameter.startsWith("false"))
{
this.trueCircle = 0;
v.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.disc";
}
}

Datei anzeigen

@ -0,0 +1,181 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Disc_Face_Brush
*
* @author Voxel
*/
public class DiscFaceBrush extends PerformBrush
{
private double trueCircle = 0;
/**
*
*/
public DiscFaceBrush()
{
this.setName("Disc Face");
}
private void discUD(final SnipeData v, AsyncBlock targetBlock)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
for (int x = brushSize; x >= 0; x--)
{
final double xSquared = Math.pow(x, 2);
for (int z = brushSize; z >= 0; z--)
{
if ((xSquared + Math.pow(z, 2)) <= brushSizeSquared)
{
current.perform(targetBlock.getRelative(x, 0, z));
current.perform(targetBlock.getRelative(x, 0, -z));
current.perform(targetBlock.getRelative(-x, 0, z));
current.perform(targetBlock.getRelative(-x, 0, -z));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
private void discNS(final SnipeData v, AsyncBlock targetBlock)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
for (int x = brushSize; x >= 0; x--)
{
final double xSquared = Math.pow(x, 2);
for (int y = brushSize; y >= 0; y--)
{
if ((xSquared + Math.pow(y, 2)) <= brushSizeSquared)
{
current.perform(targetBlock.getRelative(x, y, 0));
current.perform(targetBlock.getRelative(x, -y, 0));
current.perform(targetBlock.getRelative(-x, y, 0));
current.perform(targetBlock.getRelative(-x, -y, 0));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
private void discEW(final SnipeData v, AsyncBlock targetBlock)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
for (int x = brushSize; x >= 0; x--)
{
final double xSquared = Math.pow(x, 2);
for (int y = brushSize; y >= 0; y--)
{
if ((xSquared + Math.pow(y, 2)) <= brushSizeSquared)
{
current.perform(targetBlock.getRelative(0, x, y));
current.perform(targetBlock.getRelative(0, x, -y));
current.perform(targetBlock.getRelative(0, -x, y));
current.perform(targetBlock.getRelative(0, -x, -y));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
private void pre(final SnipeData v, AsyncBlock targetBlock)
{
BlockFace blockFace = getTargetBlock().getFace(this.getLastBlock());
if (blockFace == null)
{
return;
}
switch (blockFace)
{
case NORTH:
case SOUTH:
this.discNS(v, targetBlock);
break;
case EAST:
case WEST:
this.discEW(v, targetBlock);
break;
case UP:
case DOWN:
this.discUD(v, targetBlock);
break;
default:
break;
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.pre(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.pre(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Disc Face brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b df true -- will use a true circle algorithm instead of the skinnier version with classic sniper nubs. /b b false will switch back. (false is default)");
return;
}
if (parameter.startsWith("true"))
{
this.trueCircle = 0.5;
v.sendMessage(ChatColor.AQUA + "True circle mode ON.");
}
else if (parameter.startsWith("false"))
{
this.trueCircle = 0;
v.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.discface";
}
}

Datei anzeigen

@ -0,0 +1,119 @@
package com.thevoxelbox.voxelsniper.brush;
import java.util.HashSet;
import java.util.Set;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.block.Block;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Dome_Brush
*
* @author Gavjenks
* @author MikeMatrix
*/
public class DomeBrush extends Brush
{
/**
*
*/
public DomeBrush()
{
this.setName("Dome");
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.voxel();
vm.height();
}
/**
* @param v
* @param targetBlock
*/
@SuppressWarnings("deprecation")
private void generateDome(final SnipeData v, final Block targetBlock)
{
if (v.getVoxelHeight() == 0)
{
v.sendMessage("VoxelHeight must not be 0.");
return;
}
final int absoluteHeight = Math.abs(v.getVoxelHeight());
final boolean negative = v.getVoxelHeight() < 0;
final Set<Vector> changeablePositions = new HashSet<Vector>();
final Undo undo = new Undo();
final int brushSizeTimesVoxelHeight = v.getBrushSize() * absoluteHeight;
final double stepScale = ((v.getBrushSize() * v.getBrushSize()) + brushSizeTimesVoxelHeight + brushSizeTimesVoxelHeight) / 5;
final double stepSize = 1 / stepScale;
for (double u = 0; u <= Math.PI / 2; u += stepSize)
{
final double y = absoluteHeight * Math.sin(u);
for (double stepV = -Math.PI; stepV <= -(Math.PI / 2); stepV += stepSize)
{
final double x = v.getBrushSize() * Math.cos(u) * Math.cos(stepV);
final double z = v.getBrushSize() * Math.cos(u) * Math.sin(stepV);
final double targetBlockX = targetBlock.getX() + 0.5;
final double targetBlockZ = targetBlock.getZ() + 0.5;
final int targetY = NumberConversions.floor(targetBlock.getY() + (negative ? -y : y));
final int currentBlockXAdd = NumberConversions.floor(targetBlockX + x);
final int currentBlockZAdd = NumberConversions.floor(targetBlockZ + z);
final int currentBlockXSubtract = NumberConversions.floor(targetBlockX - x);
final int currentBlockZSubtract = NumberConversions.floor(targetBlockZ - z);
changeablePositions.add(new Vector(currentBlockXAdd, targetY, currentBlockZAdd));
changeablePositions.add(new Vector(currentBlockXSubtract, targetY, currentBlockZAdd));
changeablePositions.add(new Vector(currentBlockXAdd, targetY, currentBlockZSubtract));
changeablePositions.add(new Vector(currentBlockXSubtract, targetY, currentBlockZSubtract));
}
}
for (final Vector vector : changeablePositions)
{
final AsyncBlock currentTargetBlock = (AsyncBlock) vector.toLocation(this.getTargetBlock().getWorld()).getBlock();
if (currentTargetBlock.getTypeId() != v.getVoxelId() || currentTargetBlock.getPropertyId() != v.getPropertyId())
{
undo.put(currentTargetBlock);
currentTargetBlock.setTypeIdAndPropertyId(v.getVoxelId(), v.getPropertyId(), true);
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
this.generateDome(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.generateDome(v, this.getLastBlock());
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.dome";
}
}

Datei anzeigen

@ -0,0 +1,173 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Drain_Brush
*
* @author Gavjenks
* @author psanker
*/
public class DrainBrush extends Brush
{
private double trueCircle = 0;
private boolean disc = false;
/**
*
*/
public DrainBrush()
{
this.setName("Drain");
}
@SuppressWarnings("deprecation")
private void drain(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
final Undo undo = new Undo();
if (this.disc)
{
for (int x = brushSize; x >= 0; x--)
{
final double xSquared = Math.pow(x, 2);
for (int y = brushSize; y >= 0; y--)
{
if ((xSquared + Math.pow(y, 2)) <= brushSizeSquared)
{
if (this.getBlockIdAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() + y) == BlockTypes.WATER.getInternalId() || this.getBlockIdAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() + y) == BlockTypes.LAVA.getInternalId())
{
undo.put(this.clampY(this.getTargetBlock().getX() + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() + y));
this.setBlockIdAt(this.getTargetBlock().getZ() + y, this.getTargetBlock().getX() + x, this.getTargetBlock().getY(), BlockTypes.AIR.getInternalId());
}
if (this.getBlockIdAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - y) == BlockTypes.WATER.getInternalId() || this.getBlockIdAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - y) == BlockTypes.LAVA.getInternalId())
{
undo.put(this.clampY(this.getTargetBlock().getX() + x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - y));
this.setBlockIdAt(this.getTargetBlock().getZ() - y, this.getTargetBlock().getX() + x, this.getTargetBlock().getY(), BlockTypes.AIR.getInternalId());
}
if (this.getBlockIdAt(this.getTargetBlock().getX() - x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() + y) == BlockTypes.WATER.getInternalId() || this.getBlockIdAt(this.getTargetBlock().getX() - x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() + y) == BlockTypes.LAVA.getInternalId())
{
undo.put(this.clampY(this.getTargetBlock().getX() - x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() + y));
this.setBlockIdAt(this.getTargetBlock().getZ() + y, this.getTargetBlock().getX() - x, this.getTargetBlock().getY(), BlockTypes.AIR.getInternalId());
}
if (this.getBlockIdAt(this.getTargetBlock().getX() - x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - y) == BlockTypes.WATER.getInternalId() || this.getBlockIdAt(this.getTargetBlock().getX() - x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - y) == BlockTypes.LAVA.getInternalId())
{
undo.put(this.clampY(this.getTargetBlock().getX() - x, this.getTargetBlock().getY(), this.getTargetBlock().getZ() - y));
this.setBlockIdAt(this.getTargetBlock().getZ() - y, this.getTargetBlock().getX() - x, this.getTargetBlock().getY(), BlockTypes.AIR.getInternalId());
}
}
}
}
}
else
{
for (int y = (brushSize + 1) * 2; y >= 0; y--)
{
final double ySquared = Math.pow(y - brushSize, 2);
for (int x = (brushSize + 1) * 2; x >= 0; x--)
{
final double xSquared = Math.pow(x - brushSize, 2);
for (int z = (brushSize + 1) * 2; z >= 0; z--)
{
if ((xSquared + Math.pow(z - brushSize, 2) + ySquared) <= brushSizeSquared)
{
if (this.getBlockIdAt(this.getTargetBlock().getX() + x - brushSize, this.getTargetBlock().getY() + z - brushSize, this.getTargetBlock().getZ() + y - brushSize) == BlockTypes.WATER.getInternalId() || this.getBlockIdAt(this.getTargetBlock().getX() + x - brushSize, this.getTargetBlock().getY() + z - brushSize, this.getTargetBlock().getZ() + y - brushSize) == BlockTypes.LAVA.getInternalId())
{
undo.put(this.clampY(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + z, this.getTargetBlock().getZ() + y));
this.setBlockIdAt(this.getTargetBlock().getZ() + y - brushSize, this.getTargetBlock().getX() + x - brushSize, this.getTargetBlock().getY() + z - brushSize, BlockTypes.AIR.getInternalId());
}
}
}
}
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
this.drain(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.drain(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.custom(ChatColor.AQUA + ((this.trueCircle == 0.5) ? "True circle mode ON" : "True circle mode OFF"));
vm.custom(ChatColor.AQUA + ((this.disc) ? "Disc drain mode ON" : "Disc drain mode OFF"));
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Drain Brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b drain true -- will use a true sphere algorithm instead of the skinnier version with classic sniper nubs. /b drain false will switch back. (false is default)");
v.sendMessage(ChatColor.AQUA + "/b drain d -- toggles disc drain mode, as opposed to a ball drain mode");
return;
}
else if (parameter.startsWith("true"))
{
this.trueCircle = 0.5;
v.sendMessage(ChatColor.AQUA + "True circle mode ON.");
}
else if (parameter.startsWith("false"))
{
this.trueCircle = 0;
v.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
}
else if (parameter.equalsIgnoreCase("d"))
{
if (this.disc)
{
this.disc = false;
v.sendMessage(ChatColor.AQUA + "Disc drain mode OFF");
}
else
{
this.disc = true;
v.sendMessage(ChatColor.AQUA + "Disc drain mode ON");
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.drain";
}
}

Datei anzeigen

@ -0,0 +1,304 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Ellipse_Brush
*
* @author psanker
*/
public class EllipseBrush extends PerformBrush
{
private static final double TWO_PI = (2 * Math.PI);
private static final int SCL_MIN = 1;
private static final int SCL_MAX = 9999;
private static final int SCL_DEFAULT = 10;
private static final int STEPS_MIN = 1;
private static final int STEPS_MAX = 2000;
private static final int STEPS_DEFAULT = 200;
private int xscl;
private int yscl;
private int steps;
private double stepSize;
private boolean fill;
/**
*
*/
public EllipseBrush()
{
this.setName("Ellipse");
}
private void ellipse(final SnipeData v, AsyncBlock targetBlock)
{
try
{
for (double steps = 0; (steps <= TWO_PI); steps += stepSize)
{
final int x = (int) Math.round(this.xscl * Math.cos(steps));
final int y = (int) Math.round(this.yscl * Math.sin(steps));
switch (getTargetBlock().getFace(this.getLastBlock()))
{
case NORTH:
case SOUTH:
current.perform(targetBlock.getRelative(0, x, y));
break;
case EAST:
case WEST:
current.perform(targetBlock.getRelative(x, y, 0));
break;
case UP:
case DOWN:
current.perform(targetBlock.getRelative(x, 0, y));
default:
break;
}
if (steps >= TWO_PI)
{
break;
}
}
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Invalid target.");
}
v.owner().storeUndo(this.current.getUndo());
}
private void ellipsefill(final SnipeData v, AsyncBlock targetBlock)
{
int ix = this.xscl;
int iy = this.yscl;
current.perform(targetBlock);
try
{
if (ix >= iy)
{ // Need this unless you want weird holes
for (iy = this.yscl; iy > 0; iy--)
{
for (double steps = 0; (steps <= TWO_PI); steps += stepSize)
{
final int x = (int) Math.round(ix * Math.cos(steps));
final int y = (int) Math.round(iy * Math.sin(steps));
switch (getTargetBlock().getFace(this.getLastBlock()))
{
case NORTH:
case SOUTH:
current.perform(targetBlock.getRelative(0, x, y));
break;
case EAST:
case WEST:
current.perform(targetBlock.getRelative(x, y, 0));
break;
case UP:
case DOWN:
current.perform(targetBlock.getRelative(x, 0, y));
default:
break;
}
if (steps >= TWO_PI)
{
break;
}
}
ix--;
}
}
else
{
for (ix = this.xscl; ix > 0; ix--)
{
for (double steps = 0; (steps <= TWO_PI); steps += stepSize)
{
final int x = (int) Math.round(ix * Math.cos(steps));
final int y = (int) Math.round(iy * Math.sin(steps));
switch (getTargetBlock().getFace(this.getLastBlock()))
{
case NORTH:
case SOUTH:
current.perform(targetBlock.getRelative(0, x, y));
break;
case EAST:
case WEST:
current.perform(targetBlock.getRelative(x, y, 0));
break;
case UP:
case DOWN:
current.perform(targetBlock.getRelative(x, 0, y));
default:
break;
}
if (steps >= TWO_PI)
{
break;
}
}
iy--;
}
}
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Invalid target.");
}
v.owner().storeUndo(this.current.getUndo());
}
private void execute(final SnipeData v, AsyncBlock targetBlock)
{
this.stepSize = (TWO_PI / this.steps);
if (this.fill)
{
this.ellipsefill(v, targetBlock);
}
else
{
this.ellipse(v, targetBlock);
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.execute(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.execute(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
if (this.xscl < SCL_MIN || this.xscl > SCL_MAX)
{
this.xscl = SCL_DEFAULT;
}
if (this.yscl < SCL_MIN || this.yscl > SCL_MAX)
{
this.yscl = SCL_DEFAULT;
}
if (this.steps < STEPS_MIN || this.steps > STEPS_MAX)
{
this.steps = STEPS_DEFAULT;
}
vm.brushName(this.getName());
vm.custom(ChatColor.AQUA + "X-size set to: " + ChatColor.DARK_AQUA + this.xscl);
vm.custom(ChatColor.AQUA + "Y-size set to: " + ChatColor.DARK_AQUA + this.yscl);
vm.custom(ChatColor.AQUA + "Render step number set to: " + ChatColor.DARK_AQUA + this.steps);
if (this.fill)
{
vm.custom(ChatColor.AQUA + "Fill mode is enabled");
}
else
{
vm.custom(ChatColor.AQUA + "Fill mode is disabled");
}
}
@Override
public final void parameters(final String[] par, final com.thevoxelbox.voxelsniper.SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
try
{
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Ellipse brush parameters");
v.sendMessage(ChatColor.AQUA + "x[n]: Set X size modifier to n");
v.sendMessage(ChatColor.AQUA + "y[n]: Set Y size modifier to n");
v.sendMessage(ChatColor.AQUA + "t[n]: Set the amount of time steps");
v.sendMessage(ChatColor.AQUA + "fill: Toggles fill mode");
return;
}
else if (parameter.startsWith("x"))
{
int tempXScale = Integer.parseInt(par[i].replace("x", ""));
if (tempXScale < SCL_MIN || tempXScale > SCL_MAX)
{
v.sendMessage(ChatColor.AQUA + "Invalid X scale (" + SCL_MIN + "-" + SCL_MAX + ")");
continue;
}
this.xscl = tempXScale;
v.sendMessage(ChatColor.AQUA + "X-scale modifier set to: " + this.xscl);
}
else if (parameter.startsWith("y"))
{
int tempYScale = Integer.parseInt(par[i].replace("y", ""));
if (tempYScale < SCL_MIN || tempYScale > SCL_MAX)
{
v.sendMessage(ChatColor.AQUA + "Invalid Y scale (" + SCL_MIN + "-" + SCL_MAX + ")");
continue;
}
this.yscl = tempYScale;
v.sendMessage(ChatColor.AQUA + "Y-scale modifier set to: " + this.yscl);
}
else if (parameter.startsWith("t"))
{
int tempSteps = Integer.parseInt(par[i].replace("t", ""));
if (tempSteps < STEPS_MIN || tempSteps > STEPS_MAX)
{
v.sendMessage(ChatColor.AQUA + "Invalid step number (" + STEPS_MIN + "-" + STEPS_MAX + ")");
continue;
}
this.steps = tempSteps;
v.sendMessage(ChatColor.AQUA + "Render step number set to: " + this.steps);
}
else if (parameter.equalsIgnoreCase("fill"))
{
if (this.fill)
{
this.fill = false;
v.sendMessage(ChatColor.AQUA + "Fill mode is disabled");
}
else
{
this.fill = true;
v.sendMessage(ChatColor.AQUA + "Fill mode is enabled");
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! Use the \"info\" parameter to display parameter info.");
}
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Incorrect parameter \"" + parameter + "\"; use the \"info\" parameter.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.ellipse";
}
}

Datei anzeigen

@ -0,0 +1,147 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Ellipsoid_Brush
*
*/
public class EllipsoidBrush extends PerformBrush
{
private double xRad;
private double yRad;
private double zRad;
private boolean istrue;
/**
*
*/
public EllipsoidBrush()
{
this.setName("Ellipsoid");
}
private void execute(final SnipeData v, AsyncBlock targetBlock)
{
this.current.perform(targetBlock);
double istrueoffset = istrue ? 0.5 : 0;
int blockPositionX = targetBlock.getX();
int blockPositionY = targetBlock.getY();
int blockPositionZ = targetBlock.getZ();
for (double x = 0; x <= xRad; x++)
{
final double xSquared = (x / (xRad + istrueoffset)) * (x / (xRad + istrueoffset));
for (double z = 0; z <= zRad; z++)
{
final double zSquared = (z / (zRad + istrueoffset)) * (z / (zRad + istrueoffset));
for (double y = 0; y <= yRad; y++)
{
final double ySquared = (y / (yRad + istrueoffset)) * (y / (yRad + istrueoffset));
if (xSquared + ySquared + zSquared <= 1)
{
this.current.perform(this.clampY((int) (blockPositionX + x), (int) (blockPositionY + y), (int) (blockPositionZ + z)));
this.current.perform(this.clampY((int) (blockPositionX + x), (int) (blockPositionY + y), (int) (blockPositionZ - z)));
this.current.perform(this.clampY((int) (blockPositionX + x), (int) (blockPositionY - y), (int) (blockPositionZ + z)));
this.current.perform(this.clampY((int) (blockPositionX + x), (int) (blockPositionY - y), (int) (blockPositionZ - z)));
this.current.perform(this.clampY((int) (blockPositionX - x), (int) (blockPositionY + y), (int) (blockPositionZ + z)));
this.current.perform(this.clampY((int) (blockPositionX - x), (int) (blockPositionY + y), (int) (blockPositionZ - z)));
this.current.perform(this.clampY((int) (blockPositionX - x), (int) (blockPositionY - y), (int) (blockPositionZ + z)));
this.current.perform(this.clampY((int) (blockPositionX - x), (int) (blockPositionY - y), (int) (blockPositionZ - z)));
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.execute(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.execute(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.AQUA + "X-size set to: " + ChatColor.DARK_AQUA + this.xRad);
vm.custom(ChatColor.AQUA + "Y-size set to: " + ChatColor.DARK_AQUA + this.yRad);
vm.custom(ChatColor.AQUA + "Z-size set to: " + ChatColor.DARK_AQUA + this.zRad);
}
@Override
public final void parameters(final String[] par, final com.thevoxelbox.voxelsniper.SnipeData v)
{
this.istrue = false;
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
try
{
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Ellipse brush parameters");
v.sendMessage(ChatColor.AQUA + "x[n]: Set X radius to n");
v.sendMessage(ChatColor.AQUA + "y[n]: Set Y radius to n");
v.sendMessage(ChatColor.AQUA + "z[n]: Set Z radius to n");
return;
}
else if (parameter.startsWith("x"))
{
this.xRad = Integer.parseInt(par[i].replace("x", ""));
v.sendMessage(ChatColor.AQUA + "X radius set to: " + this.xRad);
}
else if (parameter.startsWith("y"))
{
this.yRad = Integer.parseInt(par[i].replace("y", ""));
v.sendMessage(ChatColor.AQUA + "Y radius set to: " + this.yRad);
}
else if (parameter.startsWith("z"))
{
this.zRad = Integer.parseInt(par[i].replace("z", ""));
v.sendMessage(ChatColor.AQUA + "Z radius set to: " + this.zRad);
}
else if (parameter.equalsIgnoreCase("true"))
{
this.istrue = true;
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! Use the \"info\" parameter to display parameter info.");
}
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Incorrect parameter \"" + parameter + "\"; use the \"info\" parameter.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.ellipsoid";
}
}

Datei anzeigen

@ -0,0 +1,98 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
import org.bukkit.entity.EntityType;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Entity_Brush
*
* @author Piotr
*/
public class EntityBrush extends Brush
{
private EntityType entityType = EntityType.ZOMBIE;
/**
*
*/
public EntityBrush()
{
this.setName("Entity");
}
private void spawn(final SnipeData v)
{
for (int x = 0; x < v.getBrushSize(); x++)
{
try
{
this.getWorld().spawn(this.getLastBlock().getLocation(), this.entityType.getEntityClass());
}
catch (final IllegalArgumentException exception)
{
v.sendMessage(ChatColor.RED + "Cannot spawn entity!");
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.spawn(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.spawn(v);
}
@SuppressWarnings("deprecation")
@Override
public final void info(final Message vm)
{
vm.brushMessage(ChatColor.LIGHT_PURPLE + "Entity brush" + " (" + this.entityType.getName() + ")");
vm.size();
}
@SuppressWarnings("deprecation")
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
String names = "";
v.sendMessage(ChatColor.BLUE + "The available entity types are as follows:");
for (final EntityType currentEntity : EntityType.values())
{
names += ChatColor.AQUA + " | " + ChatColor.DARK_GREEN + currentEntity.getName();
}
names += ChatColor.AQUA + " |";
v.sendMessage(names);
}
else
{
final EntityType currentEntity = EntityType.fromName(par[1]);
if (currentEntity != null)
{
this.entityType = currentEntity;
v.sendMessage(ChatColor.GREEN + "Entity type set to " + this.entityType.getName());
}
else
{
v.sendMessage(ChatColor.RED + "This is not a valid entity!");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.entity";
}
}

Datei anzeigen

@ -0,0 +1,187 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.entity.Entity;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.PatternSyntaxException;
/**
*
*/
public class EntityRemovalBrush extends Brush
{
private final List<String> exemptions = new ArrayList<String>(3);
/**
*
*/
public EntityRemovalBrush()
{
this.setName("Entity Removal");
exemptions.add("org.bukkit.entity.Player");
exemptions.add("org.bukkit.entity.Hanging");
exemptions.add("org.bukkit.entity.NPC");
}
private void radialRemoval(SnipeData v)
{
final Chunk targetChunk = getTargetBlock().getChunk();
int entityCount = 0;
int chunkCount = 0;
try
{
entityCount += removeEntities(targetChunk);
int radius = Math.round(v.getBrushSize() / 16);
for (int x = targetChunk.getX() - radius; x <= targetChunk.getX() + radius; x++)
{
for (int z = targetChunk.getZ() - radius; z <= targetChunk.getZ() + radius; z++)
{
entityCount += removeEntities(getWorld().getChunkAt(x, z));
chunkCount++;
}
}
}
catch (final PatternSyntaxException pse)
{
pse.printStackTrace();
v.sendMessage(ChatColor.RED + "Error in RegEx: " + ChatColor.LIGHT_PURPLE + pse.getPattern());
v.sendMessage(ChatColor.RED + String.format("%s (Index: %d)", pse.getDescription(), pse.getIndex()));
}
v.sendMessage(ChatColor.GREEN + "Removed " + ChatColor.RED + entityCount + ChatColor.GREEN + " entities out of " + ChatColor.BLUE + chunkCount + ChatColor.GREEN + (chunkCount == 1 ? " chunk." : " chunks."));
}
private int removeEntities(Chunk chunk) throws PatternSyntaxException
{
int entityCount = 0;
for (Entity entity : chunk.getEntities())
{
if (isClassInExemptionList(entity.getClass()))
{
continue;
}
entity.remove();
entityCount++;
}
return entityCount;
}
private boolean isClassInExemptionList(Class<? extends Entity> entityClass) throws PatternSyntaxException
{
// Create a list of superclasses and interfaces implemented by the current entity type
final List<String> entityClassHierarchy = new ArrayList<String>();
Class<?> currentClass = entityClass;
while (currentClass != null && !currentClass.equals(Object.class))
{
entityClassHierarchy.add(currentClass.getCanonicalName());
for (final Class<?> intrf : currentClass.getInterfaces())
{
entityClassHierarchy.add(intrf.getCanonicalName());
}
currentClass = currentClass.getSuperclass();
}
for (final String exemptionPattern : exemptions)
{
for (final String typeName : entityClassHierarchy)
{
if (typeName.matches(exemptionPattern))
{
return true;
}
}
}
return false;
}
@Override
protected void arrow(SnipeData v)
{
this.radialRemoval(v);
}
@Override
protected void powder(SnipeData v)
{
this.radialRemoval(v);
}
@Override
public void info(Message vm)
{
vm.brushName(getName());
final StringBuilder exemptionsList = new StringBuilder(ChatColor.GREEN + "Exemptions: " + ChatColor.LIGHT_PURPLE);
for (Iterator it = exemptions.iterator(); it.hasNext(); )
{
exemptionsList.append(it.next());
if (it.hasNext())
{
exemptionsList.append(", ");
}
}
vm.custom(exemptionsList.toString());
vm.size();
}
@Override
public void parameters(final String[] par, final SnipeData v)
{
for (final String currentParam : par)
{
if (currentParam.startsWith("+") || currentParam.startsWith("-"))
{
final boolean isAddOperation = currentParam.startsWith("+");
// +#/-# will suppress auto-prefixing
final String exemptionPattern = currentParam.startsWith("+#") || currentParam.startsWith("-#") ?
currentParam.substring(2) :
(currentParam.contains(".") ? currentParam.substring(1) : ".*." + currentParam.substring(1));
if (isAddOperation)
{
exemptions.add(exemptionPattern);
v.sendMessage(String.format("Added %s to entity exemptions list.", exemptionPattern));
}
else
{
exemptions.remove(exemptionPattern);
v.sendMessage(String.format("Removed %s from entity exemptions list.", exemptionPattern));
}
}
if (currentParam.equalsIgnoreCase("list-exemptions") || currentParam.equalsIgnoreCase("lex"))
{
for (final String exemption : exemptions)
{
v.sendMessage(ChatColor.LIGHT_PURPLE + exemption);
}
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.entityremoval";
}
}

Datei anzeigen

@ -0,0 +1,88 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import java.util.EnumSet;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Eraser_Brush
*
* @author Voxel
*/
public class EraserBrush extends Brush
{
private static final Set<Material> EXCLUSIVE_MATERIALS = EnumSet.of(
Material.AIR, Material.STONE, Material.GRASS, Material.DIRT, Material.SAND, Material.GRAVEL, Material.SANDSTONE);
private static final Set<Material> EXCLUSIVE_LIQUIDS = EnumSet.of(
Material.WATER, Material.WATER, Material.LAVA, Material.LAVA);
/**
*
*/
public EraserBrush()
{
this.setName("Eraser");
}
private void doErase(final SnipeData v, final boolean keepWater)
{
final int brushSize = v.getBrushSize();
final int brushSizeDoubled = 2 * brushSize;
World world = this.getTargetBlock().getWorld();
final Undo undo = new Undo();
for (int x = brushSizeDoubled; x >= 0; x--)
{
int currentX = this.getTargetBlock().getX() - brushSize + x;
for (int y = 0; y <= brushSizeDoubled; y++)
{
int currentY = this.getTargetBlock().getY() - brushSize + y;
for (int z = brushSizeDoubled; z >= 0; z--)
{
int currentZ = this.getTargetBlock().getZ() - brushSize + z;
Block currentBlock = world.getBlockAt(currentX, currentY, currentZ);
if (EXCLUSIVE_MATERIALS.contains(currentBlock.getType())
|| (keepWater && EXCLUSIVE_LIQUIDS.contains(currentBlock.getType())))
{
continue;
}
undo.put(currentBlock);
currentBlock.setType(Material.AIR);
}
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
this.doErase(v, false);
}
@Override
protected final void powder(final SnipeData v)
{
this.doErase(v, true);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.eraser";
}
}

Datei anzeigen

@ -0,0 +1,570 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.google.common.base.Objects;
import com.martiansoftware.jsap.FlaggedOption;
import com.martiansoftware.jsap.JSAPException;
import com.martiansoftware.jsap.JSAPResult;
import com.martiansoftware.jsap.UnflaggedOption;
import com.martiansoftware.jsap.stringparsers.EnumeratedStringParser;
import com.massivecraft.factions.P;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import com.thevoxelbox.voxelsniper.jsap.HelpJSAP;
import com.thevoxelbox.voxelsniper.jsap.NullableIntegerStringParser;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.ChatPaginator;
import org.bukkit.util.Vector;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* http://www.voxelwiki.com/minecraft/VoxelSniper#The_Erosion_Brush
*
* @author Piotr
* @author MikeMatrix
*/
public class ErodeBrush extends Brush
{
private static final Vector[] FACES_TO_CHECK = {new Vector(0, 0, 1), new Vector(0, 0, -1), new Vector(0, 1, 0), new Vector(0, -1, 0), new Vector(1, 0, 0), new Vector(-1, 0, 0)};
private final HelpJSAP parser = new HelpJSAP("/b e", "Brush for eroding landscape.", ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH);
private ErosionPreset currentPreset = new ErosionPreset(0, 1, 0, 1);
/**
*
*/
public ErodeBrush()
{
this.setName("Erode");
try
{
this.parser.registerParameter(new UnflaggedOption("preset", EnumeratedStringParser.getParser(Preset.getValuesString(";"), false), null, false, false, "Preset options: " + Preset.getValuesString(", ")));
this.parser.registerParameter(new FlaggedOption("fill", NullableIntegerStringParser.getParser(), null, false, 'f', "fill", "Surrounding blocks required to fill the block."));
this.parser.registerParameter(new FlaggedOption("erode", NullableIntegerStringParser.getParser(), null, false, 'e', "erode", "Surrounding air required to erode the block."));
this.parser.registerParameter(new FlaggedOption("fillrecursion", NullableIntegerStringParser.getParser(), null, false, 'F', "fillrecursion", "Repeated fill iterations."));
this.parser.registerParameter(new FlaggedOption("eroderecursion", NullableIntegerStringParser.getParser(), null, false, 'E', "eroderecursion", "Repeated erode iterations."));
}
catch (JSAPException ignored)
{
}
}
/**
* @param result
* @param player
* @param helpJSAP
* @return if a message was sent.
*/
public static boolean sendHelpOrErrorMessageToPlayer(final JSAPResult result, final Player player, final HelpJSAP helpJSAP)
{
final List<String> output = helpJSAP.writeHelpOrErrorMessageIfRequired(result);
if (!output.isEmpty())
{
for (final String string : output)
{
player.sendMessage(string);
}
return true;
}
return false;
}
@Override
protected final void arrow(final SnipeData v)
{
this.erosion(v, this.currentPreset);
}
@SuppressWarnings("deprecation")
private void erosion(final SnipeData v, final ErosionPreset erosionPreset)
{
final BlockChangeTracker blockChangeTracker = new BlockChangeTracker(this.getTargetBlock().getWorld());
final Vector targetBlockVector = this.getTargetBlock().getLocation().toVector();
for (int i = 0; i < erosionPreset.getErosionRecursion(); ++i)
{
erosionIteration(v, erosionPreset, blockChangeTracker, targetBlockVector);
}
for (int i = 0; i < erosionPreset.getFillRecursion(); ++i)
{
fillIteration(v, erosionPreset, blockChangeTracker, targetBlockVector);
}
final Undo undo = new Undo();
for (final BlockWrapper blockWrapper : blockChangeTracker.getAll())
{
undo.put(blockWrapper.getBlock());
blockWrapper.getBlock().setTypeIdAndPropertyId(blockWrapper.getMaterial().getId(), blockWrapper.getPropertyId(), true);
}
v.owner().storeUndo(undo);
}
private void fillIteration(final SnipeData v, final ErosionPreset erosionPreset, final BlockChangeTracker blockChangeTracker, final Vector targetBlockVector)
{
final int currentIteration = blockChangeTracker.nextIteration();
for (int x = this.getTargetBlock().getX() - v.getBrushSize(); x <= this.getTargetBlock().getX() + v.getBrushSize(); ++x)
{
for (int z = this.getTargetBlock().getZ() - v.getBrushSize(); z <= this.getTargetBlock().getZ() + v.getBrushSize(); ++z)
{
for (int y = this.getTargetBlock().getY() - v.getBrushSize(); y <= this.getTargetBlock().getY() + v.getBrushSize(); ++y)
{
final Vector currentPosition = new Vector(x, y, z);
if (currentPosition.isInSphere(targetBlockVector, v.getBrushSize()))
{
final BlockWrapper currentBlock = blockChangeTracker.get(currentPosition, currentIteration);
if (!(currentBlock.isEmpty() || currentBlock.isLiquid()))
{
continue;
}
int count = 0;
final Map<BlockWrapper, Integer> blockCount = new HashMap<BlockWrapper, Integer>();
for (final Vector vector : ErodeBrush.FACES_TO_CHECK)
{
final Vector relativePosition = currentPosition.clone().add(vector);
final BlockWrapper relativeBlock = blockChangeTracker.get(relativePosition, currentIteration);
if (!(relativeBlock.isEmpty() || relativeBlock.isLiquid()))
{
count++;
final BlockWrapper typeBlock = new BlockWrapper(null, relativeBlock.getMaterial(), relativeBlock.getPropertyId());
if (blockCount.containsKey(typeBlock))
{
blockCount.put(typeBlock, blockCount.get(typeBlock) + 1);
}
else
{
blockCount.put(typeBlock, 1);
}
}
}
BlockWrapper currentMaterial = new BlockWrapper(null, Material.AIR, 0);
int amount = 0;
for (final BlockWrapper wrapper : blockCount.keySet())
{
final Integer currentCount = blockCount.get(wrapper);
if (amount <= currentCount)
{
currentMaterial = wrapper;
amount = currentCount;
}
}
if (count >= erosionPreset.getFillFaces())
{
blockChangeTracker.put(currentPosition, new BlockWrapper(currentBlock.getBlock(), currentMaterial.getMaterial(), currentMaterial.getPropertyId()), currentIteration);
}
}
}
}
}
}
private void erosionIteration(final SnipeData v, final ErosionPreset erosionPreset, final BlockChangeTracker blockChangeTracker, final Vector targetBlockVector)
{
final int currentIteration = blockChangeTracker.nextIteration();
for (int x = this.getTargetBlock().getX() - v.getBrushSize(); x <= this.getTargetBlock().getX() + v.getBrushSize(); ++x)
{
for (int z = this.getTargetBlock().getZ() - v.getBrushSize(); z <= this.getTargetBlock().getZ() + v.getBrushSize(); ++z)
{
for (int y = this.getTargetBlock().getY() - v.getBrushSize(); y <= this.getTargetBlock().getY() + v.getBrushSize(); ++y)
{
final Vector currentPosition = new Vector(x, y, z);
if (currentPosition.isInSphere(targetBlockVector, v.getBrushSize()))
{
final BlockWrapper currentBlock = blockChangeTracker.get(currentPosition, currentIteration);
if (currentBlock.isEmpty() || currentBlock.isLiquid())
{
continue;
}
int count = 0;
for (final Vector vector : ErodeBrush.FACES_TO_CHECK)
{
final Vector relativePosition = currentPosition.clone().add(vector);
final BlockWrapper relativeBlock = blockChangeTracker.get(relativePosition, currentIteration);
if (relativeBlock.isEmpty() || relativeBlock.isLiquid())
{
count++;
}
}
if (count >= erosionPreset.getErosionFaces())
{
blockChangeTracker.put(currentPosition, new BlockWrapper(currentBlock.getBlock(), Material.AIR, 0), currentIteration);
}
}
}
}
}
}
@Override
protected final void powder(final SnipeData v)
{
this.erosion(v, this.currentPreset.getInverted());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.custom(ChatColor.AQUA + "Erosion minimum exposed faces set to " + this.currentPreset.getErosionFaces());
vm.custom(ChatColor.BLUE + "Fill minumum touching faces set to " + this.currentPreset.getFillFaces());
vm.custom(ChatColor.DARK_BLUE + "Erosion recursion amount set to " + this.currentPreset.getErosionRecursion());
vm.custom(ChatColor.DARK_GREEN + "Fill recursion amount set to " + this.currentPreset.getFillRecursion());
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
JSAPResult result = this.parser.parse(Arrays.copyOfRange(par, 1, par.length));
if (sendHelpOrErrorMessageToPlayer(result, v.owner().getPlayer(), this.parser))
{
return;
}
if (result.getString("preset") != null)
{
try
{
this.currentPreset = Preset.valueOf(result.getString("preset").toUpperCase()).getPreset();
v.getVoxelMessage().brushMessage("Brush preset set to " + result.getString("preset"));
return;
}
catch (final IllegalArgumentException exception)
{
v.getVoxelMessage().brushMessage("No such preset.");
return;
}
}
ErosionPreset currentPresetBackup = this.currentPreset;
if (result.getObject("fill") != null)
{
this.currentPreset = new ErosionPreset(this.currentPreset.getErosionFaces(), this.currentPreset.getErosionRecursion(), result.getInt("fill"), this.currentPreset.getFillRecursion());
}
if (result.getObject("erode") != null)
{
this.currentPreset = new ErosionPreset(result.getInt("erode"), this.currentPreset.getErosionRecursion(), this.currentPreset.getFillFaces(), this.currentPreset.getFillRecursion());
}
if (result.getObject("fillrecursion") != null)
{
this.currentPreset = new ErosionPreset(this.currentPreset.getErosionFaces(), this.currentPreset.getErosionRecursion(), this.currentPreset.getFillFaces(), result.getInt("fillrecursion"));
}
if (result.getObject("eroderecursion") != null)
{
this.currentPreset = new ErosionPreset(this.currentPreset.getErosionFaces(), result.getInt("eroderecursion"), this.currentPreset.getFillFaces(), this.currentPreset.getFillRecursion());
}
if (!currentPreset.equals(currentPresetBackup))
{
if (currentPreset.getErosionFaces() != currentPresetBackup.getErosionFaces())
{
v.sendMessage(ChatColor.AQUA + "Erosion faces set to: " + ChatColor.WHITE + currentPreset.getErosionFaces());
}
if (currentPreset.getFillFaces() != currentPresetBackup.getFillFaces())
{
v.sendMessage(ChatColor.AQUA + "Fill faces set to: " + ChatColor.WHITE + currentPreset.getFillFaces());
}
if (currentPreset.getErosionRecursion() != currentPresetBackup.getErosionRecursion())
{
v.sendMessage(ChatColor.AQUA + "Erosion recursions set to: " + ChatColor.WHITE + currentPreset.getErosionRecursion());
}
if (currentPreset.getFillRecursion() != currentPresetBackup.getFillRecursion())
{
v.sendMessage(ChatColor.AQUA + "Fill recursions set to: " + ChatColor.WHITE + currentPreset.getFillRecursion());
}
}
}
/**
* @author MikeMatrix
*/
private enum Preset
{
MELT(new ErosionPreset(2, 1, 5, 1)), FILL(new ErosionPreset(5, 1, 2, 1)), SMOOTH(new ErosionPreset(3, 1, 3, 1)), LIFT(new ErosionPreset(6, 0, 1, 1)), FLOATCLEAN(new ErosionPreset(6, 1, 6, 1));
private ErosionPreset preset;
Preset(final ErosionPreset preset)
{
this.preset = preset;
}
/**
* Generates a concat string of all options.
*
* @param seperator Seperator for delimiting entries.
* @return
*/
public static String getValuesString(String seperator)
{
String valuesString = "";
boolean delimiterHelper = true;
for (final Preset preset : Preset.values())
{
if (delimiterHelper)
{
delimiterHelper = false;
}
else
{
valuesString += seperator;
}
valuesString += preset.name();
}
return valuesString;
}
public ErosionPreset getPreset()
{
return this.preset;
}
}
/**
* @author MikeMatrix
*/
private static final class BlockChangeTracker
{
private final Map<Integer, Map<Vector, BlockWrapper>> blockChanges;
private final Map<Vector, BlockWrapper> flatChanges;
private final AsyncWorld world;
private int nextIterationId = 0;
public BlockChangeTracker(final AsyncWorld world)
{
this.blockChanges = new HashMap<Integer, Map<Vector, BlockWrapper>>();
this.flatChanges = new HashMap<Vector, BlockWrapper>();
this.world = world;
}
public BlockWrapper get(final Vector position, final int iteration)
{
BlockWrapper changedBlock = null;
for (int i = iteration - 1; i >= 0; --i)
{
if (this.blockChanges.containsKey(i) && this.blockChanges.get(i).containsKey(position))
{
changedBlock = this.blockChanges.get(i).get(position);
return changedBlock;
}
}
changedBlock = new BlockWrapper((AsyncBlock) position.toLocation(this.world).getBlock());
return changedBlock;
}
public Collection<BlockWrapper> getAll()
{
return this.flatChanges.values();
}
public int nextIteration()
{
return this.nextIterationId++;
}
public void put(final Vector position, final BlockWrapper changedBlock, final int iteration)
{
if (!this.blockChanges.containsKey(iteration))
{
this.blockChanges.put(iteration, new HashMap<Vector, BlockWrapper>());
}
this.blockChanges.get(iteration).put(position, changedBlock);
this.flatChanges.put(position, changedBlock);
}
}
/**
* @author MikeMatrix
*/
private static final class BlockWrapper
{
private final AsyncBlock block;
private final Material material;
private final int data;
@SuppressWarnings("deprecation")
public BlockWrapper(final AsyncBlock block)
{
this.block = block;
this.data = block.getPropertyId();
this.material = block.getType();
}
public BlockWrapper(final AsyncBlock block, final Material material, final int data)
{
this.block = block;
this.material = material;
this.data = data;
}
/**
* @return the block
*/
public AsyncBlock getBlock()
{
return this.block;
}
/**
* @return the data
*/
public int getPropertyId()
{
return this.data;
}
/**
* @return the material
*/
public Material getMaterial()
{
return this.material;
}
/**
* @return if the block is Empty.
*/
public boolean isEmpty()
{
switch (material) {
case AIR:
case CAVE_AIR:
case VOID_AIR:
return true;
default:
return false;
}
}
/**
* @return if the block is a Liquid.
*/
public boolean isLiquid()
{
switch (this.material)
{
case WATER:
case LAVA:
return true;
default:
return false;
}
}
}
/**
* @author MikeMatrix
*/
private static final class ErosionPreset
{
private final int erosionFaces;
private final int erosionRecursion;
private final int fillFaces;
private final int fillRecursion;
public ErosionPreset(final int erosionFaces, final int erosionRecursion, final int fillFaces, final int fillRecursion)
{
this.erosionFaces = erosionFaces;
this.erosionRecursion = erosionRecursion;
this.fillFaces = fillFaces;
this.fillRecursion = fillRecursion;
}
@Override
public int hashCode()
{
return Objects.hashCode(erosionFaces, erosionRecursion, fillFaces, fillRecursion);
}
@Override
public boolean equals(final Object obj)
{
if (obj instanceof ErosionPreset)
{
ErosionPreset other = (ErosionPreset) obj;
return Objects.equal(this.erosionFaces, other.erosionFaces) && Objects.equal(this.erosionRecursion, other.erosionRecursion) && Objects.equal(this.fillFaces, other.fillFaces) && Objects.equal(this.fillRecursion, other.fillRecursion);
}
return false;
}
/**
* @return the erosionFaces
*/
public int getErosionFaces()
{
return this.erosionFaces;
}
/**
* @return the erosionRecursion
*/
public int getErosionRecursion()
{
return this.erosionRecursion;
}
/**
* @return the fillFaces
*/
public int getFillFaces()
{
return this.fillFaces;
}
/**
* @return the fillRecursion
*/
public int getFillRecursion()
{
return this.fillRecursion;
}
public ErosionPreset getInverted()
{
return new ErosionPreset(this.fillFaces, this.fillRecursion, this.erosionFaces, this.erosionRecursion);
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.erode";
}
}

Datei anzeigen

@ -0,0 +1,223 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Extrude_Brush
*
* @author psanker
*/
public class ExtrudeBrush extends Brush
{
private double trueCircle;
/**
*
*/
public ExtrudeBrush()
{
this.setName("Extrude");
}
private void extrudeUpOrDown(final SnipeData v, boolean isUp)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
Undo undo = new Undo();
for (int x = -brushSize; x <= brushSize; x++)
{
final double xSquared = Math.pow(x, 2);
for (int z = -brushSize; z <= brushSize; z++)
{
if ((xSquared + Math.pow(z, 2)) <= brushSizeSquared)
{
final int direction = (isUp ? 1 : -1);
for (int y = 0; y < Math.abs(v.getVoxelHeight()); y++)
{
final int tempY = y * direction;
undo = this.perform(
this.clampY(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + tempY, this.getTargetBlock().getZ() + z),
this.clampY(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + tempY + direction, this.getTargetBlock().getZ() + z),
v, undo);
}
}
}
}
v.owner().storeUndo(undo);
}
private void extrudeNorthOrSouth(final SnipeData v, boolean isSouth)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
Undo undo = new Undo();
for (int x = -brushSize; x <= brushSize; x++)
{
final double xSquared = Math.pow(x, 2);
for (int y = -brushSize; y <= brushSize; y++)
{
if ((xSquared + Math.pow(y, 2)) <= brushSizeSquared)
{
final int direction = (isSouth) ? 1 : -1;
for (int z = 0; z < Math.abs(v.getVoxelHeight()); z++)
{
final int tempZ = z * direction;
undo = this.perform(
this.clampY(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + tempZ),
this.clampY(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + tempZ + direction),
v, undo);
}
}
}
}
v.owner().storeUndo(undo);
}
private void extrudeEastOrWest(final SnipeData v, boolean isEast)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
Undo undo = new Undo();
for (int y = -brushSize; y <= brushSize; y++)
{
final double ySquared = Math.pow(y, 2);
for (int z = -brushSize; z <= brushSize; z++)
{
if ((ySquared + Math.pow(z, 2)) <= brushSizeSquared)
{
final int direction = (isEast) ? 1 : -1;
for (int x = 0; x < Math.abs(v.getVoxelHeight()); x++)
{
final int tempX = x * direction;
undo = this.perform(
this.clampY(this.getTargetBlock().getX() + tempX, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z),
this.clampY(this.getTargetBlock().getX() + tempX + direction, this.getTargetBlock().getY() + y, this.getTargetBlock().getZ() + z),
v, undo);
}
}
}
}
v.owner().storeUndo(undo);
}
@SuppressWarnings("deprecation")
private Undo perform(final Block b1, final Block b2, final SnipeData v, final Undo undo)
{
if (v.getVoxelList().contains(b1.getBlockData()))
{
undo.put(b2);
this.setBlockIdAt(b2.getZ(), b2.getX(), b2.getY(), this.getBlockIdAt(b1.getX(), b1.getY(), b1.getZ()));
this.clampY(b2.getX(), b2.getY(), b2.getZ()).setPropertyId(this.clampY(b1.getX(), b1.getY(), b1.getZ()).getPropertyId());
}
return undo;
}
private void selectExtrudeMethod(final SnipeData v, final BlockFace blockFace, final boolean towardsUser)
{
if (blockFace == null || v.getVoxelHeight() == 0)
{
return;
}
boolean tempDirection = towardsUser;
switch (blockFace)
{
case DOWN:
tempDirection = !towardsUser;
case UP:
extrudeUpOrDown(v, tempDirection);
break;
case NORTH:
tempDirection = !towardsUser;
case SOUTH:
extrudeNorthOrSouth(v, tempDirection);
break;
case WEST:
tempDirection = !towardsUser;
case EAST:
extrudeEastOrWest(v, tempDirection);
break;
default:
break;
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.selectExtrudeMethod(v, this.getTargetBlock().getFace(this.getLastBlock()), false);
}
@Override
protected final void powder(final SnipeData v)
{
this.selectExtrudeMethod(v, this.getTargetBlock().getFace(this.getLastBlock()), true);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.height();
vm.voxelList();
vm.custom(ChatColor.AQUA + ((this.trueCircle == 0.5) ? "True circle mode ON" : "True circle mode OFF"));
}
@Override
public final void parameters(final String[] par, final com.thevoxelbox.voxelsniper.SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
try
{
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Extrude brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b ex true -- will use a true circle algorithm instead of the skinnier version with classic sniper nubs. /b ex false will switch back. (false is default)");
return;
}
else if (parameter.startsWith("true"))
{
this.trueCircle = 0.5;
v.sendMessage(ChatColor.AQUA + "True circle mode ON.");
}
else if (parameter.startsWith("false"))
{
this.trueCircle = 0;
v.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! Use the \"info\" parameter to display parameter info.");
return;
}
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Incorrect parameter \"" + parameter + "\"; use the \"info\" parameter.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.extrude";
}
}

Datei anzeigen

@ -0,0 +1,149 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* @author Voxel
*/
public class FillDownBrush extends PerformBrush
{
private double trueCircle = 0;
private boolean fillLiquid = true;
private boolean fromExisting = false;
/**
*
*/
public FillDownBrush()
{
this.setName("Fill Down");
}
private void fillDown(final SnipeData v, final Block b)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + this.trueCircle, 2);
final Block targetBlock = this.getTargetBlock();
for (int x = -brushSize; x <= brushSize; x++)
{
final double currentXSquared = Math.pow(x, 2);
for (int z = -brushSize; z <= brushSize; z++)
{
if (currentXSquared + Math.pow(z, 2) <= brushSizeSquared)
{
int y = 0;
boolean found = false;
if(this.fromExisting) {
for(y = -v.getVoxelHeight(); y < v.getVoxelHeight(); y++) {
final Block currentBlock = this.getWorld().getBlockAt(
targetBlock.getX() + x,
targetBlock.getY() + y,
targetBlock.getZ() + z);
if(!currentBlock.isEmpty()) {
found = true;
break;
}
}
if(!found) continue;
y--;
}
for (; y >= -targetBlock.getY(); --y)
{
final AsyncBlock currentBlock = this.getWorld().getBlockAt(
targetBlock.getX() + x,
targetBlock.getY() + y,
targetBlock.getZ() + z);
if (currentBlock.isEmpty() || (fillLiquid && currentBlock.isLiquid()))
{
this.current.perform(currentBlock);
} else
{
break;
}
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.fillDown(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.fillDown(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
if (par[i].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Fill Down Parameters:");
v.sendMessage(ChatColor.AQUA + "/b fd true -- will use a true circle algorithm.");
v.sendMessage(ChatColor.AQUA + "/b fd false -- will switch back. (Default)");
v.sendMessage(ChatColor.AQUA + "/b fd some -- Fills only into air.");
v.sendMessage(ChatColor.AQUA + "/b fd all -- Fills into liquids as well. (Default)");
v.sendMessage(ChatColor.AQUA + "/b fd -e -- Fills into only existing blocks. (Toggle)");
return;
}
else if (par[i].equalsIgnoreCase("true"))
{
this.trueCircle = 0.5;
v.sendMessage(ChatColor.AQUA + "True circle mode ON.");
}
else if (par[i].equalsIgnoreCase("false"))
{
this.trueCircle = 0;
v.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
}
else if (par[i].equalsIgnoreCase("all"))
{
this.fillLiquid = true;
v.sendMessage(ChatColor.AQUA + "Now filling liquids as well as air.");
}
else if (par[i].equalsIgnoreCase("some"))
{
this.fillLiquid = false;
v.setReplaceId(0);
v.sendMessage(ChatColor.AQUA + "Now only filling air.");
}
else if (par[i].equalsIgnoreCase("-e"))
{
this.fromExisting = !this.fromExisting;
v.sendMessage(ChatColor.AQUA + "Now filling down from " + ((this.fromExisting) ? "existing" : "all") + " blocks.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.filldown";
}
}

Datei anzeigen

@ -0,0 +1,128 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncChunk;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Material;
/**
* @author GavJenks
*/
public class FlatOceanBrush extends Brush
{
private static final int DEFAULT_WATER_LEVEL = 29;
private static final int DEFAULT_FLOOR_LEVEL = 8;
private int waterLevel = DEFAULT_WATER_LEVEL;
private int floorLevel = DEFAULT_FLOOR_LEVEL;
/**
*
*/
public FlatOceanBrush()
{
this.setName("FlatOcean");
}
@SuppressWarnings("deprecation")
private void flatOcean(final AsyncChunk chunk)
{
for (int x = 0; x < CHUNK_SIZE; x++)
{
for (int z = 0; z < CHUNK_SIZE; z++)
{
for (int y = 0; y < chunk.getWorld().getMaxHeight(); y++)
{
if (y <= this.floorLevel)
{
chunk.getBlock(x, y, z).setType(Material.DIRT);
}
else if (y <= this.waterLevel)
{
chunk.getBlock(x, y, z).setType(Material.WATER);
}
else
{
chunk.getBlock(x, y, z).setType(Material.AIR);
}
}
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.flatOcean(this.getWorld().getChunkAt(this.getTargetBlock()));
}
@Override
protected final void powder(final SnipeData v)
{
this.flatOcean(this.getWorld().getChunkAt(this.getTargetBlock()));
this.flatOcean(this.getWorld().getChunkAt(this.clampY(this.getTargetBlock().getX() + CHUNK_SIZE, 1, this.getTargetBlock().getZ())));
this.flatOcean(this.getWorld().getChunkAt(this.clampY(this.getTargetBlock().getX() + CHUNK_SIZE, 1, this.getTargetBlock().getZ() + CHUNK_SIZE)));
this.flatOcean(this.getWorld().getChunkAt(this.clampY(this.getTargetBlock().getX(), 1, this.getTargetBlock().getZ() + CHUNK_SIZE)));
this.flatOcean(this.getWorld().getChunkAt(this.clampY(this.getTargetBlock().getX() - CHUNK_SIZE, 1, this.getTargetBlock().getZ() + CHUNK_SIZE)));
this.flatOcean(this.getWorld().getChunkAt(this.clampY(this.getTargetBlock().getX() - CHUNK_SIZE, 1, this.getTargetBlock().getZ())));
this.flatOcean(this.getWorld().getChunkAt(this.clampY(this.getTargetBlock().getX() - CHUNK_SIZE, 1, this.getTargetBlock().getZ() - CHUNK_SIZE)));
this.flatOcean(this.getWorld().getChunkAt(this.clampY(this.getTargetBlock().getX(), 1, this.getTargetBlock().getZ() - CHUNK_SIZE)));
this.flatOcean(this.getWorld().getChunkAt(this.clampY(this.getTargetBlock().getX() + CHUNK_SIZE, 1, this.getTargetBlock().getZ() - CHUNK_SIZE)));
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.RED + "THIS BRUSH DOES NOT UNDO");
vm.custom(ChatColor.GREEN + "Water level set to " + this.waterLevel);
vm.custom(ChatColor.GREEN + "Ocean floor level set to " + this.floorLevel);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GREEN + "yo[number] to set the Level to which the water will rise.");
v.sendMessage(ChatColor.GREEN + "yl[number] to set the Level to which the ocean floor will rise.");
}
if (parameter.startsWith("yo"))
{
int newWaterLevel = Integer.parseInt(parameter.replace("yo", ""));
if (newWaterLevel < this.floorLevel)
{
newWaterLevel = this.floorLevel + 1;
}
this.waterLevel = newWaterLevel;
v.sendMessage(ChatColor.GREEN + "Water Level set to " + this.waterLevel);
}
else if (parameter.startsWith("yl"))
{
int newFloorLevel = Integer.parseInt(parameter.replace("yl", ""));
if (newFloorLevel > this.waterLevel)
{
newFloorLevel = this.waterLevel - 1;
if (newFloorLevel == 0)
{
newFloorLevel = 1;
this.waterLevel = 2;
}
}
this.floorLevel = newFloorLevel;
v.sendMessage(ChatColor.GREEN + "Ocean floor Level set to " + this.floorLevel);
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.flatocean";
}
}

Datei anzeigen

@ -0,0 +1,781 @@
package com.thevoxelbox.voxelsniper.brush;
import java.util.ArrayList;
import java.util.Random;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
// Proposal: Use /v and /vr for leave and wood material // or two more parameters -- Monofraps
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#VoxelTrees_Brush
*
* @author Ghost8700 @ Voxel
*/
public class GenerateTreeBrush extends Brush
{
// Tree Variables.
private Random randGenerator = new Random();
private ArrayList<Block> branchBlocks = new ArrayList<Block>();
private Undo undo;
// If these default values are edited. Remember to change default values in the default preset.
private Material leafType = Material.OAK_LEAVES;
private Material woodType = Material.OAK_WOOD;
private boolean rootFloat = false;
private int startHeight = 0;
private int rootLength = 9;
private int maxRoots = 2;
private int minRoots = 1;
private int thickness = 1;
private int slopeChance = 40;
private int twistChance = 5; // This is a hidden value not available through Parameters. Otherwise messy.
private int heightMininmum = 14;
private int heightMaximum = 18;
private int branchLength = 8;
private int nodeMax = 4;
private int nodeMin = 3;
private int blockPositionX;
private int blockPositionY;
private int blockPositionZ;
/**
*
*/
public GenerateTreeBrush()
{
this.setName("Generate Tree");
}
public boolean isLog(Material m) {
switch (m) {
case ACACIA_LOG:
case BIRCH_LOG:
case DARK_OAK_LOG:
case JUNGLE_LOG:
case OAK_LOG:
case SPRUCE_LOG:
return true;
default:
return false;
}
}
public boolean isLeave(Material m) {
switch (m) {
case ACACIA_LEAVES:
case BIRCH_LEAVES:
case DARK_OAK_LEAVES:
case JUNGLE_LEAVES:
case OAK_LEAVES:
case SPRUCE_LEAVES:
return true;
default:
return false;
}
}
// Branch Creation based on direction chosen from the parameters passed.
@SuppressWarnings("deprecation")
private void branchCreate(final int xDirection, final int zDirection)
{
// Sets branch origin.
final int originX = blockPositionX;
final int originY = blockPositionY;
final int originZ = blockPositionZ;
// Sets direction preference.
final int xPreference = this.randGenerator.nextInt(60) + 20;
final int zPreference = this.randGenerator.nextInt(60) + 20;
// Iterates according to branch length.
for (int r = 0; r < this.branchLength; r++)
{
// Alters direction according to preferences.
if (this.randGenerator.nextInt(100) < xPreference)
{
blockPositionX = blockPositionX + 1 * xDirection;
}
if (this.randGenerator.nextInt(100) < zPreference)
{
blockPositionZ = blockPositionZ + 1 * zDirection;
}
// 50% chance to increase elevation every second block.
if (Math.abs(r % 2) == 1)
{
blockPositionY = blockPositionY + this.randGenerator.nextInt(2);
}
// Add block to undo function.
if (!isLog(this.getBlockType(blockPositionX, blockPositionY, blockPositionZ)))
{
this.undo.put(this.clampY(blockPositionX, blockPositionY, blockPositionZ));
}
// Creates a branch block.
this.clampY(blockPositionX, blockPositionY, blockPositionZ).setType(this.woodType);
this.branchBlocks.add(this.clampY(blockPositionX, blockPositionY, blockPositionZ));
}
// Resets the origin
blockPositionX = originX;
blockPositionY = originY;
blockPositionZ = originZ;
}
@SuppressWarnings("deprecation")
private void leafNodeCreate()
{
// Generates the node size.
final int nodeRadius = this.randGenerator.nextInt(this.nodeMax - this.nodeMin + 1) + this.nodeMin;
final double bSquared = Math.pow(nodeRadius + 0.5, 2);
// Lowers the current block in order to start at the bottom of the node.
blockPositionY = blockPositionY - 2;
for (int z = nodeRadius; z >= 0; z--)
{
final double zSquared = Math.pow(z, 2);
for (int x = nodeRadius; x >= 0; x--)
{
final double xSquared = Math.pow(x, 2);
for (int y = nodeRadius; y >= 0; y--)
{
if ((xSquared + Math.pow(y, 2) + zSquared) <= bSquared)
{
// Chance to skip creation of a block.
if (this.randGenerator.nextInt(100) >= 30)
{
// If block is Air, create a leaf block.
if (this.getWorld().getBlockAt(blockPositionX + x, blockPositionY + y, blockPositionZ + z).isEmpty())
{
// Adds block to undo function.
if (!isLeave(this.getBlockType(blockPositionX + x, blockPositionY + y, blockPositionZ + z)))
{
this.undo.put(this.clampY(blockPositionX + x, blockPositionY + y, blockPositionZ + z));
}
// Creates block.
this.clampY(blockPositionX + x, blockPositionY + y, blockPositionZ + z).setType(this.leafType);
}
}
if (this.randGenerator.nextInt(100) >= 30)
{
if (this.getWorld().getBlockAt(blockPositionX + x, blockPositionY + y, blockPositionZ - z).isEmpty())
{
if (!isLeave(this.getBlockType(blockPositionX + x, blockPositionY + y, blockPositionZ - z)))
{
this.undo.put(this.clampY(blockPositionX + x, blockPositionY + y, blockPositionZ - z));
}
this.clampY(blockPositionX + x, blockPositionY + y, blockPositionZ - z).setType(this.leafType);
}
}
if (this.randGenerator.nextInt(100) >= 30)
{
if (this.getWorld().getBlockAt(blockPositionX - x, blockPositionY + y, blockPositionZ + z).isEmpty())
{
if (!isLeave(this.getBlockType(blockPositionX - x, blockPositionY + y, blockPositionZ + z)))
{
this.undo.put(this.clampY(blockPositionX - x, blockPositionY + y, blockPositionZ + z));
}
this.clampY(blockPositionX - x, blockPositionY + y, blockPositionZ + z).setType(this.leafType);
}
}
if (this.randGenerator.nextInt(100) >= 30)
{
if (this.getWorld().getBlockAt(blockPositionX - x, blockPositionY + y, blockPositionZ - z).isEmpty())
{
if (!isLeave(this.getBlockType(blockPositionX - x, blockPositionY + y, blockPositionZ - z)))
{
this.undo.put(this.clampY(blockPositionX - x, blockPositionY + y, blockPositionZ - z));
}
this.clampY(blockPositionX - x, blockPositionY + y, blockPositionZ - z).setType(this.leafType);
}
}
if (this.randGenerator.nextInt(100) >= 30)
{
if (this.getWorld().getBlockAt(blockPositionX + x, blockPositionY - y, blockPositionZ + z).isEmpty())
{
if (!isLeave(this.getBlockType(blockPositionX + x, blockPositionY - y, blockPositionZ + z)))
{
this.undo.put(this.clampY(blockPositionX + x, blockPositionY - y, blockPositionZ + z));
}
this.clampY(blockPositionX + x, blockPositionY - y, blockPositionZ + z).setType(this.leafType);
}
}
if (this.randGenerator.nextInt(100) >= 30)
{
if (this.getWorld().getBlockAt(blockPositionX + x, blockPositionY - y, blockPositionZ - z).isEmpty())
{
if (!isLeave(this.getBlockType(blockPositionX + x, blockPositionY - y, blockPositionZ - z)))
{
this.undo.put(this.clampY(blockPositionX + x, blockPositionY - y, blockPositionZ - z));
}
this.clampY(blockPositionX + x, blockPositionY - y, blockPositionZ - z).setType(this.leafType);
}
}
if (this.randGenerator.nextInt(100) >= 30)
{
if (this.getWorld().getBlockAt(blockPositionX - x, blockPositionY - y, blockPositionZ + z).isEmpty())
{
if (!isLeave(this.getBlockType(blockPositionX - x, blockPositionY - y, blockPositionZ + z)))
{
this.undo.put(this.clampY(blockPositionX - x, blockPositionY - y, blockPositionZ + z));
}
this.clampY(blockPositionX - x, blockPositionY - y, blockPositionZ + z).setType(this.leafType);
}
}
if (this.randGenerator.nextInt(100) >= 30)
{
if (this.getWorld().getBlockAt(blockPositionX - x, blockPositionY - y, blockPositionZ - z).isEmpty())
{
if (!isLeave(this.getBlockType(blockPositionX - x, blockPositionY - y, blockPositionZ - z)))
{
this.undo.put(this.clampY(blockPositionX - x, blockPositionY - y, blockPositionZ - z));
}
this.clampY(blockPositionX - x, blockPositionY - y, blockPositionZ - z).setType(this.leafType);
}
}
}
}
}
}
}
/**
* Code Concerning Root Generation.
*
* @param xDirection
* @param zDirection
*/
@SuppressWarnings("deprecation")
private void rootCreate(final int xDirection, final int zDirection)
{
// Sets Origin.
final int originX = blockPositionX;
final int originY = blockPositionY;
final int originZ = blockPositionZ;
// Generates the number of roots to create.
final int roots = this.randGenerator.nextInt(this.maxRoots - this.minRoots + 1) + this.minRoots;
// A roots preference to move along the X and Y axis.
// Loops for each root to be created.
for (int i = 0; i < roots; i++)
{
// Pushes the root'world starting point out from the center of the tree.
for (int t = 0; t < this.thickness - 1; t++)
{
blockPositionX = blockPositionX + xDirection;
blockPositionZ = blockPositionZ + zDirection;
}
// Generate directional preference between 30% and 70%
final int xPreference = this.randGenerator.nextInt(30) + 40;
final int zPreference = this.randGenerator.nextInt(30) + 40;
for (int j = 0; j < this.rootLength; j++)
{
// For the purposes of this algorithm, logs aren't considered solid.
// If not solid then...
// Save for undo function
if (!isLog(this.getBlockType(blockPositionX, blockPositionY, blockPositionZ)))
{
this.undo.put(this.clampY(blockPositionX, blockPositionY, blockPositionZ));
// Place log block.
this.clampY(blockPositionX, blockPositionY, blockPositionZ).setType(this.woodType);
}
else
{
// If solid then...
// End loop
break;
}
// Checks is block below is solid
if (this.clampY(blockPositionX, blockPositionY - 1, blockPositionZ).isEmpty() || this.clampY(blockPositionX, blockPositionY - 1, blockPositionZ).getType() == Material.WATER || this.clampY(blockPositionX, blockPositionY - 1, blockPositionZ).getType() == Material.SNOW || isLog(this.clampY(blockPositionX, blockPositionY - 1, blockPositionZ).getType()))
{
// Mos down if solid.
blockPositionY = blockPositionY - 1;
if (this.rootFloat)
{
if (this.randGenerator.nextInt(100) < xPreference)
{
blockPositionX = blockPositionX + xDirection;
}
if (this.randGenerator.nextInt(100) < zPreference)
{
blockPositionZ = blockPositionZ + zDirection;
}
}
}
else
{
// If solid then move.
if (this.randGenerator.nextInt(100) < xPreference)
{
blockPositionX = blockPositionX + xDirection;
}
if (this.randGenerator.nextInt(100) < zPreference)
{
blockPositionZ = blockPositionZ + zDirection;
}
// Checks if new location is solid, if not then move down.
if (this.clampY(blockPositionX, blockPositionY - 1, blockPositionZ).isEmpty() || this.clampY(blockPositionX, blockPositionY - 1, blockPositionZ).getType() == Material.WATER || this.clampY(blockPositionX, blockPositionY - 1, blockPositionZ).getType() == Material.SNOW || isLog(this.clampY(blockPositionX, blockPositionY - 1, blockPositionZ).getType()))
{
blockPositionY = blockPositionY - 1;
}
}
}
// Reset origin.
blockPositionX = originX;
blockPositionY = originY;
blockPositionZ = originZ;
}
}
private void rootGen()
{
// Quadrant 1
this.rootCreate(1, 1);
// Quadrant 2
this.rootCreate(-1, 1);
// Quadrant 3
this.rootCreate(1, -1);
// Quadrant 4
this.rootCreate(-1, -1);
}
@SuppressWarnings("deprecation")
private void trunkCreate()
{
// Creates true circle discs of the set size using the wood type selected.
final double bSquared = Math.pow(this.thickness + 0.5, 2);
for (int x = this.thickness; x >= 0; x--)
{
final double xSquared = Math.pow(x, 2);
for (int z = this.thickness; z >= 0; z--)
{
if ((xSquared + Math.pow(z, 2)) <= bSquared)
{
// If block is air, then create a block.
if (this.getWorld().getBlockAt(blockPositionX + x, blockPositionY, blockPositionZ + z).isEmpty())
{
// Adds block to undo function.
if (!isLog(this.getBlockType(blockPositionX + x, blockPositionY, blockPositionZ + z)))
{
this.undo.put(this.clampY(blockPositionX + x, blockPositionY, blockPositionZ + z));
}
// Creates block.
this.clampY(blockPositionX + x, blockPositionY, blockPositionZ + z).setType(this.woodType);
}
if (this.getWorld().getBlockAt(blockPositionX + x, blockPositionY, blockPositionZ - z).isEmpty())
{
if (!isLog(this.getBlockType(blockPositionX + x, blockPositionY, blockPositionZ - z)))
{
this.undo.put(this.clampY(blockPositionX + x, blockPositionY, blockPositionZ - z));
}
this.clampY(blockPositionX + x, blockPositionY, blockPositionZ - z).setType(this.woodType);
}
if (this.getWorld().getBlockAt(blockPositionX - x, blockPositionY, blockPositionZ + z).isEmpty())
{
if (!isLog(this.getBlockType(blockPositionX - x, blockPositionY, blockPositionZ + z)))
{
this.undo.put(this.clampY(blockPositionX - x, blockPositionY, blockPositionZ + z));
}
this.clampY(blockPositionX - x, blockPositionY, blockPositionZ + z).setType(this.woodType);
}
if (this.getWorld().getBlockAt(blockPositionX - x, blockPositionY, blockPositionZ - z).isEmpty())
{
if (!isLog(this.getBlockType(blockPositionX - x, blockPositionY, blockPositionZ - z)))
{
this.undo.put(this.clampY(blockPositionX - x, blockPositionY, blockPositionZ - z));
}
this.clampY(blockPositionX - x, blockPositionY, blockPositionZ - z).setType(this.woodType);
}
}
}
}
}
/*
*
* Code Concerning Trunk Generation
*/
private void trunkGen()
{
// Sets Origin
final int originX = blockPositionX;
final int originY = blockPositionY;
final int originZ = blockPositionZ;
// ----------
// Main Trunk
// ----------
// Sets diretional preferences.
int xPreference = this.randGenerator.nextInt(this.slopeChance);
int zPreference = this.randGenerator.nextInt(this.slopeChance);
// Sets direction.
int xDirection = 1;
if (this.randGenerator.nextInt(100) < 50)
{
xDirection = -1;
}
int zDirection = 1;
if (this.randGenerator.nextInt(100) < 50)
{
zDirection = -1;
}
// Generates a height for trunk.
int height = this.randGenerator.nextInt(this.heightMaximum - this.heightMininmum + 1) + this.heightMininmum;
for (int p = 0; p < height; p++)
{
if (p > 3)
{
if (this.randGenerator.nextInt(100) <= this.twistChance)
{
xDirection *= -1;
}
if (this.randGenerator.nextInt(100) <= this.twistChance)
{
zDirection *= -1;
}
if (this.randGenerator.nextInt(100) < xPreference)
{
blockPositionX += xDirection;
}
if (this.randGenerator.nextInt(100) < zPreference)
{
blockPositionZ += zDirection;
}
}
// Creates trunk section
this.trunkCreate();
// Mos up for next section
blockPositionY = blockPositionY + 1;
}
// Generates branchs at top of trunk for each quadrant.
this.branchCreate(1, 1);
this.branchCreate(-1, 1);
this.branchCreate(1, -1);
this.branchCreate(-1, -1);
// Reset Origin for next trunk.
blockPositionX = originX;
blockPositionY = originY + 4;
blockPositionZ = originZ;
// ---------------
// Secondary Trunk
// ---------------
// Sets diretional preferences.
xPreference = this.randGenerator.nextInt(this.slopeChance);
zPreference = this.randGenerator.nextInt(this.slopeChance);
// Sets direction.
xDirection = 1;
if (this.randGenerator.nextInt(100) < 50)
{
xDirection = -1;
}
zDirection = 1;
if (this.randGenerator.nextInt(100) < 50)
{
zDirection = -1;
}
// Generates a height for trunk.
height = this.randGenerator.nextInt(this.heightMaximum - this.heightMininmum + 1) + this.heightMininmum;
if (height > 4)
{
for (int p = 0; p < height; p++)
{
if (this.randGenerator.nextInt(100) <= this.twistChance)
{
xDirection *= -1;
}
if (this.randGenerator.nextInt(100) <= this.twistChance)
{
zDirection *= -1;
}
if (this.randGenerator.nextInt(100) < xPreference)
{
blockPositionX = blockPositionX + 1 * xDirection;
}
if (this.randGenerator.nextInt(100) < zPreference)
{
blockPositionZ = blockPositionZ + 1 * zDirection;
}
// Creates a trunk section
this.trunkCreate();
// Mos up for next section
blockPositionY = blockPositionY + 1;
}
// Generates branchs at top of trunk for each quadrant.
this.branchCreate(1, 1);
this.branchCreate(-1, 1);
this.branchCreate(1, -1);
this.branchCreate(-1, -1);
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.undo = new Undo();
this.branchBlocks.clear();
// Sets the location variables.
blockPositionX = this.getTargetBlock().getX();
blockPositionY = this.getTargetBlock().getY() + this.startHeight;
blockPositionZ = this.getTargetBlock().getZ();
// Generates the roots.
this.rootGen();
// Generates the trunk, which also generates branches.
this.trunkGen();
// Each branch block was saved in an array. This is now fed through an array.
// This array takes each branch block and constructs a leaf node around it.
for (final Block block : this.branchBlocks)
{
blockPositionX = block.getX();
blockPositionY = block.getY();
blockPositionZ = block.getZ();
this.leafNodeCreate();
}
// Ends the undo function and mos on.
v.owner().storeUndo(this.undo);
}
// The Powder currently does nothing extra.
@Override
protected final void powder(final SnipeData v)
{
this.arrow(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
try
{
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "This brush takes the following parameters:");
v.sendMessage(ChatColor.AQUA + "lt# - leaf type (data value)");
v.sendMessage(ChatColor.AQUA + "wt# - wood type (data value)");
v.sendMessage(ChatColor.AQUA + "tt# - tree thickness (whote number)");
v.sendMessage(ChatColor.AQUA + "rfX - root float (true or false)");
v.sendMessage(ChatColor.AQUA + "sh# - starting height (whole number)");
v.sendMessage(ChatColor.AQUA + "rl# - root length (whole number)");
v.sendMessage(ChatColor.AQUA + "ts# - trunk slope chance (0-100)");
v.sendMessage(ChatColor.AQUA + "bl# - branch length (whole number)");
v.sendMessage(ChatColor.AQUA + "info2 - more parameters");
return;
}
if (parameter.equalsIgnoreCase("info2"))
{
v.sendMessage(ChatColor.GOLD + "This brush takes the following parameters:");
v.sendMessage(ChatColor.AQUA + "minr# - minimum roots (whole number)");
v.sendMessage(ChatColor.AQUA + "maxr# - maximum roots (whole number)");
v.sendMessage(ChatColor.AQUA + "minh# - minimum height (whole number)");
v.sendMessage(ChatColor.AQUA + "maxh# - maximum height (whole number)");
v.sendMessage(ChatColor.AQUA + "minl# - minimum leaf node size (whole number)");
v.sendMessage(ChatColor.AQUA + "maxl# - maximum leaf node size (whole number)");
v.sendMessage(ChatColor.AQUA + "default - restore default params");
return;
}
if (parameter.startsWith("lt"))
{ // Leaf Type
this.leafType = BukkitAdapter.adapt(BlockTypes.parse(parameter.replace("lt", "")));
v.sendMessage(ChatColor.BLUE + "Leaf Type set to " + this.leafType);
}
else if (parameter.startsWith("wt"))
{ // Wood Type
this.woodType = BukkitAdapter.adapt(BlockTypes.parse(parameter.replace("wt", "")));
v.sendMessage(ChatColor.BLUE + "Wood Type set to " + this.woodType);
}
else if (parameter.startsWith("tt"))
{ // Tree Thickness
this.thickness = Integer.parseInt(parameter.replace("tt", ""));
v.sendMessage(ChatColor.BLUE + "Thickness set to " + this.thickness);
}
else if (parameter.startsWith("rf"))
{ // Root Float
this.rootFloat = Boolean.parseBoolean(parameter.replace("rf", ""));
v.sendMessage(ChatColor.BLUE + "Floating Roots set to " + this.rootFloat);
}
else if (parameter.startsWith("sh"))
{ // Starting Height
this.startHeight = Integer.parseInt(parameter.replace("sh", ""));
v.sendMessage(ChatColor.BLUE + "Starting Height set to " + this.startHeight);
}
else if (parameter.startsWith("rl"))
{ // Root Length
this.rootLength = Integer.parseInt(parameter.replace("rl", ""));
v.sendMessage(ChatColor.BLUE + "Root Length set to " + this.rootLength);
}
else if (parameter.startsWith("minr"))
{ // Minimum Roots
this.minRoots = Integer.parseInt(parameter.replace("minr", ""));
if (this.minRoots > this.maxRoots)
{
this.minRoots = this.maxRoots;
v.sendMessage(ChatColor.RED + "Minimum Roots can't exceed Maximum Roots, has been set to " + this.minRoots + " Instead!");
}
else
{
v.sendMessage(ChatColor.BLUE + "Minimum Roots set to " + this.minRoots);
}
}
else if (parameter.startsWith("maxr"))
{ // Maximum Roots
this.maxRoots = Integer.parseInt(parameter.replace("maxr", ""));
if (this.minRoots > this.maxRoots)
{
this.maxRoots = this.minRoots;
v.sendMessage(ChatColor.RED + "Maximum Roots can't be lower than Minimum Roots, has been set to " + this.minRoots + " Instead!");
}
else
{
v.sendMessage(ChatColor.BLUE + "Maximum Roots set to " + this.maxRoots);
}
}
else if (parameter.startsWith("ts"))
{ // Trunk Slope Chance
this.slopeChance = Integer.parseInt(parameter.replace("ts", ""));
v.sendMessage(ChatColor.BLUE + "Trunk Slope set to " + this.slopeChance);
}
else if (parameter.startsWith("minh"))
{ // Height Minimum
this.heightMininmum = Integer.parseInt(parameter.replace("minh", ""));
if (this.heightMininmum > this.heightMaximum)
{
this.heightMininmum = this.heightMaximum;
v.sendMessage(ChatColor.RED + "Minimum Height exceed than Maximum Height, has been set to " + this.heightMininmum + " Instead!");
}
else
{
v.sendMessage(ChatColor.BLUE + "Minimum Height set to " + this.heightMininmum);
}
}
else if (parameter.startsWith("maxh"))
{ // Height Maximum
this.heightMaximum = Integer.parseInt(parameter.replace("maxh", ""));
if (this.heightMininmum > this.heightMaximum)
{
this.heightMaximum = this.heightMininmum;
v.sendMessage(ChatColor.RED + "Maximum Height can't be lower than Minimum Height, has been set to " + this.heightMaximum + " Instead!");
}
else
{
v.sendMessage(ChatColor.BLUE + "Maximum Roots set to " + this.heightMaximum);
}
}
else if (parameter.startsWith("bl"))
{ // Branch Length
this.branchLength = Integer.parseInt(parameter.replace("bl", ""));
v.sendMessage(ChatColor.BLUE + "Branch Length set to " + this.branchLength);
}
else if (parameter.startsWith("maxl"))
{ // Leaf Node Max Size
this.nodeMax = Integer.parseInt(parameter.replace("maxl", ""));
v.sendMessage(ChatColor.BLUE + "Leaf Max Thickness set to " + this.nodeMax + " (Default 4)");
}
else if (parameter.startsWith("minl"))
{ // Leaf Node Min Size
this.nodeMin = Integer.parseInt(parameter.replace("minl", ""));
v.sendMessage(ChatColor.BLUE + "Leaf Min Thickness set to " + this.nodeMin + " (Default 3)");
// -------
// Presets
// -------
}
else if (parameter.startsWith("default"))
{ // Default settings.
this.leafType = Material.OAK_LEAVES;
this.woodType = Material.OAK_WOOD;
this.rootFloat = false;
this.startHeight = 0;
this.rootLength = 9;
this.maxRoots = 2;
this.minRoots = 1;
this.thickness = 1;
this.slopeChance = 40;
this.heightMininmum = 14;
this.heightMaximum = 18;
this.branchLength = 8;
this.nodeMax = 4;
this.nodeMin = 3;
v.sendMessage(ChatColor.GOLD + "Brush reset to default parameters.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! \"" + par[i] + "\" is not a valid statement. Please use the 'info' parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.generatetree";
}
}

Datei anzeigen

@ -0,0 +1,226 @@
package com.thevoxelbox.voxelsniper.brush;
import java.util.ArrayList;
import java.util.Random;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.util.Vector;
import org.bukkit.util.noise.PerlinNoiseGenerator;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Heat_Ray
*
* @author Gavjenks
*/
public class HeatRayBrush extends Brush
{
/**
* @author MikeMatrix
*/
// private enum FlameableBlock
// {
// WOOD(Material.WOOD), SAPLING(Material.SAPLING), LOG(Material.LOG), LEAVES(Material.LEAVES), SPONGE(Material.SPONGE), WEB(Material.WEB), LONG_GRASS(Material.LONG_GRASS), DEAD_BUSH(Material.DEAD_BUSH), WOOL(Material.WOOL), YELLOW_FLOWER(Material.YELLOW_FLOWER), RED_ROSE(Material.RED_ROSE), TORCH(Material.TORCH), FIRE(Material.FIRE), WOOD_STAIRS(Material.WOOD_STAIRS), CROPS(Material.CROPS), SIGN_POST(Material.SIGN_POST), WOODEN_DOOR(Material.WOODEN_DOOR), LADDER(Material.LADDER), WALL_SIGN(Material.WALL_SIGN), WOOD_PLATE(Material.WOOD_PLATE), SNOW(Material.SNOW), ICE(Material.ICE), SUGAR_CANE_BLOCK(Material.SUGAR_CANE_BLOCK), FENCE(Material.FENCE), TRAP_DOOR(Material.TRAP_DOOR), VINE(Material.VINE), FENCE_GATE(Material.FENCE_GATE), WATER_LILLY(Material.WATER_LILY);
//
// private Material material;
//
// FlameableBlock(final Material material)
// {
// this.material = material;
// }
// }
private static final double REQUIRED_OBSIDIAN_DENSITY = 0.6;
private static final double REQUIRED_COBBLE_DENSITY = 0.5;
private static final double REQUIRED_FIRE_DENSITY = -0.25;
private static final double REQUIRED_AIR_DENSITY = 0;
private static final ArrayList<Material> FLAMABLE_BLOCKS = new ArrayList<Material>();
private int octaves = 5;
private double frequency = 1;
private double amplitude = 0.3;
static
{
for (Material m : Material.values()) {
if (!m.isLegacy() && m.isBlock() && m.isFlammable()) {
FLAMABLE_BLOCKS.add(m);
}
}
}
/**
* Default Constructor.
*/
public HeatRayBrush()
{
this.setName("Heat Ray");
}
/**
* Heat Ray executer.
*
* @param v
*/
public final void heatRay(final SnipeData v)
{
final PerlinNoiseGenerator generator = new PerlinNoiseGenerator(new Random());
final Vector targetLocation = this.getTargetBlock().getLocation().toVector();
final Location currentLocation = new Location(this.getTargetBlock().getWorld(), 0, 0, 0);
final Undo undo = new Undo();
Block currentBlock;
for (int z = v.getBrushSize(); z >= -v.getBrushSize(); z--)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = v.getBrushSize(); y >= -v.getBrushSize(); y--)
{
currentLocation.setX(this.getTargetBlock().getX() + x);
currentLocation.setY(this.getTargetBlock().getY() + y);
currentLocation.setZ(this.getTargetBlock().getZ() + z);
if (currentLocation.toVector().isInSphere(targetLocation, v.getBrushSize()))
{
currentBlock = currentLocation.getBlock();
if (currentBlock == null || currentBlock.getType() == Material.CHEST)
{
continue;
}
if (currentBlock.isLiquid())
{
undo.put(currentBlock);
currentBlock.setType(Material.AIR);
continue;
}
if (HeatRayBrush.FLAMABLE_BLOCKS.contains(currentBlock.getType()))
{
undo.put(currentBlock);
currentBlock.setType(Material.FIRE);
continue;
}
if (!currentBlock.getType().equals(Material.AIR))
{
final double airDensity = generator.noise(currentLocation.getX(), currentLocation.getY(), currentLocation.getZ(), this.octaves, this.frequency, this.amplitude);
final double fireDensity = generator.noise(currentLocation.getX(), currentLocation.getY(), currentLocation.getZ(), this.octaves, this.frequency, this.amplitude);
final double cobbleDensity = generator.noise(currentLocation.getX(), currentLocation.getY(), currentLocation.getZ(), this.octaves, this.frequency, this.amplitude);
final double obsidianDensity = generator.noise(currentLocation.getX(), currentLocation.getY(), currentLocation.getZ(), this.octaves, this.frequency, this.amplitude);
if (obsidianDensity >= HeatRayBrush.REQUIRED_OBSIDIAN_DENSITY)
{
undo.put(currentBlock);
if (currentBlock.getType() != Material.OBSIDIAN)
{
currentBlock.setType(Material.OBSIDIAN);
}
}
else if (cobbleDensity >= HeatRayBrush.REQUIRED_COBBLE_DENSITY)
{
undo.put(currentBlock);
if (currentBlock.getType() != Material.COBBLESTONE)
{
currentBlock.setType(Material.COBBLESTONE);
}
}
else if (fireDensity >= HeatRayBrush.REQUIRED_FIRE_DENSITY)
{
undo.put(currentBlock);
if (currentBlock.getType() != Material.FIRE)
{
currentBlock.setType(Material.FIRE);
}
}
else if (airDensity >= HeatRayBrush.REQUIRED_AIR_DENSITY)
{
undo.put(currentBlock);
if (!currentBlock.isEmpty())
{
currentBlock.setType(Material.AIR);
}
}
}
}
}
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
this.heatRay(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.heatRay(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.GREEN + "Octaves: " + this.octaves);
vm.custom(ChatColor.GREEN + "Amplitude: " + this.amplitude);
vm.custom(ChatColor.GREEN + "Frequency: " + this.frequency);
vm.size();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i].toLowerCase();
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Heat Ray brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b hr oct[int] -- Octaves parameter for the noise generator.");
v.sendMessage(ChatColor.AQUA + "/b hr amp[float] -- Amplitude parameter for the noise generator.");
v.sendMessage(ChatColor.AQUA + "/b hr freq[float] -- Frequency parameter for the noise generator.");
}
if (parameter.startsWith("oct"))
{
this.octaves = Integer.valueOf(parameter.replace("oct", ""));
v.getVoxelMessage().custom(ChatColor.GREEN + "Octaves: " + this.octaves);
}
else if (parameter.startsWith("amp"))
{
this.amplitude = Double.valueOf(parameter.replace("amp", ""));
v.getVoxelMessage().custom(ChatColor.GREEN + "Amplitude: " + this.amplitude);
}
else if (parameter.startsWith("freq"))
{
this.frequency = Double.valueOf(parameter.replace("freq", ""));
v.getVoxelMessage().custom(ChatColor.GREEN + "Frequency: " + this.frequency);
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.heatray";
}
}

Datei anzeigen

@ -0,0 +1,53 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeAction;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.event.block.Action;
/**
* Brush Interface.
*
*/
public interface IBrush
{
/**
* @param vm Message object
*/
void info(Message vm);
/**
* Handles parameters passed to brushes.
*
* @param par Array of string containing parameters
* @param v Snipe Data
*/
void parameters(String[] par, SnipeData v);
boolean perform(SnipeAction action, SnipeData data, AsyncBlock targetBlock, AsyncBlock lastBlock);
/**
* @return The name of the Brush
*/
String getName();
/**
* @param name New name for the Brush
*/
void setName(String name);
/**
* @return The name of the category the brush is in.
*/
String getBrushCategory();
/**
* @return Permission node required to use this brush
*/
String getPermissionNode();
}

Datei anzeigen

@ -0,0 +1,157 @@
package com.thevoxelbox.voxelsniper.brush;
import java.util.Random;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.util.BlockIterator;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Jagged_Line_Brush
*
* @author Giltwist
* @author Monofraps
*/
public class JaggedLineBrush extends PerformBrush
{
private static final Vector HALF_BLOCK_OFFSET = new Vector(0.5, 0.5, 0.5);
private static int timesUsed = 0;
private static final int RECURSION_MIN = 1;
private static final int RECURSION_DEFAULT = 3;
private static final int RECURSION_MAX = 10;
private static final int SPREAD_DEFAULT = 3;
private Random random = new Random();
private Vector originCoords = null;
private Vector targetCoords = new Vector();
private int recursion = RECURSION_DEFAULT;
private int spread = SPREAD_DEFAULT;
/**
*
*/
public JaggedLineBrush()
{
this.setName("Jagged Line");
}
private void jaggedP(final SnipeData v)
{
final Vector originClone = this.originCoords.clone().add(JaggedLineBrush.HALF_BLOCK_OFFSET);
final Vector targetClone = this.targetCoords.clone().add(JaggedLineBrush.HALF_BLOCK_OFFSET);
final Vector direction = targetClone.clone().subtract(originClone);
final double length = this.targetCoords.distance(this.originCoords);
if (length == 0)
{
this.current.perform((AsyncBlock) this.targetCoords.toLocation(this.getWorld()).getBlock());
}
else
{
for (final BlockIterator iterator = new BlockIterator(this.getWorld(), originClone, direction, 0, NumberConversions.round(length)); iterator.hasNext(); )
{
final Block block = iterator.next();
for (int i = 0; i < recursion; i++)
{
this.current.perform(this.clampY(Math.round(block.getX() + this.random.nextInt(spread * 2) - spread), Math.round(block.getY() + this.random.nextInt(spread * 2) - spread), Math.round(block.getZ() + this.random.nextInt(spread * 2) - spread)));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
public final void arrow(final SnipeData v)
{
if (originCoords == null)
{
originCoords = new Vector();
}
this.originCoords = this.getTargetBlock().getLocation().toVector();
v.sendMessage(ChatColor.DARK_PURPLE + "First point selected.");
}
@Override
public final void powder(final SnipeData v)
{
if (originCoords == null)
{
v.sendMessage(ChatColor.RED + "Warning: You did not select a first coordinate with the arrow");
}
else
{
this.targetCoords = this.getTargetBlock().getLocation().toVector();
this.jaggedP(v);
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.GRAY + String.format("Recursion set to: %d", this.recursion));
vm.custom(ChatColor.GRAY + String.format("Spread set to: %d", this.spread));
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (final String parameter : par)
{
try
{
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Jagged Line Brush instructions: Right click first point with the arrow. Right click with powder to draw a jagged line to set the second point.");
v.sendMessage(ChatColor.AQUA + "/b j r# - sets the number of recursions (default 3, must be 1-10)");
v.sendMessage(ChatColor.AQUA + "/b j s# - sets the spread (default 3, must be 1-10)");
return;
}
if (parameter.startsWith("r"))
{
final int temp = Integer.parseInt(parameter.substring(1));
if (temp >= RECURSION_MIN && temp <= RECURSION_MAX)
{
this.recursion = temp;
v.sendMessage(ChatColor.GREEN + "Recursion set to: " + this.recursion);
}
else
{
v.sendMessage(ChatColor.RED + "ERROR: Recursion must be " + RECURSION_MIN + "-" + RECURSION_MAX);
}
return;
}
else if (parameter.startsWith("s"))
{
final int temp = Integer.parseInt(parameter.substring(1));
this.spread = temp;
v.sendMessage(ChatColor.GREEN + "Spread set to: " + this.spread);
}
}
catch (Exception exception)
{
v.sendMessage(ChatColor.RED + String.format("Exception while parsing parameter: %s", parameter));
exception.printStackTrace();
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.jaggedline";
}
}

Datei anzeigen

@ -0,0 +1,278 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.List;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Jockey_Brush
*
* @author Voxel
* @author Monofraps
*/
public class JockeyBrush extends Brush
{
private static final int ENTITY_STACK_LIMIT = 50;
private JockeyType jockeyType = JockeyType.NORMAL_ALL_ENTITIES;
private Entity jockeyedEntity = null;
/**
*
*/
public JockeyBrush()
{
this.setName("Jockey");
}
private void sitOn(final SnipeData v)
{
final Chunk targetChunk = this.getWorld().getChunkAt(this.getTargetBlock().getLocation());
final int targetChunkX = targetChunk.getX();
final int targetChunkZ = targetChunk.getZ();
double range = Double.MAX_VALUE;
Entity closest = null;
for (int x = targetChunkX - 1; x <= targetChunkX + 1; x++)
{
for (int y = targetChunkZ - 1; y <= targetChunkZ + 1; y++)
{
for (final Entity entity : this.getWorld().getChunkAt(x, y).getEntities())
{
if (entity.getEntityId() == v.owner().getPlayer().getEntityId())
{
continue;
}
if (jockeyType == JockeyType.NORMAL_PLAYER_ONLY || jockeyType == JockeyType.INVERSE_PLAYER_ONLY)
{
if (!(entity instanceof Player))
{
continue;
}
}
final Location entityLocation = entity.getLocation();
final double entityDistance = entityLocation.distance(v.owner().getPlayer().getLocation());
if (entityDistance < range)
{
range = entityDistance;
closest = entity;
}
}
}
}
if (closest != null)
{
final Player player = v.owner().getPlayer();
final PlayerTeleportEvent playerTeleportEvent = new PlayerTeleportEvent(player, player.getLocation(), closest.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
Bukkit.getPluginManager().callEvent(playerTeleportEvent);
if (!playerTeleportEvent.isCancelled())
{
if (jockeyType == JockeyType.INVERSE_PLAYER_ONLY || jockeyType == JockeyType.INVERSE_ALL_ENTITIES)
{
player.setPassenger(closest);
}
else
{
closest.setPassenger(player);
jockeyedEntity = closest;
}
v.sendMessage(ChatColor.GREEN + "You are now saddles on entity: " + closest.getEntityId());
}
}
else
{
v.sendMessage(ChatColor.RED + "Could not find any entities");
}
}
private void stack(final SnipeData v)
{
final int brushSizeDoubled = v.getBrushSize() * 2;
List<Entity> nearbyEntities = v.owner().getPlayer().getNearbyEntities(brushSizeDoubled, brushSizeDoubled, brushSizeDoubled);
Entity lastEntity = v.owner().getPlayer();
int stackHeight = 0;
for (Entity entity : nearbyEntities)
{
if (!(stackHeight >= ENTITY_STACK_LIMIT))
{
if (jockeyType == JockeyType.STACK_ALL_ENTITIES)
{
lastEntity.setPassenger(entity);
lastEntity = entity;
stackHeight++;
}
else if (jockeyType == JockeyType.STACK_PLAYER_ONLY)
{
if (entity instanceof Player)
{
lastEntity.setPassenger(entity);
lastEntity = entity;
stackHeight++;
}
}
else
{
v.owner().getPlayer().sendMessage("You broke stack! :O");
}
}
else
{
return;
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
if (jockeyType == JockeyType.STACK_ALL_ENTITIES || jockeyType == JockeyType.STACK_PLAYER_ONLY)
{
stack(v);
}
else
{
this.sitOn(v);
}
}
@Override
protected final void powder(final SnipeData v)
{
if (jockeyType == JockeyType.INVERSE_PLAYER_ONLY || jockeyType == JockeyType.INVERSE_ALL_ENTITIES)
{
v.owner().getPlayer().eject();
v.owner().getPlayer().sendMessage(ChatColor.GOLD + "The guy on top of you has been ejected!");
}
else
{
if (jockeyedEntity != null)
{
jockeyedEntity.eject();
jockeyedEntity = null;
v.owner().getPlayer().sendMessage(ChatColor.GOLD + "You have been ejected!");
}
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom("Current jockey mode: " + ChatColor.GREEN + jockeyType.toString());
vm.custom(ChatColor.GREEN + "Help: " + ChatColor.AQUA + "http://www.voxelwiki.com/minecraft/Voxelsniper#The_Jockey_Brush");
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
boolean inverse = false;
boolean playerOnly = false;
boolean stack = false;
try
{
for (String parameter : par)
{
if (parameter.startsWith("-i:"))
{
inverse = parameter.endsWith("y");
}
if (parameter.startsWith("-po:"))
{
playerOnly = parameter.endsWith("y");
}
if (parameter.startsWith("-s:"))
{
stack = parameter.endsWith("y");
}
}
if (inverse)
{
if (playerOnly)
{
jockeyType = JockeyType.INVERSE_PLAYER_ONLY;
}
else
{
jockeyType = JockeyType.INVERSE_ALL_ENTITIES;
}
}
else if (stack)
{
if (playerOnly)
{
jockeyType = JockeyType.STACK_PLAYER_ONLY;
}
else
{
jockeyType = JockeyType.STACK_ALL_ENTITIES;
}
}
else
{
if (playerOnly)
{
jockeyType = JockeyType.NORMAL_PLAYER_ONLY;
}
else
{
jockeyType = JockeyType.NORMAL_ALL_ENTITIES;
}
}
v.sendMessage("Current jockey mode: " + ChatColor.GREEN + jockeyType.toString());
}
catch (Exception exception)
{
v.sendMessage("Error while parsing your arguments.");
exception.printStackTrace();
}
}
/**
* Available types of jockey modes.
*/
private enum JockeyType
{
NORMAL_ALL_ENTITIES("Normal (All)"), NORMAL_PLAYER_ONLY("Normal (Player only)"), INVERSE_ALL_ENTITIES("Inverse (All)"), INVERSE_PLAYER_ONLY("Inverse (Player only)"), STACK_ALL_ENTITIES("Stack (All)"), STACK_PLAYER_ONLY("Stack (Player only)");
private String name;
JockeyType(String name)
{
this.name = name;
}
@Override
public String toString()
{
return this.name;
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.jockey";
}
}

Datei anzeigen

@ -0,0 +1,43 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
/**
* @author Gavjenks
*/
public class LightningBrush extends Brush
{
/**
*
*/
public LightningBrush()
{
this.setName("Lightning");
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.brushMessage("Lightning Brush! Please use in moderation.");
}
@Override
protected final void arrow(final SnipeData v)
{
this.getWorld().strikeLightning(this.getTargetBlock().getLocation());
}
@Override
protected final void powder(final SnipeData v)
{
this.getWorld().strikeLightning(this.getTargetBlock().getLocation());
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.lightning";
}
}

Datei anzeigen

@ -0,0 +1,103 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.util.BlockIterator;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Line_Brush
*
* @author Gavjenks
* @author giltwist
* @author MikeMatrix
*/
public class LineBrush extends PerformBrush
{
private static final Vector HALF_BLOCK_OFFSET = new Vector(0.5, 0.5, 0.5);
private Vector originCoords = null;
private Vector targetCoords = new Vector();
private AsyncWorld targetWorld;
/**
*
*/
public LineBrush()
{
this.setName("Line");
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Line Brush instructions: Right click first point with the arrow. Right click with powder to draw a line to set the second point.");
}
}
private void linePowder(final SnipeData v)
{
final Vector originClone = this.originCoords.clone().add(LineBrush.HALF_BLOCK_OFFSET);
final Vector targetClone = this.targetCoords.clone().add(LineBrush.HALF_BLOCK_OFFSET);
final Vector direction = targetClone.clone().subtract(originClone);
final double length = this.targetCoords.distance(this.originCoords);
if (length == 0)
{
this.current.perform((AsyncBlock) this.targetCoords.toLocation(this.targetWorld).getBlock());
}
else
{
for (final BlockIterator blockIterator = new BlockIterator(this.targetWorld, originClone, direction, 0, NumberConversions.round(length)); blockIterator.hasNext(); )
{
final AsyncBlock currentBlock = (AsyncBlock) blockIterator.next();
this.current.perform(currentBlock);
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.originCoords = this.getTargetBlock().getLocation().toVector();
this.targetWorld = this.getTargetBlock().getWorld();
v.owner().getPlayer().sendMessage(ChatColor.DARK_PURPLE + "First point selected.");
}
@Override
protected final void powder(final SnipeData v)
{
if (this.originCoords == null || !this.getTargetBlock().getWorld().equals(this.targetWorld))
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "Warning: You did not select a first coordinate with the arrow");
}
else
{
this.targetCoords = this.getTargetBlock().getLocation().toVector();
this.linePowder(v);
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.line";
}
}

Datei anzeigen

@ -0,0 +1,312 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncBlockState;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
/**
* Moves a selection blockPositionY a certain amount.
* http://www.voxelwiki.com/minecraft/Voxelsniper#Move_Brush
*
* @author MikeMatrix
*/
public class MoveBrush extends Brush
{
/**
* Saved direction.
*/
private final int[] moveDirections = {0, 0, 0};
/**
* Saved selection.
*/
private Selection selection = null;
/**
*
*/
public MoveBrush()
{
this.setName("Move");
}
/**
* Moves the given selection blockPositionY the amount given in direction and saves an undo for the player.
*
* @param v
* @param selection
* @param direction
*/
@SuppressWarnings("deprecation")
private void moveSelection(final SnipeData v, final Selection selection, final int[] direction)
{
if (selection.getBlockStates().size() > 0)
{
final AsyncWorld world = selection.getBlockStates().get(0).getWorld();
final Undo undo = new Undo();
final HashSet<Block> undoSet = new HashSet<Block>();
final Selection newSelection = new Selection();
final Location movedLocation1 = selection.getLocation1();
movedLocation1.add(direction[0], direction[1], direction[2]);
final Location movedLocation2 = selection.getLocation2();
movedLocation2.add(direction[0], direction[1], direction[2]);
newSelection.setLocation1(movedLocation1);
newSelection.setLocation2(movedLocation2);
try
{
newSelection.calculateRegion();
}
catch (final Exception exception)
{
v.getVoxelMessage().brushMessage("The new Selection has more blocks than the original selection. This should never happen!");
}
for (final BlockState blockState : selection.getBlockStates())
{
undoSet.add(blockState.getBlock());
}
for (final BlockState blockState : newSelection.getBlockStates())
{
undoSet.add(blockState.getBlock());
}
for (final Block block : undoSet)
{
undo.put(block);
}
v.owner().storeUndo(undo);
for (final BlockState blockState : selection.getBlockStates())
{
blockState.getBlock().setType(Material.AIR);
}
for (final AsyncBlockState blockState : selection.getBlockStates())
{
final AsyncBlock affectedBlock = world.getBlockAt(blockState.getX() + direction[0], blockState.getY() + direction[1], blockState.getZ() + direction[2]);
affectedBlock.setTypeId(blockState.getTypeId());
affectedBlock.setPropertyId(blockState.getPropertyId());
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
if (this.selection == null)
{
this.selection = new Selection();
}
this.selection.setLocation1(this.getTargetBlock().getLocation());
v.getVoxelMessage().brushMessage("Point 1 set.");
try
{
if (this.selection.calculateRegion())
{
this.moveSelection(v, this.selection, this.moveDirections);
this.selection = null;
}
}
catch (final Exception exception)
{
v.sendMessage(exception.getMessage());
}
}
@Override
protected final void powder(final SnipeData v)
{
if (this.selection == null)
{
this.selection = new Selection();
}
this.selection.setLocation2(this.getTargetBlock().getLocation());
v.getVoxelMessage().brushMessage("Point 2 set.");
try
{
if (this.selection.calculateRegion())
{
this.moveSelection(v, this.selection, this.moveDirections);
this.selection = null;
}
}
catch (final Exception exception)
{
v.sendMessage(exception.getMessage());
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.BLUE + "Move selection blockPositionY " + ChatColor.GOLD + "x:" + this.moveDirections[0] + " y:" + this.moveDirections[1] + " z:" + this.moveDirections[2]);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
if (par[i].equalsIgnoreCase("info"))
{
v.getVoxelMessage().custom(ChatColor.GOLD + this.getName() + " Parameters:");
v.getVoxelMessage().custom(ChatColor.AQUA + "/b mv x[int] -- set the x direction (positive => east)");
v.getVoxelMessage().custom(ChatColor.AQUA + "/b mv y[int] -- set the y direction (positive => up)");
v.getVoxelMessage().custom(ChatColor.AQUA + "/b mv z[int] -- set the z direction (positive => south)");
v.getVoxelMessage().custom(ChatColor.AQUA + "/b mv reset -- reset the brush (x:0 y:0 z:0)");
v.getVoxelMessage().custom(ChatColor.AQUA + "Use arrow and gunpowder to define two points.");
}
if (par[i].equalsIgnoreCase("reset"))
{
this.moveDirections[0] = 0;
this.moveDirections[1] = 0;
this.moveDirections[2] = 0;
v.getVoxelMessage().custom(ChatColor.AQUA + "X direction set to: " + this.moveDirections[0]);
v.getVoxelMessage().custom(ChatColor.AQUA + "Y direction set to: " + this.moveDirections[1]);
v.getVoxelMessage().custom(ChatColor.AQUA + "Z direction set to: " + this.moveDirections[2]);
}
if (par[i].toLowerCase().startsWith("x"))
{
this.moveDirections[0] = Integer.valueOf(par[i].substring(1));
v.getVoxelMessage().custom(ChatColor.AQUA + "X direction set to: " + this.moveDirections[0]);
}
else if (par[i].toLowerCase().startsWith("y"))
{
this.moveDirections[1] = Integer.valueOf(par[i].substring(1));
v.getVoxelMessage().custom(ChatColor.AQUA + "Y direction set to: " + this.moveDirections[1]);
}
else if (par[i].toLowerCase().startsWith("z"))
{
this.moveDirections[2] = Integer.valueOf(par[i].substring(1));
v.getVoxelMessage().custom(ChatColor.AQUA + "Z direction set to: " + this.moveDirections[2]);
}
}
}
/**
* Selection Helper class.
*
* @author MikeMatrix
*/
private class Selection
{
/**
* Maximum amount of Blocks allowed blockPositionY the Selection.
*/
private static final int MAX_BLOCK_COUNT = 5000000;
/**
* Calculated BlockStates of the selection.
*/
private final ArrayList<AsyncBlockState> blockStates = new ArrayList<AsyncBlockState>();
/**
*
*/
private Location location1 = null;
/**
*
*/
private Location location2 = null;
/**
* Calculates region, then saves all Blocks as BlockState.
*
* @return boolean success.
* @throws Exception Message to be sent to the player.
*/
public boolean calculateRegion() throws Exception
{
if (this.location1 != null && this.location2 != null)
{
if (this.location1.getWorld().equals(this.location2.getWorld()))
{
final int lowX = ((this.location1.getBlockX() <= this.location2.getBlockX()) ? this.location1.getBlockX() : this.location2.getBlockX());
final int lowY = (this.location1.getBlockY() <= this.location2.getBlockY()) ? this.location1.getBlockY() : this.location2.getBlockY();
final int lowZ = (this.location1.getBlockZ() <= this.location2.getBlockZ()) ? this.location1.getBlockZ() : this.location2.getBlockZ();
final int highX = (this.location1.getBlockX() >= this.location2.getBlockX()) ? this.location1.getBlockX() : this.location2.getBlockX();
final int highY = (this.location1.getBlockY() >= this.location2.getBlockY()) ? this.location1.getBlockY() : this.location2.getBlockY();
final int highZ = (this.location1.getBlockZ() >= this.location2.getBlockZ()) ? this.location1.getBlockZ() : this.location2.getBlockZ();
if (Math.abs(highX - lowX) * Math.abs(highZ - lowZ) * Math.abs(highY - lowY) > Selection.MAX_BLOCK_COUNT)
{
throw new Exception(ChatColor.RED + "Selection size above hardcoded limit, please use a smaller selection.");
}
final AsyncWorld world = (AsyncWorld) this.location1.getWorld();
for (int y = lowY; y <= highY; y++)
{
for (int x = lowX; x <= highX; x++)
{
for (int z = lowZ; z <= highZ; z++)
{
this.blockStates.add(world.getBlockAt(x, y, z).getState());
}
}
}
return true;
}
}
return false;
}
/**
* @return ArrayList<BlockState> calculated BlockStates of defined region.
*/
public ArrayList<AsyncBlockState> getBlockStates()
{
return this.blockStates;
}
/**
* @return Location
*/
public Location getLocation1()
{
return this.location1;
}
/**
* @param location1
*/
public void setLocation1(final Location location1)
{
this.location1 = location1;
}
/**
* @return Location
*/
public Location getLocation2()
{
return this.location2;
}
/**
* @param location2
*/
public void setLocation2(final Location location2)
{
this.location2 = location2;
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.move";
}
}

Datei anzeigen

@ -0,0 +1,191 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_OCEANATOR_5000
*
* @author Voxel
*/
public class OceanBrush extends Brush
{
private static final int WATER_LEVEL_DEFAULT = 62; // y=63 -- we are using array indices here
private static final int WATER_LEVEL_MIN = 12;
private static final int LOW_CUT_LEVEL = 12;
private int waterLevel = WATER_LEVEL_DEFAULT;
private boolean coverFloor = false;
/**
*
*/
public OceanBrush()
{
this.setName("OCEANATOR 5000(tm)");
}
private int getHeight(final int bx, final int bz)
{
for (int y = this.getWorld().getHighestBlockYAt(bx, bz); y > 0; y--)
{
final Material material = this.clampY(bx, y, bz).getType();
if (material.isSolid())
{
return y;
}
}
return 0;
}
/**
* @param v
* @param undo
*/
protected final void oceanator(final SnipeData v, final Undo undo)
{
final AsyncWorld world = this.getWorld();
final int minX = (int) Math.floor((this.getTargetBlock().getX() - v.getBrushSize()));
final int minZ = (int) Math.floor((this.getTargetBlock().getZ() - v.getBrushSize()));
final int maxX = (int) Math.floor((this.getTargetBlock().getX() + v.getBrushSize()));
final int maxZ = (int) Math.floor((this.getTargetBlock().getZ() + v.getBrushSize()));
for (int x = minX; x <= maxX; x++)
{
for (int z = minZ; z <= maxZ; z++)
{
final int currentHeight = getHeight(x, z);
final int wLevelDiff = currentHeight - (this.waterLevel - 1);
final int newSeaFloorLevel = ((this.waterLevel - wLevelDiff) >= LOW_CUT_LEVEL) ? this.waterLevel - wLevelDiff : LOW_CUT_LEVEL;
final int highestY = this.getWorld().getHighestBlockYAt(x, z);
// go down from highest Y block down to new sea floor
for (int y = highestY; y > newSeaFloorLevel; y--)
{
final Block block = world.getBlockAt(x, y, z);
if (!block.getType().equals(Material.AIR))
{
undo.put(block);
block.setType(Material.AIR);
}
}
// go down from water level to new sea level
for (int y = this.waterLevel; y > newSeaFloorLevel; y--)
{
final Block block = world.getBlockAt(x, y, z);
if (!block.getType().equals(Material.WATER))
{
// do not put blocks into the undo we already put into
if (!block.getType().equals(Material.AIR))
{
undo.put(block);
}
block.setType(Material.WATER);
}
}
// cover the sea floor of required
if (this.coverFloor && (newSeaFloorLevel < this.waterLevel))
{
AsyncBlock block = world.getBlockAt(x, newSeaFloorLevel, z);
if (block.getTypeId() != v.getVoxelId())
{
undo.put(block);
block.setTypeId(v.getVoxelId());
}
}
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
Undo undo = new Undo();
this.oceanator(v, undo);
v.owner().storeUndo(undo);
}
@Override
protected final void powder(final SnipeData v)
{
arrow(v);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 0; i < par.length; i++)
{
final String parameter = par[i];
try
{
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.BLUE + "Parameters:");
v.sendMessage(ChatColor.GREEN + "-wlevel # " + ChatColor.BLUE + "-- Sets the water level (e.g. -wlevel 64)");
v.sendMessage(ChatColor.GREEN + "-cfloor [y|n] " + ChatColor.BLUE + "-- Enables or disables sea floor cover (e.g. -cfloor y) (Cover material will be your voxel material)");
}
else if (parameter.equalsIgnoreCase("-wlevel"))
{
if ((i + 1) >= par.length)
{
v.sendMessage(ChatColor.RED + "Missing parameter. Correct syntax: -wlevel [#] (e.g. -wlevel 64)");
continue;
}
int temp = Integer.parseInt(par[++i]);
if (temp <= WATER_LEVEL_MIN)
{
v.sendMessage(ChatColor.RED + "Error: Your specified water level was below 12.");
continue;
}
this.waterLevel = temp - 1;
v.sendMessage(ChatColor.BLUE + "Water level set to " + ChatColor.GREEN + (waterLevel + 1)); // +1 since we are working with 0-based array indices
}
else if (parameter.equalsIgnoreCase("-cfloor") || parameter.equalsIgnoreCase("-coverfloor"))
{
if ((i + 1) >= par.length)
{
v.sendMessage(ChatColor.RED + "Missing parameter. Correct syntax: -cfloor [y|n] (e.g. -cfloor y)");
continue;
}
this.coverFloor = par[++i].equalsIgnoreCase("y");
v.sendMessage(ChatColor.BLUE + String.format("Floor cover %s.", ChatColor.GREEN + (this.coverFloor ? "enabled" : "disabled")));
}
}
catch (Exception exception)
{
v.sendMessage(ChatColor.RED + String.format("Error while parsing parameter: %s", parameter));
exception.printStackTrace();
}
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.BLUE + "Water level set to " + ChatColor.GREEN + (waterLevel + 1)); // +1 since we are working with 0-based array indices
vm.custom(ChatColor.BLUE + String.format("Floor cover %s.", ChatColor.GREEN + (this.coverFloor ? "enabled" : "disabled")));
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.ocean";
}
}

Datei anzeigen

@ -0,0 +1,233 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.Material;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Overlay_.2F_Topsoil_Brush
*
* @author Gavjenks
*/
public class OverlayBrush extends PerformBrush
{
private static final int DEFAULT_DEPTH = 3;
private int depth = DEFAULT_DEPTH;
private boolean allBlocks = false;
/**
*
*/
public OverlayBrush()
{
this.setName("Overlay (Topsoil Filling)");
}
private void overlay(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + 0.5, 2);
for (int z = brushSize; z >= -brushSize; z--)
{
for (int x = brushSize; x >= -brushSize; x--)
{
// check if column is valid
// column is valid if it has no solid block right above the clicked layer
final int materialId = this.getBlockIdAt(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + 1, this.getTargetBlock().getZ() + z);
if (isIgnoredBlock(materialId))
{
if ((Math.pow(x, 2) + Math.pow(z, 2)) <= brushSizeSquared)
{
for (int y = this.getTargetBlock().getY(); y > 0; y--)
{
// check for surface
final int layerBlockId = this.getBlockIdAt(this.getTargetBlock().getX() + x, y, this.getTargetBlock().getZ() + z);
if (!isIgnoredBlock(layerBlockId))
{
for (int currentDepth = y; y - currentDepth < depth; currentDepth--)
{
final int currentBlockId = this.getBlockIdAt(this.getTargetBlock().getX() + x, currentDepth, this.getTargetBlock().getZ() + z);
if (isOverrideableMaterial(currentBlockId))
{
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, currentDepth, this.getTargetBlock().getZ() + z));
}
}
break;
}
}
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@SuppressWarnings("deprecation")
private boolean isIgnoredBlock(int materialId)
{
BlockTypes type = BlockTypes.getFromStateId(materialId);
switch (type) {
case WATER:
case LAVA:
case CACTUS:
return true;
}
BlockMaterial mat = type.getMaterial();
return mat.isTranslucent();
}
@SuppressWarnings("deprecation")
private boolean isOverrideableMaterial(int materialId)
{
BlockMaterial mat = BlockTypes.getFromStateId(materialId).getMaterial();
if (allBlocks && !(mat.isAir()))
{
return true;
}
if (!mat.isFragileWhenPushed() && mat.isFullCube()) {
return true;
}
return false;
}
private void overlayTwo(final SnipeData v)
{
final int brushSize = v.getBrushSize();
final double brushSizeSquared = Math.pow(brushSize + 0.5, 2);
final int[][] memory = new int[brushSize * 2 + 1][brushSize * 2 + 1];
for (int z = brushSize; z >= -brushSize; z--)
{
for (int x = brushSize; x >= -brushSize; x--)
{
boolean surfaceFound = false;
for (int y = this.getTargetBlock().getY(); y > 0 && !surfaceFound; y--)
{ // start scanning from the height you clicked at
if (memory[x + brushSize][z + brushSize] != 1)
{ // if haven't already found the surface in this column
if ((Math.pow(x, 2) + Math.pow(z, 2)) <= brushSizeSquared)
{ // if inside of the column...
if (this.getBlockIdAt(this.getTargetBlock().getX() + x, y - 1, this.getTargetBlock().getZ() + z) != 0)
{ // if not a floating block (like one of Notch'world pools)
if (this.getBlockIdAt(this.getTargetBlock().getX() + x, y + 1, this.getTargetBlock().getZ() + z) == 0)
{ // must start at surface... this prevents it filling stuff in if
// you click in a wall and it starts out below surface.
if (!this.allBlocks)
{ // if the override parameter has not been activated, go to the switch that filters out manmade stuff.
BlockTypes type = BlockTypes.get(this.getBlockIdAt(this.getTargetBlock().getX() + x, y, this.getTargetBlock().getZ() + z));
BlockMaterial mat = type.getMaterial();
if (mat.isSolid() && mat.isFullCube() && !mat.hasContainer()) {
for (int d = 1; (d < this.depth + 1); d++) {
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y + d, this.getTargetBlock().getZ() + z)); // fills down as many layers as you specify
// in parameters
memory[x + brushSize][z + brushSize] = 1; // stop it from checking any other blocks in this vertical 1x1 column.
}
surfaceFound = true;
continue;
} else {
continue;
}
}
else
{
for (int d = 1; (d < this.depth + 1); d++)
{
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y + d, this.getTargetBlock().getZ() + z)); // fills down as many layers as you specify in
// parameters
memory[x + brushSize][z + brushSize] = 1; // stop it from checking any other blocks in this vertical 1x1 column.
}
surfaceFound = true;
}
}
}
}
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.overlay(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.overlayTwo(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Overlay brush parameters:");
v.sendMessage(ChatColor.AQUA + "d[number] (ex: d3) How many blocks deep you want to replace from the surface.");
v.sendMessage(ChatColor.BLUE + "all (ex: /b over all) Sets the brush to overlay over ALL materials, not just natural surface ones (will no longer ignore trees and buildings). The parameter /some will set it back to default.");
return;
}
if (parameter.startsWith("d"))
{
try {
this.depth = Integer.parseInt(parameter.replace("d", ""));
if (this.depth < 1)
{
this.depth = 1;
}
v.sendMessage(ChatColor.AQUA + "Depth set to " + this.depth);
} catch (NumberFormatException e) {
v.sendMessage(ChatColor.RED + "Depth isn't a number.");
}
}
else if (parameter.startsWith("all"))
{
this.allBlocks = true;
v.sendMessage(ChatColor.BLUE + "Will overlay over any block." + this.depth);
}
else if (parameter.startsWith("some"))
{
this.allBlocks = false;
v.sendMessage(ChatColor.BLUE + "Will overlay only natural block types." + this.depth);
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.overlay";
}
}

Datei anzeigen

@ -0,0 +1,56 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.PaintingWrapper;
import com.thevoxelbox.voxelsniper.SnipeData;
/**
* Painting scrolling Brush.
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Painting_Picker_Brush
*
* @author Voxel
*/
public class PaintingBrush extends Brush
{
/**
*
*/
public PaintingBrush()
{
this.setName("Painting");
}
/**
* Scroll painting forward.
*
* @param v Sniper caller
*/
@Override
protected final void arrow(final SnipeData v)
{
PaintingWrapper.paint(v.owner().getPlayer(), true, false, 0);
}
/**
* Scroll painting backwards.
*
* @param v Sniper caller
*/
@Override
protected final void powder(final SnipeData v)
{
PaintingWrapper.paint(v.owner().getPlayer(), true, true, 0);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.painting";
}
}

Datei anzeigen

@ -0,0 +1,371 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import java.util.HashSet;
/**
* @author Piotr
*/
public class PullBrush extends Brush
{
private final HashSet<BlockWrapper> surface = new HashSet<BlockWrapper>();
private int vh;
private double c1 = 1;
private double c2 = 0;
/**
* Default Constructor.
*/
public PullBrush()
{
this.setName("Soft Selection");
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.height();
vm.custom(ChatColor.AQUA + "Pinch " + (-this.c1 + 1));
vm.custom(ChatColor.AQUA + "Bubble " + this.c2);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
try
{
final double pinch = Double.parseDouble(par[1]);
final double bubble = Double.parseDouble(par[2]);
this.c1 = 1 - pinch;
this.c2 = bubble;
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters!");
}
}
/**
* @param t
* @return double
*/
private double getStr(final double t)
{
final double lt = 1 - t;
return (lt * lt * lt) + 3 * (lt * lt) * t * this.c1 + 3 * lt * (t * t) * this.c2; // My + (t * ((By + (t * ((c2 + (t * (0 - c2))) - By))) - My));
}
/**
* @param v
*/
private void getSurface(final SnipeData v)
{
this.surface.clear();
final double bSquared = Math.pow(v.getBrushSize() + 0.5, 2);
for (int z = -v.getBrushSize(); z <= v.getBrushSize(); z++)
{
final double zSquared = Math.pow(z, 2);
final int actualZ = this.getTargetBlock().getZ() + z;
for (int x = -v.getBrushSize(); x <= v.getBrushSize(); x++)
{
final double xSquared = Math.pow(x, 2);
final int actualX = this.getTargetBlock().getX() + x;
for (int y = -v.getBrushSize(); y <= v.getBrushSize(); y++)
{
final double volume = (xSquared + Math.pow(y, 2) + zSquared);
if (volume <= bSquared)
{
if (this.isSurface(actualX, this.getTargetBlock().getY() + y, actualZ))
{
this.surface.add(new BlockWrapper(this.clampY(actualX, this.getTargetBlock().getY() + y, actualZ), this.getStr(((volume / bSquared)))));
}
}
}
}
}
}
/**
* @param x
* @param y
* @param z
* @return boolean
*/
private boolean isSurface(final int x, final int y, final int z)
{
return this.getBlockIdAt(x, y, z) != 0 && ((this.getBlockIdAt(x, y - 1, z) == 0) || (this.getBlockIdAt(x, y + 1, z) == 0) || (this.getBlockIdAt(x + 1, y, z) == 0) || (this.getBlockIdAt(x - 1, y, z) == 0) || (this.getBlockIdAt(x, y, z + 1) == 0) || (this.getBlockIdAt(x, y, z - 1) == 0));
}
@SuppressWarnings("deprecation")
private void setBlock(final BlockWrapper block)
{
final AsyncBlock currentBlock = this.clampY(block.getX(), block.getY() + (int) (this.vh * block.getStr()), block.getZ());
if (this.getBlockIdAt(block.getX(), block.getY() - 1, block.getZ()) == 0)
{
currentBlock.setTypeId(block.getId());
currentBlock.setPropertyId(block.getD());
for (int y = block.getY(); y < currentBlock.getY(); y++)
{
this.setBlockIdAt(block.getZ(), block.getX(), y, 0);
}
}
else
{
currentBlock.setTypeId(block.getId());
currentBlock.setPropertyId(block.getD());
for (int y = block.getY() - 1; y < currentBlock.getY(); y++)
{
final AsyncBlock current = this.clampY(block.getX(), y, block.getZ());
current.setTypeId(block.getId());
current.setPropertyId(block.getD());
}
}
}
@SuppressWarnings("deprecation")
private void setBlockDown(final BlockWrapper block)
{
final AsyncBlock currentBlock = this.clampY(block.getX(), block.getY() + (int) (this.vh * block.getStr()), block.getZ());
currentBlock.setTypeId(block.getId());
currentBlock.setPropertyId(block.getD());
for (int y = block.getY(); y > currentBlock.getY(); y--)
{
this.setBlockIdAt(block.getZ(), block.getX(), y, 0);
}
// }
}
@Override
protected final void arrow(final SnipeData v)
{
this.vh = v.getVoxelHeight();
this.getSurface(v);
if (this.vh > 0)
{
for (final BlockWrapper block : this.surface)
{
this.setBlock(block);
}
}
else if (this.vh < 0)
{
for (final BlockWrapper block : this.surface)
{
this.setBlockDown(block);
}
}
}
@SuppressWarnings("deprecation")
@Override
protected final void powder(final SnipeData v)
{
this.vh = v.getVoxelHeight();
this.surface.clear();
int lastY;
int newY;
int lastStr;
double str;
final double brushSizeSquared = Math.pow(v.getBrushSize() + 0.5, 2);
int id;
// Are we pulling up ?
if (this.vh > 0)
{
// Z - Axis
for (int z = -v.getBrushSize(); z <= v.getBrushSize(); z++)
{
final int zSquared = z * z;
final int actualZ = this.getTargetBlock().getZ() + z;
// X - Axis
for (int x = -v.getBrushSize(); x <= v.getBrushSize(); x++)
{
final int xSquared = x * x;
final int actualX = this.getTargetBlock().getX() + x;
// Down the Y - Axis
for (int y = v.getBrushSize(); y >= -v.getBrushSize(); y--)
{
final double volume = zSquared + xSquared + (y * y);
// Is this in the range of the brush?
if (volume <= brushSizeSquared && !this.getWorld().getBlockAt(actualX, this.getTargetBlock().getY() + y, actualZ).isEmpty())
{
int actualY = this.getTargetBlock().getY() + y;
// Starting strength and new Position
str = this.getStr(volume / brushSizeSquared);
lastStr = (int) (this.vh * str);
lastY = actualY + lastStr;
this.clampY(actualX, lastY, actualZ).setTypeId(this.getWorld().getBlockAt(actualX, actualY, actualZ).getTypeId());
if (str == 1)
{
str = 0.8;
}
while (lastStr > 0)
{
if (actualY < this.getTargetBlock().getY())
{
str = str * str;
}
lastStr = (int) (this.vh * str);
newY = actualY + lastStr;
id = this.getWorld().getBlockAt(actualX, actualY, actualZ).getTypeId();
for (int i = newY; i < lastY; i++)
{
this.clampY(actualX, i, actualZ).setTypeId(id);
}
lastY = newY;
actualY--;
}
break;
}
}
}
}
}
else
{
for (int z = -v.getBrushSize(); z <= v.getBrushSize(); z++)
{
final double zSquared = Math.pow(z, 2);
final int actualZ = this.getTargetBlock().getZ() + z;
for (int x = -v.getBrushSize(); x <= v.getBrushSize(); x++)
{
final double xSquared = Math.pow(x, 2);
final int actualX = this.getTargetBlock().getX() + x;
for (int y = -v.getBrushSize(); y <= v.getBrushSize(); y++)
{
double volume = (xSquared + Math.pow(y, 2) + zSquared);
if (volume <= brushSizeSquared && !this.getWorld().getBlockAt(actualX, this.getTargetBlock().getY() + y, actualZ).isEmpty())
{
final int actualY = this.getTargetBlock().getY() + y;
lastY = actualY + (int) (this.vh * this.getStr(volume / brushSizeSquared));
this.clampY(actualX, lastY, actualZ).setTypeId(this.getWorld().getBlockAt(actualX, actualY, actualZ).getTypeId());
y++;
volume = (xSquared + Math.pow(y, 2) + zSquared);
while (volume <= brushSizeSquared)
{
final int blockY = this.getTargetBlock().getY() + y + (int) (this.vh * this.getStr(volume / brushSizeSquared));
final int blockId = this.getWorld().getBlockAt(actualX, this.getTargetBlock().getY() + y, actualZ).getTypeId();
for (int i = blockY; i < lastY; i++)
{
this.clampY(actualX, i, actualZ).setTypeId(blockId);
}
lastY = blockY;
y++;
volume = (xSquared + Math.pow(y, 2) + zSquared);
}
break;
}
}
}
}
}
}
/**
* @author Piotr
*/
private final class BlockWrapper
{
private final int id;
private final int d;
private final double str;
private final int x;
private final int y;
private final int z;
/**
* @param block
* @param st
*/
@SuppressWarnings("deprecation")
public BlockWrapper(final AsyncBlock block, final double st)
{
this.id = block.getTypeId();
this.d = block.getPropertyId();
this.x = block.getX();
this.y = block.getY();
this.z = block.getZ();
this.str = st;
}
/**
* @return the d
*/
public int getD()
{
return this.d;
}
/**
* @return the id
*/
public int getId()
{
return this.id;
}
/**
* @return the str
*/
public double getStr()
{
return this.str;
}
/**
* @return the x
*/
public int getX()
{
return this.x;
}
/**
* @return the y
*/
public int getY()
{
return this.y;
}
/**
* @return the z
*/
public int getZ()
{
return this.z;
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.pull";
}
}

Datei anzeigen

@ -0,0 +1,383 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import java.util.List;
import java.util.Random;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Punish_Brush
*
* @author Monofraps
* @author Deamon
* @author MikeMatrix
*/
public class PunishBrush extends PerformBrush
{
private static final int MAXIMAL_RANDOM_TELEPORTATION_RANGE = 400;
private static final int TICKS_PER_SECOND = 20;
private static final int INFINIPUNISH_SIZE = -3;
private static final int DEFAULT_PUNISH_LEVEL = 10;
private static final int DEFAULT_PUSNIH_DURATION = 60;
private Punishment punishment = Punishment.FIRE;
private int punishLevel = DEFAULT_PUNISH_LEVEL;
private int punishDuration = DEFAULT_PUSNIH_DURATION;
private boolean specificPlayer = false;
private String punishPlayerName = "";
private boolean hypnoAffectLandscape = false;
private boolean hitsSelf = false;
/**
* Default Constructor.
*/
public PunishBrush()
{
this.setName("Punish");
}
@SuppressWarnings("deprecation")
private void applyPunishment(final LivingEntity entity, final SnipeData v)
{
switch (this.punishment)
{
case FIRE:
entity.setFireTicks(PunishBrush.TICKS_PER_SECOND * this.punishDuration);
break;
case LIGHTNING:
entity.getWorld().strikeLightning(entity.getLocation());
break;
case BLINDNESS:
entity.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case DRUNK:
entity.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case SLOW:
entity.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case JUMP:
entity.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case ABSORPTION:
entity.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case DAMAGE_RESISTANCE:
entity.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case FAST_DIGGING:
entity.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case FIRE_RESISTANCE:
entity.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case HEAL:
entity.addPotionEffect(new PotionEffect(PotionEffectType.HEAL, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case HEALTH_BOOST:
entity.addPotionEffect(new PotionEffect(PotionEffectType.HEALTH_BOOST, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case HUNGER:
entity.addPotionEffect(new PotionEffect(PotionEffectType.HUNGER, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case INCREASE_DAMAGE:
entity.addPotionEffect(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case INVISIBILITY:
entity.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case NIGHT_VISION:
entity.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case POISON:
entity.addPotionEffect(new PotionEffect(PotionEffectType.POISON, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case REGENERATION:
entity.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case SATURATION:
entity.addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case SLOW_DIGGING:
entity.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case SPEED:
entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case WATER_BREATHING:
entity.addPotionEffect(new PotionEffect(PotionEffectType.WATER_BREATHING, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case WEAKNESS:
entity.addPotionEffect(new PotionEffect(PotionEffectType.WEAKNESS, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case WITHER:
entity.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case KILL:
entity.setHealth(0d);
break;
case RANDOMTP:
final Random random = new Random();
final Location targetLocation = entity.getLocation();
targetLocation.setX(targetLocation.getX() + (random.nextInt(MAXIMAL_RANDOM_TELEPORTATION_RANGE) - (MAXIMAL_RANDOM_TELEPORTATION_RANGE / 2)));
targetLocation.setZ(targetLocation.getZ() + (random.nextInt(PunishBrush.MAXIMAL_RANDOM_TELEPORTATION_RANGE) - PunishBrush.MAXIMAL_RANDOM_TELEPORTATION_RANGE / 2));
entity.teleport(targetLocation);
break;
case ALL_POTION:
entity.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
entity.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
entity.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
entity.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, PunishBrush.TICKS_PER_SECOND * this.punishDuration, this.punishLevel), true);
break;
case FORCE:
final Vector playerVector = this.getTargetBlock().getLocation().toVector();
final Vector direction = entity.getLocation().toVector().clone();
direction.subtract(playerVector);
final double length = direction.length();
final double stregth = (1 - (length / v.getBrushSize())) * this.punishLevel;
direction.normalize();
direction.multiply(stregth);
entity.setVelocity(direction);
break;
case HYPNO:
if (entity instanceof Player)
{
final Location location = entity.getLocation();
Location target = location.clone();
for (int z = this.punishLevel; z >= -this.punishLevel; z--)
{
for (int x = this.punishLevel; x >= -this.punishLevel; x--)
{
for (int y = this.punishLevel; y >= -this.punishLevel; y--)
{
target.setX(location.getX() + x);
target.setY(location.getY() + y);
target.setZ(location.getZ() + z);
if (this.hypnoAffectLandscape && target.getBlock().isEmpty())
{
continue;
}
target = location.clone();
target.add(x, y, z);
Player plr = ((Player) entity);
BlockData bd = BukkitAdapter.adapt(BlockState.get(v.getVoxelId() + (v.getPropertyId() << BlockTypes.BIT_OFFSET)));
plr.sendBlockChange(target, bd);
}
}
}
}
break;
default:
Bukkit.getLogger().warning("Could not determine the punishment of punish brush!");
break;
}
}
@Override
protected final void arrow(final SnipeData v)
{
if (!v.owner().getPlayer().hasPermission("voxelsniper.punish"))
{
v.sendMessage("The server says no!");
return;
}
this.punishDuration = v.getVoxelHeight();
this.punishLevel = v.getcCen();
if (this.specificPlayer)
{
final Player punishedPlayer = Bukkit.getPlayer(this.punishPlayerName);
if (punishedPlayer == null)
{
v.sendMessage("No player " + this.punishPlayerName + " found.");
return;
}
this.applyPunishment(punishedPlayer, v);
return;
}
final int brushSizeSquare = v.getBrushSize() * v.getBrushSize();
final Location targetLocation = new Location(v.getWorld(), this.getTargetBlock().getX(), this.getTargetBlock().getY(), this.getTargetBlock().getZ());
final List<LivingEntity> entities = v.getWorld().getLivingEntities();
int numPunishApps = 0;
for (final LivingEntity entity : entities)
{
if (v.owner().getPlayer() != entity || hitsSelf)
{
if (v.getBrushSize() >= 0)
{
try
{
if (entity.getLocation().distanceSquared(targetLocation) <= brushSizeSquare)
{
numPunishApps++;
this.applyPunishment(entity, v);
}
}
catch (final Exception exception)
{
exception.printStackTrace();
v.sendMessage("An error occured.");
return;
}
}
else if (v.getBrushSize() == PunishBrush.INFINIPUNISH_SIZE)
{
numPunishApps++;
this.applyPunishment(entity, v);
}
}
}
v.sendMessage(ChatColor.DARK_RED + "Punishment applied to " + numPunishApps + " living entities.");
}
@Override
protected final void powder(final SnipeData v)
{
if (!v.owner().getPlayer().hasPermission("voxelsniper.punish"))
{
v.sendMessage("The server says no!");
return;
}
final int brushSizeSquare = v.getBrushSize() * v.getBrushSize();
final Location targetLocation = new Location(v.getWorld(), this.getTargetBlock().getX(), this.getTargetBlock().getY(), this.getTargetBlock().getZ());
final List<LivingEntity> entities = v.getWorld().getLivingEntities();
for (final LivingEntity entity : entities)
{
if (entity.getLocation().distanceSquared(targetLocation) < brushSizeSquare)
{
entity.setFireTicks(0);
entity.removePotionEffect(PotionEffectType.BLINDNESS);
entity.removePotionEffect(PotionEffectType.CONFUSION);
entity.removePotionEffect(PotionEffectType.SLOW);
entity.removePotionEffect(PotionEffectType.JUMP);
}
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.GREEN + "Punishment: " + this.punishment.toString());
vm.size();
vm.center();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i].toLowerCase();
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Punish Brush Options:");
v.sendMessage(ChatColor.AQUA + "Punishments can be set via /b p [punishment]");
v.sendMessage(ChatColor.AQUA + "Punishment level can be set with /vc [level]");
v.sendMessage(ChatColor.AQUA + "Punishment duration in seconds can be set with /vh [duration]");
v.sendMessage(ChatColor.AQUA + "Parameter -toggleHypnoLandscape will make Hypno punishment only affect landscape.");
v.sendMessage(ChatColor.AQUA + "Parameter -toggleSM [playername] will make punishbrush only affect that player.");
v.sendMessage(ChatColor.AQUA + "Parameter -toggleSelf will toggle whether you get hit as well.");
v.sendMessage(ChatColor.AQUA + "Available Punishment Options:");
final StringBuilder punishmentOptions = new StringBuilder();
for (final Punishment punishment : Punishment.values())
{
if (punishmentOptions.length() != 0)
{
punishmentOptions.append(" | ");
}
punishmentOptions.append(punishment.name());
}
v.sendMessage(ChatColor.GOLD + punishmentOptions.toString());
return;
}
else if (parameter.equalsIgnoreCase("-toggleSM"))
{
this.specificPlayer = !this.specificPlayer;
if (this.specificPlayer)
{
try
{
this.punishPlayerName = par[++i];
}
catch (final IndexOutOfBoundsException exception)
{
v.sendMessage(ChatColor.AQUA + "You have to specify a player name after -toggleSM if you want to turn the specific player feature on.");
}
}
}
else if (parameter.equalsIgnoreCase("-toggleSelf"))
{
this.hitsSelf = !this.hitsSelf;
if (hitsSelf)
{
v.sendMessage(ChatColor.AQUA + "Your punishments will now affect you too!");
}
else
{
v.sendMessage(ChatColor.AQUA + "Your punishments will no longer affect you!");
}
}
else if (parameter.equalsIgnoreCase("-toggleHypnoLandscape"))
{
this.hypnoAffectLandscape = !this.hypnoAffectLandscape;
}
else
{
try
{
this.punishment = Punishment.valueOf(parameter.toUpperCase());
v.sendMessage(ChatColor.AQUA + this.punishment.name().toLowerCase() + " punishment selected.");
}
catch (final IllegalArgumentException exception)
{
v.sendMessage(ChatColor.AQUA + "No such Punishment.");
}
}
}
}
/**
* @author Monofraps
*/
private enum Punishment
{
// Monofraps
FIRE, LIGHTNING, BLINDNESS, DRUNK, KILL, RANDOMTP, ALL_POTION,
// Deamon
SLOW, JUMP, ABSORPTION, DAMAGE_RESISTANCE, FAST_DIGGING, FIRE_RESISTANCE, HEAL, HEALTH_BOOST, HUNGER, INCREASE_DAMAGE, INVISIBILITY, NIGHT_VISION, POISON, REGENERATION,
SATURATION, SLOW_DIGGING, SPEED, WATER_BREATHING, WEAKNESS, WITHER,
// MikeMatrix
FORCE, HYPNO
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.punish";
}
}

Datei anzeigen

@ -0,0 +1,470 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.block.Block;
import java.util.Random;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Random-Erode_Brush
*
* @author Piotr
* @author Giltwist (Randomized blockPositionY)
*/
public class RandomErodeBrush extends Brush
{
private final double trueCircle = 0.5;
private BlockWrapper[][][] snap;
private BlockWrapper[][][] firstSnap;
private int bsize;
private int erodeFace;
private int fillFace;
private int brushSize;
private int erodeRecursion = 1;
private int fillRecursion = 1;
private Random generator = new Random();
/**
*
*/
public RandomErodeBrush()
{
this.setName("RandomErode");
}
private boolean erode(final int x, final int y, final int z)
{
if (this.snap[x][y][z].isSolid())
{
int d = 0;
if (!this.snap[x + 1][y][z].isSolid())
{
d++;
}
if (!this.snap[x - 1][y][z].isSolid())
{
d++;
}
if (!this.snap[x][y + 1][z].isSolid())
{
d++;
}
if (!this.snap[x][y - 1][z].isSolid())
{
d++;
}
if (!this.snap[x][y][z + 1].isSolid())
{
d++;
}
if (!this.snap[x][y][z - 1].isSolid())
{
d++;
}
return (d >= this.erodeFace);
}
else
{
return false;
}
}
@SuppressWarnings("deprecation")
private boolean fill(final int x, final int y, final int z)
{
if (this.snap[x][y][z].isSolid())
{
return false;
}
else
{
int d = 0;
if (this.snap[x + 1][y][z].isSolid())
{
this.snap[x][y][z].setId(this.snap[x + 1][y][z].getNativeBlock().getTypeId());
d++;
}
if (this.snap[x - 1][y][z].isSolid())
{
this.snap[x][y][z].setId(this.snap[x - 1][y][z].getNativeBlock().getTypeId());
d++;
}
if (this.snap[x][y + 1][z].isSolid())
{
this.snap[x][y][z].setId(this.snap[x][y + 1][z].getNativeBlock().getTypeId());
d++;
}
if (this.snap[x][y - 1][z].isSolid())
{
this.snap[x][y][z].setId(this.snap[x][y - 1][z].getNativeBlock().getTypeId());
d++;
}
if (this.snap[x][y][z + 1].isSolid())
{
this.snap[x][y][z].setId(this.snap[x][y][z + 1].getNativeBlock().getTypeId());
d++;
}
if (this.snap[x][y][z - 1].isSolid())
{
this.snap[x][y][z].setId(this.snap[x][y][z - 1].getNativeBlock().getTypeId());
d++;
}
return (d >= this.fillFace);
}
}
private void getMatrix()
{
this.brushSize = ((this.bsize + 1) * 2) + 1;
if (this.snap.length == 0)
{
this.snap = new BlockWrapper[this.brushSize][this.brushSize][this.brushSize];
int sx = this.getTargetBlock().getX() - (this.bsize + 1);
int sy = this.getTargetBlock().getY() - (this.bsize + 1);
int sz = this.getTargetBlock().getZ() - (this.bsize + 1);
for (int x = 0; x < this.snap.length; x++)
{
sz = this.getTargetBlock().getZ() - (this.bsize + 1);
for (int z = 0; z < this.snap.length; z++)
{
sy = this.getTargetBlock().getY() - (this.bsize + 1);
for (int y = 0; y < this.snap.length; y++)
{
this.snap[x][y][z] = new BlockWrapper(this.clampY(sx, sy, sz));
sy++;
}
sz++;
}
sx++;
}
this.firstSnap = this.snap.clone();
}
else
{
this.snap = new BlockWrapper[this.brushSize][this.brushSize][this.brushSize];
int sx = this.getTargetBlock().getX() - (this.bsize + 1);
int sy = this.getTargetBlock().getY() - (this.bsize + 1);
int sz = this.getTargetBlock().getZ() - (this.bsize + 1);
for (int x = 0; x < this.snap.length; x++)
{
sz = this.getTargetBlock().getZ() - (this.bsize + 1);
for (int z = 0; z < this.snap.length; z++)
{
sy = this.getTargetBlock().getY() - (this.bsize + 1);
for (int y = 0; y < this.snap.length; y++)
{
this.snap[x][y][z] = new BlockWrapper(this.clampY(sx, sy, sz));
sy++;
}
sz++;
}
sx++;
}
}
}
@SuppressWarnings("deprecation")
private void rerosion(final SnipeData v)
{
final Undo undo = new Undo();
if (this.erodeFace >= 0 && this.erodeFace <= 6)
{
for (int currentErodeRecursion = 0; currentErodeRecursion < this.erodeRecursion; currentErodeRecursion++)
{
this.getMatrix();
final double brushSizeSquared = Math.pow(this.bsize + this.trueCircle, 2);
for (int z = 1; z < this.snap.length - 1; z++)
{
final double zSquared = Math.pow(z - (this.bsize + 1), 2);
for (int x = 1; x < this.snap.length - 1; x++)
{
final double xSquared = Math.pow(x - (this.bsize + 1), 2);
for (int y = 1; y < this.snap.length - 1; y++)
{
if (((xSquared + Math.pow(y - (this.bsize + 1), 2) + zSquared) <= brushSizeSquared))
{
if (this.erode(x, y, z))
{
this.snap[x][y][z].getNativeBlock().setTypeId(0);
}
}
}
}
}
}
}
if (this.fillFace >= 0 && this.fillFace <= 6)
{
final double brushSizeSquared = Math.pow(this.bsize + 0.5, 2);
for (int currentFillRecursion = 0; currentFillRecursion < this.fillRecursion; currentFillRecursion++)
{
this.getMatrix();
for (int z = 1; z < this.snap.length - 1; z++)
{
final double zSquared = Math.pow(z - (this.bsize + 1), 2);
for (int x = 1; x < this.snap.length - 1; x++)
{
final double xSquared = Math.pow(x - (this.bsize + 1), 2);
for (int y = 1; y < this.snap.length - 1; y++)
{
if (((xSquared + Math.pow(y - (this.bsize + 1), 2) + zSquared) <= brushSizeSquared))
{
if (this.fill(x, y, z))
{
this.snap[x][y][z].getNativeBlock().setTypeId(this.snap[x][y][z].getId());
}
}
}
}
}
}
}
for (BlockWrapper[][] firstSnapSlice : this.firstSnap)
{
for (BlockWrapper[] firstSnapString : firstSnapSlice)
{
for (final BlockWrapper block : firstSnapString)
{
if (block.getI() != block.getNativeBlock().getTypeId())
{
undo.put(block.getNativeBlock());
}
}
}
}
v.owner().storeUndo(undo);
}
@SuppressWarnings("deprecation")
private void rfilling(final SnipeData v)
{
final Undo undo = new Undo();
if (this.fillFace >= 0 && this.fillFace <= 6)
{
final double bSquared = Math.pow(this.bsize + 0.5, 2);
for (int currentFillRecursion = 0; currentFillRecursion < this.fillRecursion; currentFillRecursion++)
{
this.getMatrix();
for (int z = 1; z < this.snap.length - 1; z++)
{
final double zSquared = Math.pow(z - (this.bsize + 1), 2);
for (int x = 1; x < this.snap.length - 1; x++)
{
final double xSquared = Math.pow(x - (this.bsize + 1), 2);
for (int y = 1; y < this.snap.length - 1; y++)
{
if (((xSquared + Math.pow(y - (this.bsize + 1), 2) + zSquared) <= bSquared))
{
if (this.fill(x, y, z))
{
this.snap[x][y][z].getNativeBlock().setTypeId(this.snap[x][y][z].getId());
}
}
}
}
}
}
}
if (this.erodeFace >= 0 && this.erodeFace <= 6)
{
final double bSquared = Math.pow(this.bsize + this.trueCircle, 2);
for (int currentErodeRecursion = 0; currentErodeRecursion < this.erodeRecursion; currentErodeRecursion++)
{
this.getMatrix();
for (int z = 1; z < this.snap.length - 1; z++)
{
final double zSquared = Math.pow(z - (this.bsize + 1), 2);
for (int x = 1; x < this.snap.length - 1; x++)
{
final double xSquared = Math.pow(x - (this.bsize + 1), 2);
for (int y = 1; y < this.snap.length - 1; y++)
{
if (((xSquared + Math.pow(y - (this.bsize + 1), 2) + zSquared) <= bSquared))
{
if (this.erode(x, y, z))
{
this.snap[x][y][z].getNativeBlock().setTypeId(0);
}
}
}
}
}
}
}
for (BlockWrapper[][] firstSnapSlice : this.firstSnap)
{
for (BlockWrapper[] firstSnapString : firstSnapSlice)
{
for (final BlockWrapper block : firstSnapString)
{
if (block.getI() != block.getNativeBlock().getTypeId())
{
undo.put(block.getNativeBlock());
}
}
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
this.bsize = v.getBrushSize();
this.snap = new BlockWrapper[0][0][0];
this.erodeFace = this.generator.nextInt(5) + 1;
this.fillFace = this.generator.nextInt(3) + 3;
this.erodeRecursion = this.generator.nextInt(3);
this.fillRecursion = this.generator.nextInt(3);
if (this.fillRecursion == 0 && this.erodeRecursion == 0)
{ // if they are both zero, it will lead to a null pointer exception. Still want to give them a
// chance to be zero though, for more interestingness -Gav
this.erodeRecursion = this.generator.nextInt(2) + 1;
this.fillRecursion = this.generator.nextInt(2) + 1;
}
this.rerosion(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.bsize = v.getBrushSize();
this.snap = new BlockWrapper[0][0][0];
this.erodeFace = this.generator.nextInt(3) + 3;
this.fillFace = this.generator.nextInt(5) + 1;
this.erodeRecursion = this.generator.nextInt(3);
this.fillRecursion = this.generator.nextInt(3);
if (this.fillRecursion == 0 && this.erodeRecursion == 0)
{ // if they are both zero, it will lead to a null pointer exception. Still want to give them a
// chance to be zero though, for more interestingness -Gav
this.erodeRecursion = this.generator.nextInt(2) + 1;
this.fillRecursion = this.generator.nextInt(2) + 1;
}
this.rfilling(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
/**
* @author unknown
*/
private class BlockWrapper
{
private boolean solid;
private AsyncBlock nativeBlock;
private int id;
private int i;
/**
* @param bl
*/
@SuppressWarnings("deprecation")
public BlockWrapper(final AsyncBlock bl)
{
this.setNativeBlock(bl);
this.setI(bl.getTypeId());
switch (bl.getType())
{
case AIR:
this.setSolid(false);
break;
case WATER:
this.setSolid(false);
break;
case LAVA:
this.setSolid(false);
break;
default:
this.setSolid(true);
}
}
public boolean isSolid()
{
return solid;
}
public void setSolid(boolean solid)
{
this.solid = solid;
}
public AsyncBlock getNativeBlock()
{
return nativeBlock;
}
public void setNativeBlock(AsyncBlock nativeBlock)
{
this.nativeBlock = nativeBlock;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public int getI()
{
return i;
}
public void setI(int i)
{
this.i = i;
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.randomerode";
}
}

Datei anzeigen

@ -0,0 +1,70 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.Chunk;
/**
* Regenerates the target chunk.
*
* @author Mick
*/
public class RegenerateChunkBrush extends Brush
{
/**
*
*/
public RegenerateChunkBrush()
{
this.setName("Chunk Generator 40k");
}
private void generateChunk(final SnipeData v)
{
final Chunk chunk = this.getTargetBlock().getChunk();
final Undo undo = new Undo();
for (int z = CHUNK_SIZE; z >= 0; z--)
{
for (int x = CHUNK_SIZE; x >= 0; x--)
{
for (int y = this.getWorld().getMaxHeight(); y >= 0; y--)
{
undo.put(chunk.getBlock(x, y, z));
}
}
}
v.owner().storeUndo(undo);
v.sendMessage("Generate that chunk! " + chunk.getX() + " " + chunk.getZ());
this.getWorld().regenerateChunk(chunk.getX(), chunk.getZ());
this.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
}
@Override
protected final void arrow(final SnipeData v)
{
this.generateChunk(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.generateChunk(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.brushMessage("Tread lightly.");
vm.brushMessage("This brush will melt your spleen and sell your kidneys.");
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.regeneratechunk";
}
}

Datei anzeigen

@ -0,0 +1,120 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Ring_Brush
*
* @author Voxel
*/
public class RingBrush extends PerformBrush
{
private double trueCircle = 0;
private double innerSize = 0;
/**
*
*/
public RingBrush()
{
this.setName("Ring");
}
private void ring(final SnipeData v, AsyncBlock targetBlock)
{
final int brushSize = v.getBrushSize();
final double outerSquared = Math.pow(brushSize + this.trueCircle, 2);
final double innerSquared = Math.pow(this.innerSize, 2);
for (int x = brushSize; x >= 0; x--)
{
final double xSquared = Math.pow(x, 2);
for (int z = brushSize; z >= 0; z--)
{
final double ySquared = Math.pow(z, 2);
if ((xSquared + ySquared) <= outerSquared && (xSquared + ySquared) >= innerSquared)
{
current.perform(targetBlock.getRelative(x, 0, z));
current.perform(targetBlock.getRelative(x, 0, -z));
current.perform(targetBlock.getRelative(-x, 0, z));
current.perform(targetBlock.getRelative(-x, 0, -z));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.ring(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.ring(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.custom(ChatColor.AQUA + "The inner radius is " + ChatColor.RED + this.innerSize);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
if (par[i].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Ring Brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b ri true -- will use a true circle algorithm instead of the skinnier version with classic sniper nubs. /b ri false will switch back. (false is default)");
v.sendMessage(ChatColor.AQUA + "/b ri ir2.5 -- will set the inner radius to 2.5 units");
return;
}
else if (par[i].startsWith("true"))
{
this.trueCircle = 0.5;
v.sendMessage(ChatColor.AQUA + "True circle mode ON.");
}
else if (par[i].startsWith("false"))
{
this.trueCircle = 0;
v.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
}
else if (par[i].startsWith("ir"))
{
try
{
final double d = Double.parseDouble(par[i].replace("ir", ""));
this.innerSize = d;
v.sendMessage(ChatColor.AQUA + "The inner radius has been set to " + ChatColor.RED + this.innerSize);
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "The parameters included are invalid.");
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.ring";
}
}

Datei anzeigen

@ -0,0 +1,214 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.util.BlockWrapper;
import org.bukkit.ChatColor;
/**
* @author Piotr
*/
public class Rot2DBrush extends Brush
{
private int mode = 0;
private int bSize;
private int brushSize;
private BlockWrapper[][][] snap;
private double se;
/**
*
*/
public Rot2DBrush()
{
this.setName("2D Rotation");
}
@SuppressWarnings("deprecation")
private void getMatrix()
{
this.brushSize = (this.bSize * 2) + 1;
this.snap = new BlockWrapper[this.brushSize][this.brushSize][this.brushSize];
final double brushSizeSquared = Math.pow(this.bSize + 0.5, 2);
int sx = this.getTargetBlock().getX() - this.bSize;
int sy = this.getTargetBlock().getY() - this.bSize;
int sz = this.getTargetBlock().getZ() - this.bSize;
for (int x = 0; x < this.snap.length; x++)
{
sz = this.getTargetBlock().getZ() - this.bSize;
final double xSquared = Math.pow(x - this.bSize, 2);
for (int y = 0; y < this.snap.length; y++)
{
sy = this.getTargetBlock().getY() - this.bSize;
if (xSquared + Math.pow(y - this.bSize, 2) <= brushSizeSquared)
{
for (int z = 0; z < this.snap.length; z++)
{
final AsyncBlock block = this.clampY(sx, sy, sz); // why is this not sx + x, sy + y sz + z?
this.snap[x][z][y] = new BlockWrapper(block);
block.setTypeId(0);
sy++;
}
}
sz++;
}
sx++;
}
}
private void rotate(final SnipeData v)
{
final double brushSiyeSquared = Math.pow(this.bSize + 0.5, 2);
final double cos = Math.cos(this.se);
final double sin = Math.sin(this.se);
final boolean[][] doNotFill = new boolean[this.snap.length][this.snap.length];
// I put y in the inside loop, since it doesn't have any power functions, should be much faster.
// Also, new array keeps track of which x and z coords are being assigned in the rotated space so that we can
// do a targeted filling of only those columns later that were left out.
for (int x = 0; x < this.snap.length; x++)
{
final int xx = x - this.bSize;
final double xSquared = Math.pow(xx, 2);
for (int y = 0; y < this.snap.length; y++)
{
final int zz = y - this.bSize;
if (xSquared + Math.pow(zz, 2) <= brushSiyeSquared)
{
final double newX = (xx * cos) - (zz * sin);
final double newZ = (xx * sin) + (zz * cos);
doNotFill[(int) newX + this.bSize][(int) newZ + this.bSize] = true;
for (int currentY = 0; currentY < this.snap.length; currentY++)
{
final int yy = currentY - this.bSize;
final BlockWrapper block = this.snap[x][currentY][y];
if (block.getId() == 0)
{
continue;
}
this.setBlockIdAndDataAt(this.getTargetBlock().getX() + (int) newX, this.getTargetBlock().getY() + yy, this.getTargetBlock().getZ() + (int) newZ, block.getId(), block.getPropertyId());
}
}
}
}
for (int x = 0; x < this.snap.length; x++)
{
final double xSquared = Math.pow(x - this.bSize, 2);
final int fx = x + this.getTargetBlock().getX() - this.bSize;
for (int z = 0; z < this.snap.length; z++)
{
if (xSquared + Math.pow(z - this.bSize, 2) <= brushSiyeSquared)
{
final int fz = z + this.getTargetBlock().getZ() - this.bSize;
if (!doNotFill[x][z])
{
// smart fill stuff
for (int y = 0; y < this.snap.length; y++)
{
final int fy = y + this.getTargetBlock().getY() - this.bSize;
final int a = this.getBlockIdAt(fx + 1, fy, fz);
final int aData = this.getBlockDataAt(fx + 1, fy, fz);
final int d = this.getBlockIdAt(fx - 1, fy, fz);
final int dData = this.getBlockDataAt(fx - 1, fy, fz);
final int c = this.getBlockIdAt(fx, fy, fz + 1);
final int b = this.getBlockIdAt(fx, fy, fz - 1);
final int bData = this.getBlockDataAt(fx, fy, fz - 1);
int winner;
int winnerData;
if (a == b || a == c || a == d)
{ // I figure that since we are already narrowing it down to ONLY the holes left behind, it
// should
// be fine to do all 5 checks needed to be legit about it.
winner = a;
winnerData = aData;
}
else if (b == d || c == d)
{
winner = d;
winnerData = dData;
}
else
{
winner = b; // blockPositionY making this default, it will also automatically cover situations where B = C;
winnerData = bData;
}
this.setBlockIdAndDataAt(fx, fy, fz, winner, winnerData);
}
}
}
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.bSize = v.getBrushSize();
switch (this.mode)
{
case 0:
this.getMatrix();
this.rotate(v);
break;
default:
v.sendMessage(ChatColor.RED + "Something went wrong.");
break;
}
}
@Override
protected final void powder(final SnipeData v)
{
this.bSize = v.getBrushSize();
switch (this.mode)
{
case 0:
this.getMatrix();
this.rotate(v);
break;
default:
v.sendMessage(ChatColor.RED + "Something went wrong.");
break;
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
this.se = Math.toRadians(Double.parseDouble(par[1]));
v.sendMessage(ChatColor.GREEN + "Angle set to " + this.se);
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.rot2d";
}
}

Datei anzeigen

@ -0,0 +1,223 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.util.BlockWrapper;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
/**
* @author Gavjenks, hack job from the other 2d rotation brush blockPositionY piotr
*/
// The X Y and Z variable names in this file do NOT MAKE ANY SENSE. Do not attempt to actually figure out what on earth is going on here. Just go to the
// original 2d horizontal brush if you wish to make anything similar to this, and start there. I didn't bother renaming everything.
public class Rot2DvertBrush extends Brush
{
private int mode = 0;
private int bSize;
private int brushSize;
private BlockWrapper[][][] snap;
private double se;
/**
*
*/
public Rot2DvertBrush()
{
this.setName("2D Rotation");
}
@SuppressWarnings("deprecation")
private void getMatrix()
{
this.brushSize = (this.bSize * 2) + 1;
this.snap = new BlockWrapper[this.brushSize][this.brushSize][this.brushSize];
int sx = this.getTargetBlock().getX() - this.bSize;
int sy = this.getTargetBlock().getY() - this.bSize;
int sz = this.getTargetBlock().getZ() - this.bSize;
for (int x = 0; x < this.snap.length; x++)
{
sz = this.getTargetBlock().getZ() - this.bSize;
for (int z = 0; z < this.snap.length; z++)
{
sy = this.getTargetBlock().getY() - this.bSize;
for (int y = 0; y < this.snap.length; y++)
{
final AsyncBlock block = this.clampY(sx, sy, sz); // why is this not sx + x, sy + y sz + z?
this.snap[x][y][z] = new BlockWrapper(block);
block.setTypeId(0);
sy++;
}
sz++;
}
sx++;
}
}
private void rotate(final SnipeData v)
{
final double brushSizeSquared = Math.pow(this.bSize + 0.5, 2);
final double cos = Math.cos(this.se);
final double sin = Math.sin(this.se);
final boolean[][] doNotFill = new boolean[this.snap.length][this.snap.length];
// I put y in the inside loop, since it doesn't have any power functions, should be much faster.
// Also, new array keeps track of which x and z coords are being assigned in the rotated space so that we can
// do a targeted filling of only those columns later that were left out.
for (int x = 0; x < this.snap.length; x++)
{
final int xx = x - this.bSize;
final double xSquared = Math.pow(xx, 2);
for (int z = 0; z < this.snap.length; z++)
{
final int zz = z - this.bSize;
if (xSquared + Math.pow(zz, 2) <= brushSizeSquared)
{
final double newX = (xx * cos) - (zz * sin);
final double newZ = (xx * sin) + (zz * cos);
doNotFill[(int) newX + this.bSize][(int) newZ + this.bSize] = true;
for (int y = 0; y < this.snap.length; y++)
{
final int yy = y - this.bSize;
final BlockWrapper block = this.snap[y][x][z];
if (block.getId() == 0)
{
continue;
}
this.setBlockIdAndDataAt(this.getTargetBlock().getX() + yy, this.getTargetBlock().getY() + (int) newX, this.getTargetBlock().getZ() + (int) newZ, block.getId(), block.getPropertyId());
}
}
}
}
for (int x = 0; x < this.snap.length; x++)
{
final double xSquared = Math.pow(x - this.bSize, 2);
final int fx = x + this.getTargetBlock().getX() - this.bSize;
for (int z = 0; z < this.snap.length; z++)
{
if (xSquared + Math.pow(z - this.bSize, 2) <= brushSizeSquared)
{
final int fz = z + this.getTargetBlock().getZ() - this.bSize;
if (!doNotFill[x][z])
{
// smart fill stuff
for (int y = 0; y < this.snap.length; y++)
{
final int fy = y + this.getTargetBlock().getY() - this.bSize;
final int a = this.getBlockIdAt(fy, fx + 1, fz);
final int aData = this.getBlockDataAt(fy, fx + 1, fz);
final int d = this.getBlockIdAt(fy, fx - 1, fz);
final int dData = this.getBlockDataAt(fy, fx - 1, fz);
final int c = this.getBlockIdAt(fy, fx, fz + 1);
final int b = this.getBlockIdAt(fy, fx, fz - 1);
final int bData = this.getBlockDataAt(fy, fx, fz - 1);
int winner;
int winnerData;
if (a == b || a == c || a == d)
{ // I figure that since we are already narrowing it down to ONLY the holes left behind, it
// should
// be fine to do all 5 checks needed to be legit about it.
winner = a;
winnerData = aData;
}
else if (b == d || c == d)
{
winner = d;
winnerData = dData;
}
else
{
winner = b; // blockPositionY making this default, it will also automatically cover situations where B = C;
winnerData = bData;
}
this.setBlockIdAndDataAt(fy, fx, fz, winner, winnerData);
}
}
}
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.bSize = v.getBrushSize();
switch (this.mode)
{
case 0:
this.getMatrix();
this.rotate(v);
break;
default:
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
break;
}
}
@Override
protected final void powder(final SnipeData v)
{
this.bSize = v.getBrushSize();
switch (this.mode)
{
case 0:
this.getMatrix();
this.rotate(v);
break;
default:
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
break;
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
try
{
this.se = Math.toRadians(Double.parseDouble(par[1]));
v.sendMessage(ChatColor.GREEN + "Angle set to " + this.se);
}
catch (Exception _ex)
{
v.sendMessage("Exception while parsing parameter: " + par[1]);
Bukkit.getLogger().severe(_ex.getMessage());
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.rot2dvert";
}
}

Datei anzeigen

@ -0,0 +1,286 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import com.thevoxelbox.voxelsniper.util.BlockWrapper;
import org.bukkit.ChatColor;
/**
*
*/
public class Rot3DBrush extends Brush
{
private final int mode = 0;
private int bSize;
private int brushSize;
private BlockWrapper[][][] snap;
private double seYaw;
private double sePitch;
private double seRoll;
/**
*
*/
public Rot3DBrush()
{
this.setName("3D Rotation");
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.brushMessage("Rotates Yaw (XZ), then Pitch(XY), then Roll(ZY), in order.");
}
// after all rotations, compare snapshot to new state of world, and store changed blocks to undo?
// --> agreed. Do what erode does and store one snapshot with Block pointers and int id of what the block started with, afterwards simply go thru that
// matrix and compare Block.getId with 'id' if different undo.add( new BlockWrapper ( Block, oldId ) )
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
// which way is clockwise is less obvious for roll and pitch... should probably fix that / make it clear
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Rotate brush Parameters:");
v.sendMessage(ChatColor.AQUA + "p[0-359] -- set degrees of pitch rotation (rotation about the Z axis).");
v.sendMessage(ChatColor.BLUE + "r[0-359] -- set degrees of roll rotation (rotation about the X axis).");
v.sendMessage(ChatColor.LIGHT_PURPLE + "y[0-359] -- set degrees of yaw rotation (Rotation about the Y axis).");
return;
}
else if (parameter.startsWith("p"))
{
this.sePitch = Math.toRadians(Double.parseDouble(parameter.replace("p", "")));
v.sendMessage(ChatColor.AQUA + "Around Z-axis degrees set to " + this.sePitch);
if (this.sePitch < 0 || this.sePitch > 359)
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! Angles must be from 1-359");
}
}
else if (parameter.startsWith("r"))
{
this.seRoll = Math.toRadians(Double.parseDouble(parameter.replace("r", "")));
v.sendMessage(ChatColor.AQUA + "Around X-axis degrees set to " + this.seRoll);
if (this.seRoll < 0 || this.seRoll > 359)
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! Angles must be from 1-359");
}
}
else if (parameter.startsWith("y"))
{
this.seYaw = Math.toRadians(Double.parseDouble(parameter.replace("y", "")));
v.sendMessage(ChatColor.AQUA + "Around Y-axis degrees set to " + this.seYaw);
if (this.seYaw < 0 || this.seYaw > 359)
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! Angles must be from 1-359");
}
}
}
}
@SuppressWarnings("deprecation")
private void getMatrix()
{ // only need to do once. But y needs to change + sphere
final double brushSizeSquared = Math.pow(this.bSize + 0.5, 2);
this.brushSize = (this.bSize * 2) + 1;
this.snap = new BlockWrapper[this.brushSize][this.brushSize][this.brushSize];
int sx = this.getTargetBlock().getX() - this.bSize;
//int sy = this.getTargetBlock().getY() - this.bSize; Not used
int sz = this.getTargetBlock().getZ() - this.bSize;
for (int x = 0; x < this.snap.length; x++)
{
final double xSquared = Math.pow(x - this.bSize, 2);
sz = this.getTargetBlock().getZ() - this.bSize;
for (int z = 0; z < this.snap.length; z++)
{
final double zSquared = Math.pow(z - this.bSize, 2);
sz = this.getTargetBlock().getY() - this.bSize;
for (int y = 0; y < this.snap.length; y++)
{
if (xSquared + zSquared + Math.pow(y - this.bSize, 2) <= brushSizeSquared)
{
final AsyncBlock block = this.clampY(sx, sz, sz);
this.snap[x][y][z] = new BlockWrapper(block);
block.setTypeId(0);
sz++;
}
}
sz++;
}
sx++;
}
}
private void rotate(final SnipeData v)
{
// basically 1) make it a sphere we are rotating in, not a cylinder
// 2) do three rotations in a row, one in each dimension, unless some dimensions are set to zero or udnefined or whatever, then skip those.
// --> Why not utilize Sniper'world new oportunities and have arrow rotate all 3, powder rotate x, goldsisc y, otherdisc z. Or something like that. Or
// we
// could just use arrow and powder and just differenciate between left and right click that gis 4 different situations
// --> Well, there would be 7 different possibilities... X, Y, Z, XY, XZ, YZ, XYZ, and different numbers of parameters for each, so I think each having
// and item is too confusing. How about this: arrow = rotate one dimension, based on the face you click, and takes 1 param... powder: rotates all three
// at once, and takes 3 params.
final double brushSizeSquared = Math.pow(this.bSize + 0.5, 2);
final double cosYaw = Math.cos(this.seYaw);
final double sinYaw = Math.sin(this.seYaw);
final double cosPitch = Math.cos(this.sePitch);
final double sinPitch = Math.sin(this.sePitch);
final double cosRoll = Math.cos(this.seRoll);
final double sinRoll = Math.sin(this.seRoll);
final boolean[][][] doNotFill = new boolean[this.snap.length][this.snap.length][this.snap.length];
final Undo undo = new Undo();
for (int x = 0; x < this.snap.length; x++)
{
final int xx = x - this.bSize;
final double xSquared = Math.pow(xx, 2);
for (int z = 0; z < this.snap.length; z++)
{
final int zz = z - this.bSize;
final double zSquared = Math.pow(zz, 2);
final double newxzX = (xx * cosYaw) - (zz * sinYaw);
final double newxzZ = (xx * sinYaw) + (zz * cosYaw);
for (int y = 0; y < this.snap.length; y++)
{
final int yy = y - this.bSize;
if (xSquared + zSquared + Math.pow(yy, 2) <= brushSizeSquared)
{
undo.put(this.clampY(this.getTargetBlock().getX() + xx, this.getTargetBlock().getY() + yy, this.getTargetBlock().getZ() + zz)); // just store
// whole sphere in undo, too complicated otherwise, since this brush both adds and remos things unpredictably.
final double newxyX = (newxzX * cosPitch) - (yy * sinPitch);
final double newxyY = (newxzX * sinPitch) + (yy * cosPitch); // calculates all three in succession in precise math space
final double newyzY = (newxyY * cosRoll) - (newxzZ * sinRoll);
final double newyzZ = (newxyY * sinRoll) + (newxzZ * cosRoll);
doNotFill[(int) newxyX + this.bSize][(int) newyzY + this.bSize][(int) newyzZ + this.bSize] = true; // only rounds off to nearest
// block
// after all three, though.
final BlockWrapper block = this.snap[x][y][z];
if (block.getId() == 0)
{
continue;
}
this.setBlockIdAndDataAt(this.getTargetBlock().getX() + (int) newxyX, this.getTargetBlock().getY() + (int) newyzY, this.getTargetBlock().getZ() + (int) newyzZ, block.getId(), block.getPropertyId());
}
}
}
}
for (int x = 0; x < this.snap.length; x++)
{
final double xSquared = Math.pow(x - this.bSize, 2);
final int fx = x + this.getTargetBlock().getX() - this.bSize;
for (int z = 0; z < this.snap.length; z++)
{
final double zSquared = Math.pow(z - this.bSize, 2);
final int fz = z + this.getTargetBlock().getZ() - this.bSize;
for (int y = 0; y < this.snap.length; y++)
{
if (xSquared + zSquared + Math.pow(y - this.bSize, 2) <= brushSizeSquared)
{
if (!doNotFill[x][y][z])
{
// smart fill stuff
final int fy = y + this.getTargetBlock().getY() - this.bSize;
final int a = this.getBlockIdAt(fx + 1, fy, fz);
final int aData = this.getBlockDataAt(fx + 1, fy, fz);
final int d = this.getBlockIdAt(fx - 1, fy, fz);
final int dData = this.getBlockDataAt(fx - 1, fy, fz);
final int c = this.getBlockIdAt(fx, fy, fz + 1);
final int b = this.getBlockIdAt(fx, fy, fz - 1);
final int bData = this.getBlockDataAt(fx, fy, fz - 1);
int winner;
int winnerData;
if (a == b || a == c || a == d)
{ // I figure that since we are already narrowing it down to ONLY the holes left behind, it
// should
// be fine to do all 5 checks needed to be legit about it.
winner = a;
winnerData = aData;
}
else if (b == d || c == d)
{
winner = d;
winnerData = dData;
}
else
{
winner = b; // blockPositionY making this default, it will also automatically cover situations where B = C;
winnerData = bData;
}
this.setBlockIdAndDataAt(fx, fy, fz, winner, winnerData);
}
}
}
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
this.bSize = v.getBrushSize();
switch (this.mode)
{
case 0:
this.getMatrix();
this.rotate(v);
break;
default:
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
break;
}
}
@Override
protected final void powder(final SnipeData v)
{
this.bSize = v.getBrushSize();
switch (this.mode)
{
case 0:
this.getMatrix();
this.rotate(v);
break;
default:
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
break;
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.rot3d";
}
}

Datei anzeigen

@ -0,0 +1,129 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.util.Vector;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Ruler_Brush
*
* @author Gavjenks
*/
public class RulerBrush extends Brush
{
private boolean first = true;
private Vector coords = new Vector(0, 0, 0);
private int xOff = 0;
private int yOff = 0;
private int zOff = 0;
/**
*
*/
public RulerBrush()
{
this.setName("Ruler");
}
@Override
protected final void arrow(final SnipeData v)
{
final int voxelMaterialId = v.getVoxelId();
this.coords = this.getTargetBlock().getLocation().toVector();
if (this.xOff == 0 && this.yOff == 0 && this.zOff == 0)
{
v.sendMessage(ChatColor.DARK_PURPLE + "First point selected.");
this.first = !this.first;
}
else
{
final Undo undo = new Undo();
undo.put(this.clampY(this.getTargetBlock().getX() + this.xOff, this.getTargetBlock().getY() + this.yOff, this.getTargetBlock().getZ() + this.zOff));
this.setBlockIdAt(this.getTargetBlock().getZ() + this.zOff, this.getTargetBlock().getX() + this.xOff, this.getTargetBlock().getY() + this.yOff, voxelMaterialId);
v.owner().storeUndo(undo);
}
}
@Override
protected final void powder(final SnipeData v)
{
if (this.coords == null || this.coords.lengthSquared() == 0)
{
v.sendMessage(ChatColor.RED + "Warning: You did not select a first coordinate with the arrow. Comparing to point 0,0,0 instead.");
return;
}
v.sendMessage(ChatColor.BLUE + "Format = (second coord - first coord)");
v.sendMessage(ChatColor.AQUA + "X change: " + (this.getTargetBlock().getX() - this.coords.getX()));
v.sendMessage(ChatColor.AQUA + "Y change: " + (this.getTargetBlock().getY() - this.coords.getY()));
v.sendMessage(ChatColor.AQUA + "Z change: " + (this.getTargetBlock().getZ() - this.coords.getZ()));
final double distance = (double) (Math.round(this.getTargetBlock().getLocation().toVector().subtract(this.coords).length() * 100) / 100);
final double blockDistance = (double) (Math.round((Math.abs(Math.max(Math.max(Math.abs(this.getTargetBlock().getX() - coords.getX()), Math.abs(this.getTargetBlock().getY() - this.coords.getY())), Math.abs(this.getTargetBlock().getZ() - this.coords.getZ()))) + 1) * 100) / 100);
v.sendMessage(ChatColor.AQUA + "Euclidean distance = " + distance);
v.sendMessage(ChatColor.AQUA + "Block distance = " + blockDistance);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.voxel();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Ruler Brush instructions: Right click first point with the arrow. Right click with powder for distances from that block (can repeat without getting a new first block.) For placing blocks, use arrow and input the desired coordinates with parameters.");
v.sendMessage(ChatColor.LIGHT_PURPLE + "/b r x[x value] y[y value] z[z value] -- Will place blocks one at a time of the type you have set with /v at the location you click + this many units away. If you don't include a value, it will be zero. Don't include ANY values, and the brush will just measure distance.");
v.sendMessage(ChatColor.BLUE + "/b r ruler -- will reset the tool to just measure distances, not layout blocks.");
return;
}
else if (parameter.startsWith("x"))
{
this.xOff = Integer.parseInt(parameter.replace("x", ""));
v.sendMessage(ChatColor.AQUA + "X offset set to " + this.xOff);
}
else if (parameter.startsWith("y"))
{
this.yOff = Integer.parseInt(parameter.replace("y", ""));
v.sendMessage(ChatColor.AQUA + "Y offset set to " + this.yOff);
}
else if (parameter.startsWith("z"))
{
this.zOff = Integer.parseInt(parameter.replace("z", ""));
v.sendMessage(ChatColor.AQUA + "Z offset set to " + this.zOff);
}
else if (parameter.startsWith("ruler"))
{
this.zOff = 0;
this.yOff = 0;
this.xOff = 0;
v.sendMessage(ChatColor.BLUE + "Ruler mode.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.ruler";
}
}

Datei anzeigen

@ -0,0 +1,200 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
/**
* @author DivineRage
*/
public class ScannerBrush extends Brush
{
private static final int DEPTH_MIN = 1;
private static final int DEPTH_DEFAULT = 24;
private static final int DEPTH_MAX = 64;
private int depth = DEPTH_DEFAULT;
private Material checkFor = Material.AIR;
/**
*
*/
public ScannerBrush()
{
this.setName("Scanner");
}
private int clamp(final int value, final int min, final int max)
{
if (value < min)
{
return min;
}
else if (value > max)
{
return max;
}
else
{
return value;
}
}
private void scan(final SnipeData v, final BlockFace bf)
{
if (bf == null)
{
return;
}
switch (bf)
{
case NORTH:
// Scan south
for (int i = 1; i < this.depth + 1; i++)
{
if (this.clampY(this.getTargetBlock().getX() + i, this.getTargetBlock().getY(), this.getTargetBlock().getZ()).getType() == this.checkFor)
{
v.sendMessage(ChatColor.GREEN + "" + this.checkFor + " found after " + i + " blocks.");
return;
}
}
v.sendMessage(ChatColor.GRAY + "Nope.");
break;
case SOUTH:
// Scan north
for (int i = 1; i < this.depth + 1; i++)
{
if (this.clampY(this.getTargetBlock().getX() - i, this.getTargetBlock().getY(), this.getTargetBlock().getZ()).getType() == this.checkFor)
{
v.sendMessage(ChatColor.GREEN + "" + this.checkFor + " found after " + i + " blocks.");
return;
}
}
v.sendMessage(ChatColor.GRAY + "Nope.");
break;
case EAST:
// Scan west
for (int i = 1; i < this.depth + 1; i++)
{
if (this.clampY(this.getTargetBlock().getX(), this.getTargetBlock().getY(), this.getTargetBlock().getZ() + i).getType() == this.checkFor)
{
v.sendMessage(ChatColor.GREEN + "" + this.checkFor + " found after " + i + " blocks.");
return;
}
}
v.sendMessage(ChatColor.GRAY + "Nope.");
break;
case WEST:
// Scan east
for (int i = 1; i < this.depth + 1; i++)
{
if (this.clampY(this.getTargetBlock().getX(), this.getTargetBlock().getY(), this.getTargetBlock().getZ() - i).getType() == this.checkFor)
{
v.sendMessage(ChatColor.GREEN + "" + this.checkFor + " found after " + i + " blocks.");
return;
}
}
v.sendMessage(ChatColor.GRAY + "Nope.");
break;
case UP:
// Scan down
for (int i = 1; i < this.depth + 1; i++)
{
if ((this.getTargetBlock().getY() - i) <= 0)
{
break;
}
if (this.clampY(this.getTargetBlock().getX(), this.getTargetBlock().getY() - i, this.getTargetBlock().getZ()).getType() == this.checkFor)
{
v.sendMessage(ChatColor.GREEN + "" + this.checkFor + " found after " + i + " blocks.");
return;
}
}
v.sendMessage(ChatColor.GRAY + "Nope.");
break;
case DOWN:
// Scan up
for (int i = 1; i < this.depth + 1; i++)
{
if ((this.getTargetBlock().getY() + i) >= v.getWorld().getMaxHeight())
{
break;
}
if (this.clampY(this.getTargetBlock().getX(), this.getTargetBlock().getY() + i, this.getTargetBlock().getZ()).getType() == this.checkFor)
{
v.sendMessage(ChatColor.GREEN + "" + this.checkFor + " found after " + i + " blocks.");
return;
}
}
v.sendMessage(ChatColor.GRAY + "Nope.");
break;
default:
break;
}
}
@SuppressWarnings("deprecation")
@Override
protected final void arrow(final SnipeData v)
{
this.checkFor = BukkitAdapter.adapt(BlockTypes.get(v.getVoxelId()));
this.scan(v, this.getTargetBlock().getFace(this.getLastBlock()));
}
@SuppressWarnings("deprecation")
@Override
protected final void powder(final SnipeData v)
{
this.checkFor = BukkitAdapter.adapt(BlockTypes.get(v.getVoxelId()));
this.scan(v, this.getTargetBlock().getFace(this.getLastBlock()));
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom(ChatColor.GREEN + "Scanner depth set to " + this.depth);
vm.custom(ChatColor.GREEN + "Scanner scans for " + this.checkFor + " (change with /v #)");
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
if (par[i].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Scanner brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b sc d# -- will set the search depth to #. Clamps to 1 - 64.");
return;
}
if (par[i].startsWith("d"))
{
this.depth = this.clamp(Integer.parseInt(par[i].substring(1)), DEPTH_MIN, DEPTH_MAX);
v.sendMessage(ChatColor.AQUA + "Scanner depth set to " + this.depth);
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.scanner";
}
}

Datei anzeigen

@ -0,0 +1,116 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Set_Brush
*
* @author Voxel
*/
public class SetBrush extends PerformBrush
{
private static final int SELECTION_SIZE_MAX = 5000000;
private Block block = null;
/**
*
*/
public SetBrush()
{
this.setName("Set");
}
private boolean set(final Block bl, final SnipeData v)
{
if (this.block == null)
{
this.block = bl;
return true;
}
else
{
if (!this.block.getWorld().getName().equals(bl.getWorld().getName()))
{
v.sendMessage(ChatColor.RED + "You selected points in different worlds!");
this.block = null;
return true;
}
final int lowX = (this.block.getX() <= bl.getX()) ? this.block.getX() : bl.getX();
final int lowY = (this.block.getY() <= bl.getY()) ? this.block.getY() : bl.getY();
final int lowZ = (this.block.getZ() <= bl.getZ()) ? this.block.getZ() : bl.getZ();
final int highX = (this.block.getX() >= bl.getX()) ? this.block.getX() : bl.getX();
final int highY = (this.block.getY() >= bl.getY()) ? this.block.getY() : bl.getY();
final int highZ = (this.block.getZ() >= bl.getZ()) ? this.block.getZ() : bl.getZ();
if (Math.abs(highX - lowX) * Math.abs(highZ - lowZ) * Math.abs(highY - lowY) > SELECTION_SIZE_MAX)
{
v.sendMessage(ChatColor.RED + "Selection size above hardcoded limit, please use a smaller selection.");
}
else
{
for (int y = lowY; y <= highY; y++)
{
for (int x = lowX; x <= highX; x++)
{
for (int z = lowZ; z <= highZ; z++)
{
this.current.perform(this.clampY(x, y, z));
}
}
}
}
this.block = null;
return false;
}
}
@Override
protected final void arrow(final SnipeData v)
{
if (this.set(this.getTargetBlock(), v))
{
v.sendMessage(ChatColor.GRAY + "Point one");
}
else
{
v.owner().storeUndo(this.current.getUndo());
}
}
@Override
protected final void powder(final SnipeData v)
{
if (this.set(this.getLastBlock(), v))
{
v.sendMessage(ChatColor.GRAY + "Point one");
}
else
{
v.owner().storeUndo(this.current.getUndo());
}
}
@Override
public final void info(final Message vm)
{
this.block = null;
vm.brushName(this.getName());
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
super.parameters(par, v);
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.set";
}
}

Datei anzeigen

@ -0,0 +1,160 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
/**
* @author Voxel
*/
public class SetRedstoneFlipBrush extends Brush
{
private Block block = null;
private Undo undo;
private boolean northSouth = true;
/**
*
*/
public SetRedstoneFlipBrush()
{
this.setName("Set Redstone Flip");
}
private boolean set(final Block bl)
{
if (this.block == null)
{
this.block = bl;
return true;
}
else
{
this.undo = new Undo();
final int lowX = (this.block.getX() <= bl.getX()) ? this.block.getX() : bl.getX();
final int lowY = (this.block.getY() <= bl.getY()) ? this.block.getY() : bl.getY();
final int lowZ = (this.block.getZ() <= bl.getZ()) ? this.block.getZ() : bl.getZ();
final int highX = (this.block.getX() >= bl.getX()) ? this.block.getX() : bl.getX();
final int highY = (this.block.getY() >= bl.getY()) ? this.block.getY() : bl.getY();
final int highZ = (this.block.getZ() >= bl.getZ()) ? this.block.getZ() : bl.getZ();
for (int y = lowY; y <= highY; y++)
{
for (int x = lowX; x <= highX; x++)
{
for (int z = lowZ; z <= highZ; z++)
{
this.perform(this.clampY(x, y, z));
}
}
}
this.block = null;
return false;
}
}
@SuppressWarnings("deprecation")
private void perform(final AsyncBlock bl)
{
if (bl.getType() == Material.REPEATER)
{
if (this.northSouth)
{
if ((bl.getPropertyId() % 4) == 1)
{
this.undo.put(bl);
bl.setPropertyId((bl.getPropertyId() + 2));
}
else if ((bl.getPropertyId() % 4) == 3)
{
this.undo.put(bl);
bl.setPropertyId((bl.getPropertyId() - 2));
}
}
else
{
if ((bl.getPropertyId() % 4) == 2)
{
this.undo.put(bl);
bl.setPropertyId((bl.getPropertyId() - 2));
}
else if ((bl.getPropertyId() % 4) == 0)
{
this.undo.put(bl);
bl.setPropertyId((bl.getPropertyId() + 2));
}
}
}
}
@Override
protected final void arrow(final SnipeData v)
{
if (this.set(this.getTargetBlock()))
{
v.sendMessage(ChatColor.GRAY + "Point one");
}
else
{
v.owner().storeUndo(this.undo);
}
}
@Override
protected final void powder(final SnipeData v)
{
if (this.set(this.getLastBlock()))
{
v.sendMessage(ChatColor.GRAY + "Point one");
}
else
{
v.owner().storeUndo(this.undo);
}
}
@Override
public final void info(final Message vm)
{
this.block = null;
vm.brushName(this.getName());
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
if (par[i].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Set Repeater Flip Parameters:");
v.sendMessage(ChatColor.AQUA + "/b setrf <direction> -- valid direction inputs are(n,s,e,world), Set the direction that you wish to flip your repeaters, defaults to north/south.");
return;
}
if (par[i].startsWith("n") || par[i].startsWith("s") || par[i].startsWith("ns"))
{
this.northSouth = true;
v.sendMessage(ChatColor.AQUA + "Flip direction set to north/south");
}
else if (par[i].startsWith("e") || par[i].startsWith("world") || par[i].startsWith("ew"))
{
this.northSouth = false;
v.sendMessage(ChatColor.AQUA + "Flip direction set to east/west.");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.setredstoneflip";
}
}

Datei anzeigen

@ -0,0 +1,113 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
/**
* @author Voxel
*/
public class SetRedstoneRotateBrush extends Brush
{
private Block block = null;
private Undo undo;
/**
*
*/
public SetRedstoneRotateBrush()
{
this.setName("Set Redstone Rotate");
}
private boolean set(final Block bl)
{
if (this.block == null)
{
this.block = bl;
return true;
}
else
{
this.undo = new Undo();
final int lowX = (this.block.getX() <= bl.getX()) ? this.block.getX() : bl.getX();
final int lowY = (this.block.getY() <= bl.getY()) ? this.block.getY() : bl.getY();
final int lowZ = (this.block.getZ() <= bl.getZ()) ? this.block.getZ() : bl.getZ();
final int highX = (this.block.getX() >= bl.getX()) ? this.block.getX() : bl.getX();
final int highY = (this.block.getY() >= bl.getY()) ? this.block.getY() : bl.getY();
final int highZ = (this.block.getZ() >= bl.getZ()) ? this.block.getZ() : bl.getZ();
for (int y = lowY; y <= highY; y++)
{
for (int x = lowX; x <= highX; x++)
{
for (int z = lowZ; z <= highZ; z++)
{
this.perform(this.clampY(x, y, z));
}
}
}
this.block = null;
return false;
}
}
@SuppressWarnings("deprecation")
private void perform(final AsyncBlock bl)
{
if (bl.getType() == Material.REPEATER)
{
this.undo.put(bl);
bl.setPropertyId((((bl.getPropertyId() % 4) + 1 < 5) ? (bl.getPropertyId() + 1) : (bl.getPropertyId() - 4)));
}
}
@Override
protected final void arrow(final SnipeData v)
{
if (this.set(this.getTargetBlock()))
{
v.owner().getPlayer().sendMessage(ChatColor.GRAY + "Point one");
}
else
{
v.owner().storeUndo(this.undo);
}
}
@Override
protected final void powder(final SnipeData v)
{
if (this.set(this.getLastBlock()))
{
v.owner().getPlayer().sendMessage(ChatColor.GRAY + "Point one");
}
else
{
v.owner().storeUndo(this.undo);
}
}
@Override
public final void info(final Message vm)
{
this.block = null;
vm.brushName(this.getName());
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
super.parameters(par, v);
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.setredstonerotate";
}
}

Datei anzeigen

@ -0,0 +1,161 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* THIS BRUSH SHOULD NOT USE PERFORMERS.
* http://www.voxelwiki.com/minecraft/Voxelsniper#Shell_Brushes
*
* @author Voxel
*/
public class ShellBallBrush extends Brush
{
/**
*
*/
public ShellBallBrush()
{
this.setName("Shell Ball");
}
// parameters isn't an abstract method, gilt. You can just leave it out if there are none.
private void bShell(final SnipeData v, Block targetBlock)
{
final int brushSize = v.getBrushSize();
final int brushSizeDoubled = 2 * brushSize;
final int[][][] oldMaterials = new int[2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1]; // Array that holds the original materials plus a buffer
final int[][][] newMaterials = new int[brushSizeDoubled + 1][brushSizeDoubled + 1][brushSizeDoubled + 1]; // Array that holds the hollowed materials
int blockPositionX = targetBlock.getX();
int blockPositionY = targetBlock.getY();
int blockPositionZ = targetBlock.getZ();
// Log current materials into oldmats
for (int x = 0; x <= 2 * (brushSize + 1); x++)
{
for (int y = 0; y <= 2 * (brushSize + 1); y++)
{
for (int z = 0; z <= 2 * (brushSize + 1); z++)
{
oldMaterials[x][y][z] = this.getBlockIdAt(blockPositionX - brushSize - 1 + x, blockPositionY - brushSize - 1 + y, blockPositionZ - brushSize - 1 + z);
}
}
}
// Log current materials into newmats
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int y = 0; y <= brushSizeDoubled; y++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
newMaterials[x][y][z] = oldMaterials[x + 1][y + 1][z + 1];
}
}
}
int temp;
// Hollow Brush Area
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int y = 0; y <= brushSizeDoubled; y++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
temp = 0;
if (oldMaterials[x + 1 + 1][y + 1][z + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1 - 1][y + 1][z + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1][y + 1 + 1][z + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1][y + 1 - 1][z + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1][y + 1][z + 1 + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1][y + 1][z + 1 - 1] == v.getReplaceId())
{
temp++;
}
if (temp == 0)
{
newMaterials[x][y][z] = v.getVoxelId();
}
}
}
}
// Make the changes
final Undo undo = new Undo();
final double rSquared = Math.pow(brushSize + 0.5, 2);
for (int x = brushSizeDoubled; x >= 0; x--)
{
final double xSquared = Math.pow(x - brushSize, 2);
for (int y = 0; y <= 2 * brushSize; y++)
{
final double ySquared = Math.pow(y - brushSize, 2);
for (int z = 2 * brushSize; z >= 0; z--)
{
if (xSquared + ySquared + Math.pow(z - brushSize, 2) <= rSquared)
{
if (this.getBlockIdAt(blockPositionX - brushSize + x, blockPositionY - brushSize + y, blockPositionZ - brushSize + z) != newMaterials[x][y][z])
{
undo.put(this.clampY(blockPositionX - brushSize + x, blockPositionY - brushSize + y, blockPositionZ - brushSize + z));
}
this.setBlockIdAt(blockPositionZ - brushSize + z, blockPositionX - brushSize + x, blockPositionY - brushSize + y, newMaterials[x][y][z]);
}
}
}
}
v.owner().storeUndo(undo);
// This is needed because most uses of this brush will not be sible to the sniper.
v.owner().getPlayer().sendMessage(ChatColor.AQUA + "Shell complete.");
}
@Override
protected final void arrow(final SnipeData v)
{
this.bShell(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.bShell(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.voxel();
vm.replace();
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.shellball";
}
}

Datei anzeigen

@ -0,0 +1,153 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import java.util.ArrayList;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Shell_Brushes
*
* @author Piotr
*/
public class ShellSetBrush extends Brush
{
private static final int MAX_SIZE = 5000000;
private Block block = null;
/**
*
*/
public ShellSetBrush()
{
this.setName("Shell Set");
}
@SuppressWarnings("deprecation")
private boolean set(final Block bl, final SnipeData v)
{
if (this.block == null)
{
this.block = bl;
return true;
}
else
{
if (!this.block.getWorld().getName().equals(bl.getWorld().getName()))
{
v.sendMessage(ChatColor.RED + "You selected points in different worlds!");
this.block = null;
return true;
}
final int lowX = (this.block.getX() <= bl.getX()) ? this.block.getX() : bl.getX();
final int lowY = (this.block.getY() <= bl.getY()) ? this.block.getY() : bl.getY();
final int lowZ = (this.block.getZ() <= bl.getZ()) ? this.block.getZ() : bl.getZ();
final int highX = (this.block.getX() >= bl.getX()) ? this.block.getX() : bl.getX();
final int highY = (this.block.getY() >= bl.getY()) ? this.block.getY() : bl.getY();
final int highZ = (this.block.getZ() >= bl.getZ()) ? this.block.getZ() : bl.getZ();
if (Math.abs(highX - lowX) * Math.abs(highZ - lowZ) * Math.abs(highY - lowY) > MAX_SIZE)
{
v.sendMessage(ChatColor.RED + "Selection size above hardcoded limit, please use a smaller selection.");
}
else
{
final ArrayList<AsyncBlock> blocks = new ArrayList<AsyncBlock>(((Math.abs(highX - lowX) * Math.abs(highZ - lowZ) * Math.abs(highY - lowY)) / 2));
for (int y = lowY; y <= highY; y++)
{
for (int x = lowX; x <= highX; x++)
{
for (int z = lowZ; z <= highZ; z++)
{
if (this.getWorld().getBlockAt(x, y, z).getTypeId() == v.getReplaceId())
{
continue;
}
else if (this.getWorld().getBlockAt(x + 1, y, z).getTypeId() == v.getReplaceId())
{
continue;
}
else if (this.getWorld().getBlockAt(x - 1, y, z).getTypeId() == v.getReplaceId())
{
continue;
}
else if (this.getWorld().getBlockAt(x, y, z + 1).getTypeId() == v.getReplaceId())
{
continue;
}
else if (this.getWorld().getBlockAt(x, y, z - 1).getTypeId() == v.getReplaceId())
{
continue;
}
else if (this.getWorld().getBlockAt(x, y + 1, z).getTypeId() == v.getReplaceId())
{
continue;
}
else if (this.getWorld().getBlockAt(x, y - 1, z).getTypeId() == v.getReplaceId())
{
continue;
}
else
{
blocks.add(this.getWorld().getBlockAt(x, y, z));
}
}
}
}
final Undo undo = new Undo();
for (final AsyncBlock currentBlock : blocks)
{
if (currentBlock.getTypeId() != v.getVoxelId())
{
undo.put(currentBlock);
currentBlock.setTypeId(v.getVoxelId());
}
}
v.owner().storeUndo(undo);
v.sendMessage(ChatColor.AQUA + "Shell complete.");
}
this.block = null;
return false;
}
}
@Override
protected final void arrow(final SnipeData v)
{
if (this.set(this.getTargetBlock(), v))
{
v.owner().getPlayer().sendMessage(ChatColor.GRAY + "Point one");
}
}
@Override
protected final void powder(final SnipeData v)
{
if (this.set(this.getLastBlock(), v))
{
v.owner().getPlayer().sendMessage(ChatColor.GRAY + "Point one");
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.voxel();
vm.replace();
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.shellset";
}
}

Datei anzeigen

@ -0,0 +1,163 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* THIS BRUSH SHOULD NOT USE PERFORMERS.
* http://www.voxelwiki.com/minecraft/Voxelsniper#Shell_Brushes
*
* @author Voxel
*/
public class ShellVoxelBrush extends Brush
{
/**
*
*/
public ShellVoxelBrush()
{
this.setName("Shell Voxel");
}
private void vShell(final SnipeData v, Block targetBlock)
{
final int brushSize = v.getBrushSize();
final int brushSizeSquared = 2 * brushSize;
final int[][][] oldMaterials = new int[2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1][2 * (brushSize + 1) + 1]; // Array that holds the original materials plus a buffer
final int[][][] newMaterials = new int[2 * brushSize + 1][2 * brushSize + 1][2 * brushSize + 1]; // Array that holds the hollowed materials
int blockPositionX = targetBlock.getX();
int blockPositionY = targetBlock.getY();
int blockPositionZ = targetBlock.getZ();
// Log current materials into oldmats
for (int x = 0; x <= 2 * (brushSize + 1); x++)
{
for (int y = 0; y <= 2 * (brushSize + 1); y++)
{
for (int z = 0; z <= 2 * (brushSize + 1); z++)
{
oldMaterials[x][y][z] = this.getBlockIdAt(blockPositionX - brushSize - 1 + x, blockPositionY - brushSize - 1 + y, blockPositionZ - brushSize - 1 + z);
}
}
}
// Log current materials into newmats
for (int x = 0; x <= brushSizeSquared; x++)
{
for (int y = 0; y <= brushSizeSquared; y++)
{
for (int z = 0; z <= brushSizeSquared; z++)
{
newMaterials[x][y][z] = oldMaterials[x + 1][y + 1][z + 1];
}
}
}
int temp;
// Hollow Brush Area
for (int x = 0; x <= brushSizeSquared; x++)
{
for (int z = 0; z <= brushSizeSquared; z++)
{
for (int y = 0; y <= brushSizeSquared; y++)
{
temp = 0;
if (oldMaterials[x + 1 + 1][z + 1][y + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1 - 1][z + 1][y + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1][z + 1 + 1][y + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1][z + 1 - 1][y + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1][z + 1][y + 1 + 1] == v.getReplaceId())
{
temp++;
}
if (oldMaterials[x + 1][z + 1][y + 1 - 1] == v.getReplaceId())
{
temp++;
}
if (temp == 0)
{
newMaterials[x][z][y] = v.getVoxelId();
}
}
}
}
// Make the changes
final Undo undo = new Undo();
for (int x = brushSizeSquared; x >= 0; x--)
{
for (int y = 0; y <= brushSizeSquared; y++)
{
for (int z = brushSizeSquared; z >= 0; z--)
{
if (this.getBlockIdAt(blockPositionX - brushSize + x, blockPositionY - brushSize + y, blockPositionZ - brushSize + z) != newMaterials[x][y][z])
{
undo.put(this.clampY(blockPositionX - brushSize + x, blockPositionY - brushSize + y, blockPositionZ - brushSize + z));
}
this.setBlockIdAt(blockPositionZ - brushSize + z, blockPositionX - brushSize + x, blockPositionY - brushSize + y, newMaterials[x][y][z]);
}
}
}
v.owner().storeUndo(undo);
v.owner().getPlayer().sendMessage(ChatColor.AQUA + "Shell complete.");
}
@Override
protected final void arrow(final SnipeData v)
{
this.vShell(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.vShell(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
vm.voxel();
vm.replace();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Shell Voxel Parameters:");
}
else
{
v.sendMessage(ChatColor.RED + "Invalid parameter - see the info message for help.");
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.shellvoxel";
}
}

Datei anzeigen

@ -0,0 +1,484 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.VoxelSniper;
import org.bukkit.ChatColor;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* Overwrites signs. (Wiki:
* http://www.voxelwiki.com/minecraft/VoxelSniper#Sign_Overwrite_Brush)
*
* @author Monofraps
*/
public class SignOverwriteBrush extends Brush
{
private static final int MAX_SIGN_LINE_LENGTH = 15;
private static final int NUM_SIGN_LINES = 4;
// these are no array indices
private static final int SIGN_LINE_1 = 1;
private static final int SIGN_LINE_2 = 2;
private static final int SIGN_LINE_3 = 3;
private static final int SIGN_LINE_4 = 4;
private String[] signTextLines = new String[NUM_SIGN_LINES];
private boolean[] signLinesEnabled = new boolean[NUM_SIGN_LINES];
private boolean rangedMode = false;
/**
*
*/
public SignOverwriteBrush()
{
this.setName("Sign Overwrite Brush");
clearBuffer();
resetStates();
}
/**
* Sets the text of a given sign.
*
* @param sign
*/
private void setSignText(final Sign sign)
{
for (int i = 0; i < this.signTextLines.length; i++)
{
if (this.signLinesEnabled[i])
{
sign.setLine(i, this.signTextLines[i]);
}
}
sign.update();
}
/**
* Sets the text of the target sign if the target block is a sign.
*
* @param v
*/
private void setSingle(final SnipeData v)
{
if (this.getTargetBlock().getState() instanceof Sign)
{
setSignText((Sign) this.getTargetBlock().getState());
}
else
{
v.sendMessage(ChatColor.RED + "Target block is not a sign.");
return;
}
}
/**
* Sets all signs in a range of box{x=z=brushSize*2+1 ; z=voxelHeight*2+1}.
*
* @param v
*/
private void setRanged(final SnipeData v)
{
final int minX = getTargetBlock().getX() - v.getBrushSize();
final int maxX = getTargetBlock().getX() + v.getBrushSize();
final int minY = getTargetBlock().getY() - v.getVoxelHeight();
final int maxY = getTargetBlock().getY() + v.getVoxelHeight();
final int minZ = getTargetBlock().getZ() - v.getBrushSize();
final int maxZ = getTargetBlock().getZ() + v.getBrushSize();
boolean signFound = false; // indicates whether or not a sign was set
for (int x = minX; x <= maxX; x++)
{
for (int y = minY; y <= maxY; y++)
{
for (int z = minZ; z <= maxZ; z++)
{
BlockState blockState = this.getWorld().getBlockAt(x, y, z).getState();
if (blockState instanceof Sign)
{
setSignText((Sign) blockState);
signFound = true;
}
}
}
}
if (!signFound)
{
v.sendMessage(ChatColor.RED + "Did not found any sign in selection box.");
}
}
@Override
protected final void arrow(final SnipeData v)
{
if (this.rangedMode)
{
setRanged(v);
}
else
{
setSingle(v);
}
}
@Override
protected final void powder(final SnipeData v)
{
if (this.getTargetBlock().getState() instanceof Sign)
{
Sign sign = (Sign) this.getTargetBlock().getState();
for (int i = 0; i < this.signTextLines.length; i++)
{
if (this.signLinesEnabled[i])
{
this.signTextLines[i] = sign.getLine(i);
}
}
displayBuffer(v);
}
else
{
v.sendMessage(ChatColor.RED + "Target block is not a sign.");
}
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
boolean textChanged = false;
for (int i = 0; i < par.length; i++)
{
String parameter = par[i];
try
{
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.AQUA + "Sign Overwrite Brush Powder/Arrow:");
v.sendMessage(ChatColor.BLUE + "The arrow writes the internal line buffer to the tearget sign.");
v.sendMessage(ChatColor.BLUE + "The powder reads the text of the target sign into the internal buffer.");
v.sendMessage(ChatColor.AQUA + "Sign Overwrite Brush Parameters:");
v.sendMessage(ChatColor.GREEN + "-1[:(enabled|disabled)] ... " + ChatColor.BLUE + "-- Sets the text of the first sign line. (e.g. -1 Blah Blah)");
v.sendMessage(ChatColor.GREEN + "-2[:(enabled|disabled)] ... " + ChatColor.BLUE + "-- Sets the text of the second sign line. (e.g. -2 Blah Blah)");
v.sendMessage(ChatColor.GREEN + "-3[:(enabled|disabled)] ... " + ChatColor.BLUE + "-- Sets the text of the third sign line. (e.g. -3 Blah Blah)");
v.sendMessage(ChatColor.GREEN + "-4[:(enabled|disabled)] ... " + ChatColor.BLUE + "-- Sets the text of the fourth sign line. (e.g. -4 Blah Blah)");
v.sendMessage(ChatColor.GREEN + "-clear " + ChatColor.BLUE + "-- Clears the line buffer. (Alias: -c)");
v.sendMessage(ChatColor.GREEN + "-clearall " + ChatColor.BLUE + "-- Clears the line buffer and sets all lines back to enabled. (Alias: -ca)");
v.sendMessage(ChatColor.GREEN + "-multiple [on|off] " + ChatColor.BLUE + "-- Enables or disables ranged mode. (Alias: -m) (see Wiki for more information)");
v.sendMessage(ChatColor.GREEN + "-save (name) " + ChatColor.BLUE + "-- Save you buffer to a file named [name]. (Alias: -s)");
v.sendMessage(ChatColor.GREEN + "-open (name) " + ChatColor.BLUE + "-- Loads a buffer from a file named [name]. (Alias: -o)");
}
else if (parameter.startsWith("-1"))
{
textChanged = true;
i = parseSignLineFromParam(par, SIGN_LINE_1, v, i);
}
else if (parameter.startsWith("-2"))
{
textChanged = true;
i = parseSignLineFromParam(par, SIGN_LINE_2, v, i);
}
else if (parameter.startsWith("-3"))
{
textChanged = true;
i = parseSignLineFromParam(par, SIGN_LINE_3, v, i);
}
else if (parameter.startsWith("-4"))
{
textChanged = true;
i = parseSignLineFromParam(par, SIGN_LINE_4, v, i);
}
else if (parameter.equalsIgnoreCase("-clear") || parameter.equalsIgnoreCase("-c"))
{
clearBuffer();
v.sendMessage(ChatColor.BLUE + "Internal text buffer cleard.");
}
else if (parameter.equalsIgnoreCase("-clearall") || parameter.equalsIgnoreCase("-ca"))
{
clearBuffer();
resetStates();
v.sendMessage(ChatColor.BLUE + "Internal text buffer cleard and states back to enabled.");
}
else if (parameter.equalsIgnoreCase("-multiple") || parameter.equalsIgnoreCase("-m"))
{
if ((i + 1) >= par.length)
{
v.sendMessage(ChatColor.RED + String.format("Missing parameter after %s.", parameter));
continue;
}
rangedMode = (par[++i].equalsIgnoreCase("on") || par[++i].equalsIgnoreCase("yes"));
v.sendMessage(ChatColor.BLUE + String.format("Ranged mode is %s", ChatColor.GREEN + (rangedMode ? "enabled" : "disabled")));
if (this.rangedMode)
{
v.sendMessage(ChatColor.GREEN + "Brush size set to " + ChatColor.RED + v.getBrushSize());
v.sendMessage(ChatColor.AQUA + "Brush height set to " + ChatColor.RED + v.getVoxelHeight());
}
}
else if (parameter.equalsIgnoreCase("-save") || parameter.equalsIgnoreCase("-s"))
{
if ((i + 1) >= par.length)
{
v.sendMessage(ChatColor.RED + String.format("Missing parameter after %s.", parameter));
continue;
}
String fileName = par[++i];
saveBufferToFile(fileName, v);
}
else if (parameter.equalsIgnoreCase("-open") || parameter.equalsIgnoreCase("-o"))
{
if ((i + 1) >= par.length)
{
v.sendMessage(ChatColor.RED + String.format("Missing parameter after %s.", parameter));
continue;
}
String fileName = par[++i];
loadBufferFromFile(fileName, "", v);
textChanged = true;
}
}
catch (Exception exception)
{
v.sendMessage(ChatColor.RED + String.format("Error while parsing parameter %s", parameter));
exception.printStackTrace();
}
}
if (textChanged)
{
displayBuffer(v);
}
}
/**
* Parses parameter input text of line [param:lineNumber].
* Iterates though the given array until the next top level param (a parameter which starts
* with a dash -) is found.
*
* @param params
* @param lineNumber
* @param v
* @param i
* @return
*/
private int parseSignLineFromParam(final String[] params, final int lineNumber, final SnipeData v, int i)
{
final int lineIndex = lineNumber - 1;
final String parameter = params[i];
boolean statusSet = false;
if (parameter.contains(":"))
{
this.signLinesEnabled[lineIndex] = parameter.substring(parameter.indexOf(":")).equalsIgnoreCase(":enabled");
v.sendMessage(ChatColor.BLUE + "Line " + lineNumber + " is " + ChatColor.GREEN + (this.signLinesEnabled[lineIndex] ? "enabled" : "disabled"));
statusSet = true;
}
if ((i + 1) >= params.length)
{
// return if the user just wanted to set the status
if (statusSet)
{
return i;
}
v.sendMessage(ChatColor.RED + "Warning: No text after -" + lineNumber + ". Setting buffer text to \"\" (empty string)");
signTextLines[lineIndex] = "";
return i;
}
String newText = "";
// go through the array until the next top level parameter is found
for (i++; i < params.length; i++)
{
final String currentParameter = params[i];
if (currentParameter.startsWith("-"))
{
i--;
break;
}
else
{
newText += currentParameter + " ";
}
}
newText = ChatColor.translateAlternateColorCodes('&', newText);
// remove last space or return if the string is empty and the user just wanted to set the status
if (!newText.isEmpty() && newText.endsWith(" "))
{
newText = newText.substring(0, newText.length() - 1);
}
else if (newText.isEmpty())
{
if (statusSet)
{
return i;
}
v.sendMessage(ChatColor.RED + "Warning: No text after -" + lineNumber + ". Setting buffer text to \"\" (empty string)");
}
// check the line length and cut the text if needed
if (newText.length() > MAX_SIGN_LINE_LENGTH)
{
v.sendMessage(ChatColor.RED + "Warning: Text on line " + lineNumber + " exceeds the maximum line length of " + MAX_SIGN_LINE_LENGTH + " characters. Your text will be cut.");
newText = newText.substring(0, MAX_SIGN_LINE_LENGTH);
}
this.signTextLines[lineIndex] = newText;
return i;
}
private void displayBuffer(final SnipeData v)
{
v.sendMessage(ChatColor.BLUE + "Buffer text set to: ");
for (int i = 0; i < this.signTextLines.length; i++)
{
v.sendMessage((this.signLinesEnabled[i] ? ChatColor.GREEN + "(E): " : ChatColor.RED + "(D): ") + ChatColor.BLACK + this.signTextLines[i]);
}
}
/**
* Saves the buffer to file.
*
* @param fileName
* @param v
*/
private void saveBufferToFile(final String fileName, final SnipeData v)
{
final File store = new File(VoxelSniper.getInstance().getDataFolder() + "/" + fileName + ".vsign");
if (store.exists())
{
v.sendMessage("This file already exists.");
return;
}
try
{
store.createNewFile();
FileWriter outFile = new FileWriter(store);
BufferedWriter outStream = new BufferedWriter(outFile);
for (int i = 0; i < this.signTextLines.length; i++)
{
outStream.write(String.valueOf(this.signLinesEnabled[i]) + "\n");
outStream.write(this.signTextLines[i] + "\n");
}
outStream.close();
outFile.close();
v.sendMessage(ChatColor.BLUE + "File saved successfully.");
}
catch (IOException exception)
{
v.sendMessage(ChatColor.RED + "Failed to save file. " + exception.getMessage());
exception.printStackTrace();
}
}
/**
* Loads a buffer from a file.
*
* @param fileName
* @param userDomain
* @param v
*/
private void loadBufferFromFile(final String fileName, final String userDomain, final SnipeData v)
{
final File store = new File(VoxelSniper.getInstance().getDataFolder() + "/" + fileName + ".vsign");
if (!store.exists())
{
v.sendMessage("This file does not exist.");
return;
}
try
{
FileReader inFile = new FileReader(store);
BufferedReader inStream = new BufferedReader(inFile);
for (int i = 0; i < this.signTextLines.length; i++)
{
this.signLinesEnabled[i] = Boolean.valueOf(inStream.readLine());
this.signTextLines[i] = inStream.readLine();
}
inStream.close();
inFile.close();
v.sendMessage(ChatColor.BLUE + "File loaded successfully.");
}
catch (IOException exception)
{
v.sendMessage(ChatColor.RED + "Failed to load file. " + exception.getMessage());
exception.printStackTrace();
}
}
/**
* Clears the internal text buffer. (Sets it to empty strings)
*/
private void clearBuffer()
{
for (int i = 0; i < this.signTextLines.length; i++)
{
this.signTextLines[i] = "";
}
}
/**
* Resets line enabled states to enabled.
*/
private void resetStates()
{
for (int i = 0; i < this.signLinesEnabled.length; i++)
{
this.signLinesEnabled[i] = true;
}
}
@Override
public final void info(final Message vm)
{
vm.brushName("Sign Overwrite Brush");
vm.custom(ChatColor.BLUE + "Buffer text: ");
for (int i = 0; i < this.signTextLines.length; i++)
{
vm.custom((this.signLinesEnabled[i] ? ChatColor.GREEN + "(E): " : ChatColor.RED + "(D): ") + ChatColor.BLACK + this.signTextLines[i]);
}
vm.custom(ChatColor.BLUE + String.format("Ranged mode is %s", ChatColor.GREEN + (rangedMode ? "enabled" : "disabled")));
if (rangedMode)
{
vm.size();
vm.height();
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.signoverwrite";
}
}

Datei anzeigen

@ -0,0 +1,47 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Snipe_Brush
*
* @author Voxel
*/
public class SnipeBrush extends PerformBrush
{
/**
*
*/
public SnipeBrush()
{
this.setName("Snipe");
}
@Override
protected final void arrow(final SnipeData v)
{
this.current.perform(this.getTargetBlock());
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void powder(final SnipeData v)
{
this.current.perform(this.getLastBlock());
v.owner().storeUndo(this.current.getUndo());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.snipe";
}
}

Datei anzeigen

@ -0,0 +1,194 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Snow_cone_brush
*
* @author Voxel
*/
public class SnowConeBrush extends Brush
{
@SuppressWarnings("deprecation")
private void addSnow(final SnipeData v, Block targetBlock)
{
int brushSize;
int blockPositionX = targetBlock.getX();
int blockPositionY = targetBlock.getY();
int blockPositionZ = targetBlock.getZ();
if (targetBlock.isEmpty())
{
brushSize = 0;
}
else
{
brushSize = this.clampY(blockPositionX, blockPositionY, blockPositionZ).getPropertyId() + 1;
}
final int brushSizeDoubled = 2 * brushSize;
final int[][] snowcone = new int[brushSizeDoubled + 1][brushSizeDoubled + 1]; // Will hold block IDs
final int[][] snowconeData = new int[brushSizeDoubled + 1][brushSizeDoubled + 1]; // Will hold data values for snowcone
final int[][] yOffset = new int[brushSizeDoubled + 1][brushSizeDoubled + 1];
// prime the arrays
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
boolean flag = true;
for (int i = 0; i < 10; i++)
{ // overlay
if (flag)
{
if ((this.getBlockIdAt(blockPositionX - brushSize + x, blockPositionY - i, blockPositionZ - brushSize + z) == 0 || this.getBlockIdAt(blockPositionX - brushSize + x, blockPositionY - i, blockPositionZ - brushSize + z) == BlockTypes.SNOW.getInternalId()) && !this.getBlockAt(blockPositionX - brushSize + x, blockPositionY - i - 1, blockPositionZ - brushSize + z).isEmpty() && this.getBlockIdAt(blockPositionX - brushSize + x, blockPositionY - i - 1, blockPositionZ - brushSize + z) != Material.SNOW.getId())
{
flag = false;
yOffset[x][z] = i;
}
}
}
snowcone[x][z] = this.getBlockIdAt(blockPositionX - brushSize + x, blockPositionY - yOffset[x][z], blockPositionZ - brushSize + z);
snowconeData[x][z] = this.clampY(blockPositionX - brushSize + x, blockPositionY - yOffset[x][z], blockPositionZ - brushSize + z).getPropertyId();
}
}
// figure out new snowheights
for (int x = 0; x <= brushSizeDoubled; x++)
{
final double xSquared = Math.pow(x - brushSize, 2);
for (int z = 0; z <= 2 * brushSize; z++)
{
final double zSquared = Math.pow(z - brushSize, 2);
final double dist = Math.pow(xSquared + zSquared, .5); // distance from center of array
final int snowData = brushSize - (int) Math.ceil(dist);
if (snowData >= 0)
{ // no funny business
switch (snowData)
{
case 0:
if (BlockTypes.get(snowcone[x][z]).getMaterial().isAir())
{
snowcone[x][z] = BlockTypes.SNOW.getInternalId();
snowconeData[x][z] = 0;
}
break;
case 7: // Turn largest snowtile into snowblock
if (snowcone[x][z] == BlockTypes.SNOW.getInternalId())
{
snowcone[x][z] = BlockTypes.SNOW_BLOCK.getInternalId();
snowconeData[x][z] = 0;
}
break;
default: // Increase snowtile size, if smaller than target
if (snowData > snowconeData[x][z])
{
switch (BlockTypes.get(snowcone[x][z]))
{
case AIR:
case CAVE_AIR:
case VOID_AIR:
snowconeData[x][z] = snowData;
snowcone[x][z] = BlockTypes.SNOW.getInternalId();
case SNOW_BLOCK:
snowconeData[x][z] = snowData;
break;
default:
break;
}
}
else if (yOffset[x][z] > 0 && snowcone[x][z] == BlockTypes.SNOW.getInternalId())
{
snowconeData[x][z]++;
if (snowconeData[x][z] == 7)
{
snowconeData[x][z] = 0;
snowcone[x][z] = BlockTypes.SNOW_BLOCK.getInternalId();
}
}
break;
}
}
}
}
final Undo undo = new Undo();
for (int x = 0; x <= brushSizeDoubled; x++)
{
for (int z = 0; z <= brushSizeDoubled; z++)
{
if (this.getBlockIdAt(blockPositionX - brushSize + x, blockPositionY - yOffset[x][z], blockPositionZ - brushSize + z) != snowcone[x][z] || this.clampY(blockPositionX - brushSize + x, blockPositionY - yOffset[x][z], blockPositionZ - brushSize + z).getPropertyId() != snowconeData[x][z])
{
undo.put(this.clampY(blockPositionX - brushSize + x, blockPositionY - yOffset[x][z], blockPositionZ - brushSize + z));
}
this.setBlockIdAt(blockPositionZ - brushSize + z, blockPositionX - brushSize + x, blockPositionY - yOffset[x][z], snowcone[x][z]);
this.clampY(blockPositionX - brushSize + x, blockPositionY - yOffset[x][z], blockPositionZ - brushSize + z).setPropertyId(snowconeData[x][z]);
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
}
@Override
protected final void powder(final SnipeData v)
{
switch (getTargetBlock().getType())
{
case SNOW:
this.addSnow(v, this.getTargetBlock());
break;
default:
Block blockAbove = getTargetBlock().getRelative(BlockFace.UP);
if (blockAbove != null && BukkitAdapter.adapt(blockAbove.getType()).getMaterial().isAir())
{
addSnow(v, blockAbove);
}
else
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "Error: Center block neither snow nor air.");
}
break;
}
}
@Override
public final void info(final Message vm)
{
vm.brushName("Snow Cone");
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Snow Cone Parameters:");
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.snowcone";
}
}

Datei anzeigen

@ -0,0 +1,830 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Spiral_Staircase_Brush
*
* @author giltwist
*/
public class SpiralStaircaseBrush extends Brush
{
private String stairtype = "block"; // "block" 1x1 blocks (default), "step" alternating step double step, "stair" staircase with blocks on corners
private String sdirect = "c"; // "c" clockwise (default), "cc" counter-clockwise
private String sopen = "n"; // "n" north (default), "e" east, "world" south, "world" west
/**
*
*/
public SpiralStaircaseBrush()
{
this.setName("Spiral Staircase");
}
@SuppressWarnings("deprecation")
private void buildStairWell(final SnipeData v, Block targetBlock)
{
if (v.getVoxelHeight() < 1)
{
v.setVoxelHeight(1);
v.sendMessage(ChatColor.RED + "VoxelHeight must be a natural number! Set to 1.");
}
final int[][][] spiral = new int[2 * v.getBrushSize() + 1][v.getVoxelHeight()][2 * v.getBrushSize() + 1];
// locate first block in staircase
// Note to self, fix these
int startX = 0;
int startZ = 0;
int y = 0;
int xOffset = 0;
int zOffset = 0;
int toggle = 0;
if (this.sdirect.equalsIgnoreCase("cc"))
{
if (this.sopen.equalsIgnoreCase("n"))
{
startX = 0;
startZ = 2 * v.getBrushSize();
}
else if (this.sopen.equalsIgnoreCase("e"))
{
startX = 0;
startZ = 0;
}
else if (this.sopen.equalsIgnoreCase("s"))
{
startX = 2 * v.getBrushSize();
startZ = 0;
}
else
{
startX = 2 * v.getBrushSize();
startZ = 2 * v.getBrushSize();
}
}
else
{
if (this.sopen.equalsIgnoreCase("n"))
{
startX = 0;
startZ = 0;
}
else if (this.sopen.equalsIgnoreCase("e"))
{
startX = 2 * v.getBrushSize();
startZ = 0;
}
else if (this.sopen.equalsIgnoreCase("s"))
{
startX = 2 * v.getBrushSize();
startZ = 2 * v.getBrushSize();
}
else
{
startX = 0;
startZ = 2 * v.getBrushSize();
}
}
while (y < v.getVoxelHeight())
{
if (this.stairtype.equalsIgnoreCase("block"))
{
// 1x1x1 voxel material steps
spiral[startX + xOffset][y][startZ + zOffset] = 1;
y++;
}
else if (this.stairtype.equalsIgnoreCase("step"))
{
// alternating step-doublestep, uses data value to determine type
switch (toggle)
{
case 0:
toggle = 2;
spiral[startX + xOffset][y][startZ + zOffset] = 1;
break;
case 1:
toggle = 2;
spiral[startX + xOffset][y][startZ + zOffset] = 1;
break;
case 2:
toggle = 1;
spiral[startX + xOffset][y][startZ + zOffset] = 2;
y++;
break;
default:
break;
}
}
// Adjust horizontal position and do stair-option array stuff
if (startX + xOffset == 0)
{ // All North
if (startZ + zOffset == 0)
{ // NORTHEAST
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 1;
}
if (this.sdirect.equalsIgnoreCase("c"))
{
xOffset++;
}
else
{
zOffset++;
}
}
else if (startZ + zOffset == 2 * v.getBrushSize())
{ // NORTHWEST
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 1;
}
if (this.sdirect.equalsIgnoreCase("c"))
{
zOffset--;
}
else
{
xOffset++;
}
}
else
{ // JUST PLAIN NORTH
if (this.sdirect.equalsIgnoreCase("c"))
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 5;
y++;
}
zOffset--;
}
else
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 4;
y++;
}
zOffset++;
}
}
}
else if (startX + xOffset == 2 * v.getBrushSize())
{ // ALL SOUTH
if (startZ + zOffset == 0)
{ // SOUTHEAST
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 1;
}
if (this.sdirect.equalsIgnoreCase("c"))
{
zOffset++;
}
else
{
xOffset--;
}
}
else if (startZ + zOffset == 2 * v.getBrushSize())
{ // SOUTHWEST
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 1;
}
if (this.sdirect.equalsIgnoreCase("c"))
{
xOffset--;
}
else
{
zOffset--;
}
}
else
{ // JUST PLAIN SOUTH
if (this.sdirect.equalsIgnoreCase("c"))
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 4;
y++;
}
zOffset++;
}
else
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 5;
y++;
}
zOffset--;
}
}
}
else if (startZ + zOffset == 0)
{ // JUST PLAIN EAST
if (this.sdirect.equalsIgnoreCase("c"))
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 2;
y++;
}
xOffset++;
}
else
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 3;
y++;
}
xOffset--;
}
}
else
{ // JUST PLAIN WEST
if (this.sdirect.equalsIgnoreCase("c"))
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 3;
y++;
}
xOffset--;
}
else
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 2;
y++;
}
xOffset++;
}
}
}
final Undo undo = new Undo();
// Make the changes
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int i = v.getVoxelHeight() - 1; i >= 0; i--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
int blockPositionX = targetBlock.getX();
int blockPositionY = targetBlock.getY();
int blockPositionZ = targetBlock.getZ();
switch (spiral[x][i][z])
{
case 0:
if (i != v.getVoxelHeight() - 1)
{
if (!((this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair")) && spiral[x][i + 1][z] == 1))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z) != 0)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, 0);
}
}
else
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z) != 0)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, 0);
}
break;
case 1:
if (this.stairtype.equalsIgnoreCase("block"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z) != v.getVoxelId())
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, v.getVoxelId());
}
else if (this.stairtype.equalsIgnoreCase("step"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z) != 44)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, 44);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z).setPropertyId(v.getPropertyId());
}
else if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i - 1, blockPositionZ - v.getBrushSize() + z) != v.getVoxelId())
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i - 1, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i - 1, v.getVoxelId());
}
break;
case 2:
if (this.stairtype.equalsIgnoreCase("step"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z) != 43)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, 43);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z).setPropertyId(v.getPropertyId());
}
else if (this.stairtype.equalsIgnoreCase("woodstair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z) != 53)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, 53);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z).setPropertyId( 0);
}
else if (this.stairtype.equalsIgnoreCase("cobblestair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z) != 67)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, 67);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z).setPropertyId( 0);
}
break;
default:
if (this.stairtype.equalsIgnoreCase("woodstair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z) != 53)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, 53);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z).setPropertyId((spiral[x][i][z] - 2));
}
else if (this.stairtype.equalsIgnoreCase("cobblestair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z) != 67)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, 67);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z).setPropertyId((spiral[x][i][z] - 2));
}
break;
}
}
}
}
v.owner().storeUndo(undo);
}
@SuppressWarnings("deprecation")
private void digStairWell(final SnipeData v, Block targetBlock)
{
if (v.getVoxelHeight() < 1)
{
v.setVoxelHeight(1);
v.sendMessage(ChatColor.RED + "VoxelHeight must be a natural number! Set to 1.");
}
// initialize array
final int[][][] spiral = new int[2 * v.getBrushSize() + 1][v.getVoxelHeight()][2 * v.getBrushSize() + 1];
// locate first block in staircase
// Note to self, fix these
int startX = 0;
int startZ = 0;
int y = 0;
int xOffset = 0;
int zOffset = 0;
int toggle = 0;
if (this.sdirect.equalsIgnoreCase("cc"))
{
if (this.sopen.equalsIgnoreCase("n"))
{
startX = 0;
startZ = 2 * v.getBrushSize();
}
else if (this.sopen.equalsIgnoreCase("e"))
{
startX = 0;
startZ = 0;
}
else if (this.sopen.equalsIgnoreCase("s"))
{
startX = 2 * v.getBrushSize();
startZ = 0;
}
else
{
startX = 2 * v.getBrushSize();
startZ = 2 * v.getBrushSize();
}
}
else
{
if (this.sopen.equalsIgnoreCase("n"))
{
startX = 0;
startZ = 0;
}
else if (this.sopen.equalsIgnoreCase("e"))
{
startX = 2 * v.getBrushSize();
startZ = 0;
}
else if (this.sopen.equalsIgnoreCase("s"))
{
startX = 2 * v.getBrushSize();
startZ = 2 * v.getBrushSize();
}
else
{
startX = 0;
startZ = 2 * v.getBrushSize();
}
}
while (y < v.getVoxelHeight())
{
if (this.stairtype.equalsIgnoreCase("block"))
{
// 1x1x1 voxel material steps
spiral[startX + xOffset][y][startZ + zOffset] = 1;
y++;
}
else if (this.stairtype.equalsIgnoreCase("step"))
{
// alternating step-doublestep, uses data value to determine type
switch (toggle)
{
case 0:
toggle = 2;
spiral[startX + xOffset][y][startZ + zOffset] = 2;
break;
case 1:
toggle = 2;
spiral[startX + xOffset][y][startZ + zOffset] = 2;
break;
case 2:
toggle = 1;
spiral[startX + xOffset][y][startZ + zOffset] = 1;
y++;
break;
default:
break;
}
}
// Adjust horizontal position and do stair-option array stuff
if (startX + xOffset == 0)
{ // All North
if (startZ + zOffset == 0)
{ // NORTHEAST
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 1;
}
if (this.sdirect.equalsIgnoreCase("c"))
{
xOffset++;
}
else
{
zOffset++;
}
}
else if (startZ + zOffset == 2 * v.getBrushSize())
{ // NORTHWEST
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 1;
}
if (this.sdirect.equalsIgnoreCase("c"))
{
zOffset--;
}
else
{
xOffset++;
}
}
else
{ // JUST PLAIN NORTH
if (this.sdirect.equalsIgnoreCase("c"))
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 4;
y++;
}
zOffset--;
}
else
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 5;
y++;
}
zOffset++;
}
}
}
else if (startX + xOffset == 2 * v.getBrushSize())
{ // ALL SOUTH
if (startZ + zOffset == 0)
{ // SOUTHEAST
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 1;
}
if (this.sdirect.equalsIgnoreCase("c"))
{
zOffset++;
}
else
{
xOffset--;
}
}
else if (startZ + zOffset == 2 * v.getBrushSize())
{ // SOUTHWEST
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 1;
}
if (this.sdirect.equalsIgnoreCase("c"))
{
xOffset--;
}
else
{
zOffset--;
}
}
else
{ // JUST PLAIN SOUTH
if (this.sdirect.equalsIgnoreCase("c"))
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 5;
y++;
}
zOffset++;
}
else
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 4;
y++;
}
zOffset--;
}
}
}
else if (startZ + zOffset == 0)
{ // JUST PLAIN EAST
if (this.sdirect.equalsIgnoreCase("c"))
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 3;
y++;
}
xOffset++;
}
else
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 2;
y++;
}
xOffset--;
}
}
else
{ // JUST PLAIN WEST
if (this.sdirect.equalsIgnoreCase("c"))
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 2;
y++;
}
xOffset--;
}
else
{
if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
spiral[startX + xOffset][y][startZ + zOffset] = 3;
y++;
}
xOffset++;
}
}
}
final Undo undo = new Undo();
// Make the changes
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int i = v.getVoxelHeight() - 1; i >= 0; i--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
int blockPositionX = targetBlock.getX();
int blockPositionY = targetBlock.getY();
int blockPositionZ = targetBlock.getZ();
switch (spiral[x][i][z])
{
case 0:
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z) != 0)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, 0);
break;
case 1:
if (this.stairtype.equalsIgnoreCase("block"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z) != v.getVoxelId())
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, v.getVoxelId());
}
else if (this.stairtype.equalsIgnoreCase("step"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z) != 44)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, 44);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z).setPropertyId(v.getPropertyId());
}
else if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z) != v.getVoxelId())
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, v.getVoxelId());
}
break;
case 2:
if (this.stairtype.equalsIgnoreCase("step"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z) != 43)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, 43);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z).setPropertyId(v.getPropertyId());
}
else if (this.stairtype.equalsIgnoreCase("woodstair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z) != 53)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() - x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, 53);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z).setPropertyId( 0);
}
else if (this.stairtype.equalsIgnoreCase("cobblestair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z) != 67)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, 67);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z).setPropertyId( 0);
}
break;
default:
if (this.stairtype.equalsIgnoreCase("woodstair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z) != 53)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, 53);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z).setPropertyId((spiral[x][i][z] - 2));
}
else if (this.stairtype.equalsIgnoreCase("cobblestair"))
{
if (this.getBlockIdAt(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z) != 67)
{
undo.put(this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z));
}
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, 67);
this.clampY(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z).setPropertyId((spiral[x][i][z] - 2));
}
break;
}
}
}
}
v.owner().storeUndo(undo);
}
@Override
protected final void arrow(final SnipeData v)
{
this.digStairWell(v, this.getTargetBlock()); // make stairwell below target
}
@Override
protected final void powder(final SnipeData v)
{
this.buildStairWell(v, this.getLastBlock()); // make stairwell above target
}
@Override
public final void info(final Message vm)
{
vm.brushName("Spiral Staircase");
vm.size();
vm.voxel();
vm.height();
vm.data();
vm.custom(ChatColor.BLUE + "Staircase type: " + this.stairtype);
vm.custom(ChatColor.BLUE + "Staircase turns: " + this.sdirect);
vm.custom(ChatColor.BLUE + "Staircase opens: " + this.sopen);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Spiral Staircase Parameters:");
v.sendMessage(ChatColor.AQUA + "/b sstair 'block' (default) | 'step' | 'woodstair' | 'cobblestair' -- set the type of staircase");
v.sendMessage(ChatColor.AQUA + "/b sstair 'c' (default) | 'cc' -- set the turning direction of staircase");
v.sendMessage(ChatColor.AQUA + "/b sstair 'n' (default) | 'e' | 's' | 'world' -- set the opening direction of staircase");
return;
}
for (int i = 1; i < par.length; i++)
{
if (par[i].equalsIgnoreCase("block") || par[i].equalsIgnoreCase("step") || par[i].equalsIgnoreCase("woodstair") || par[i].equalsIgnoreCase("cobblestair"))
{
this.stairtype = par[i];
v.sendMessage(ChatColor.BLUE + "Staircase type: " + this.stairtype);
}
else if (par[i].equalsIgnoreCase("c") || par[i].equalsIgnoreCase("cc"))
{
this.sdirect = par[i];
v.sendMessage(ChatColor.BLUE + "Staircase turns: " + this.sdirect);
}
else if (par[i].equalsIgnoreCase("n") || par[i].equalsIgnoreCase("e") || par[i].equalsIgnoreCase("s") || par[i].equalsIgnoreCase("world"))
{
this.sopen = par[i];
v.sendMessage(ChatColor.BLUE + "Staircase opens: " + this.sopen);
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.spiralstaircase";
}
}

Datei anzeigen

@ -0,0 +1,284 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import java.util.Random;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Splatter_Brushes
*
* @author Voxel
*/
public class SplatterBallBrush extends PerformBrush
{
private static final int GROW_PERCENT_MIN = 1;
private static final int GROW_PERCENT_DEFAULT = 1000;
private static final int GROW_PERCENT_MAX = 9999;
private static final int SEED_PERCENT_MIN = 1;
private static final int SEED_PERCENT_DEFAULT = 1000;
private static final int SEED_PERCENT_MAX = 9999;
private static final int SPLATREC_PERCENT_MIN = 1;
private static final int SPLATREC_PERCENT_DEFAULT = 3;
private static final int SPLATREC_PERCENT_MAX = 10;
private int seedPercent; // Chance block on first pass is made active
private int growPercent; // chance block on recursion pass is made active
private int splatterRecursions; // How many times you grow the seeds
private Random generator = new Random();
/**
*
*/
public SplatterBallBrush()
{
this.setName("Splatter Ball");
}
private void splatterBall(final SnipeData v, AsyncBlock targetBlock)
{
if (this.seedPercent < SEED_PERCENT_MIN || this.seedPercent > SEED_PERCENT_MAX)
{
v.owner().getPlayer().sendMessage(ChatColor.BLUE + "Seed percent set to: 10%");
this.seedPercent = SEED_PERCENT_DEFAULT;
}
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
v.owner().getPlayer().sendMessage(ChatColor.BLUE + "Growth percent set to: 10%");
this.growPercent = GROW_PERCENT_DEFAULT;
}
if (this.splatterRecursions < SPLATREC_PERCENT_MIN || this.splatterRecursions > SPLATREC_PERCENT_MAX)
{
v.owner().getPlayer().sendMessage(ChatColor.BLUE + "Recursions set to: 3");
this.splatterRecursions = SPLATREC_PERCENT_DEFAULT;
}
final int[][][] splat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
// Seed the array
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
if (this.generator.nextInt(SEED_PERCENT_MAX + 1) <= this.seedPercent)
{
splat[x][y][z] = 1;
}
}
}
}
// Grow the seeds
final int gref = this.growPercent;
final int[][][] tempSplat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
int growcheck;
for (int r = 0; r < this.splatterRecursions; r++)
{
this.growPercent = gref - ((gref / this.splatterRecursions) * (r));
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
tempSplat[x][y][z] = splat[x][y][z]; // prime tempsplat
growcheck = 0;
if (splat[x][y][z] == 0)
{
if (x != 0 && splat[x - 1][y][z] == 1)
{
growcheck++;
}
if (y != 0 && splat[x][y - 1][z] == 1)
{
growcheck++;
}
if (z != 0 && splat[x][y][z - 1] == 1)
{
growcheck++;
}
if (x != 2 * v.getBrushSize() && splat[x + 1][y][z] == 1)
{
growcheck++;
}
if (y != 2 * v.getBrushSize() && splat[x][y + 1][z] == 1)
{
growcheck++;
}
if (z != 2 * v.getBrushSize() && splat[x][y][z + 1] == 1)
{
growcheck++;
}
}
if (growcheck >= GROW_PERCENT_MIN && this.generator.nextInt(GROW_PERCENT_MAX + 1) <= this.growPercent)
{
tempSplat[x][y][z] = 1; // prevent bleed into splat
}
}
}
}
// integrate tempsplat back into splat at end of iteration
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
splat[x][y][z] = tempSplat[x][y][z];
}
}
}
}
this.growPercent = gref;
// Fill 1x1x1 holes
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
if (splat[Math.max(x - 1, 0)][y][z] == 1 && splat[Math.min(x + 1, 2 * v.getBrushSize())][y][z] == 1 && splat[x][Math.max(0, y - 1)][z] == 1 && splat[x][Math.min(2 * v.getBrushSize(), y + 1)][z] == 1)
{
splat[x][y][z] = 1;
}
}
}
}
// Make the changes
final double rSquared = Math.pow(v.getBrushSize() + 1, 2);
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
final double xSquared = Math.pow(x - v.getBrushSize() - 1, 2);
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
final double ySquared = Math.pow(y - v.getBrushSize() - 1, 2);
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
if (splat[x][y][z] == 1 && xSquared + ySquared + Math.pow(z - v.getBrushSize() - 1, 2) <= rSquared)
{
current.perform(targetBlock.getRelative(-v.getBrushSize() + x, -v.getBrushSize() + y, -v.getBrushSize() + z));
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.splatterBall(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.splatterBall(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
if (this.seedPercent < SEED_PERCENT_MIN || this.seedPercent > SEED_PERCENT_MAX)
{
this.seedPercent = SEED_PERCENT_DEFAULT;
}
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
this.growPercent = GROW_PERCENT_DEFAULT;
}
if (this.splatterRecursions < SPLATREC_PERCENT_MIN || this.splatterRecursions > SPLATREC_PERCENT_MAX)
{
this.splatterRecursions = SPLATREC_PERCENT_DEFAULT;
}
vm.brushName("Splatter Ball");
vm.size();
vm.custom(ChatColor.BLUE + "Seed percent set to: " + this.seedPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Growth percent set to: " + this.growPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Recursions set to: " + this.splatterRecursions);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Splatter Ball brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b sb s[int] -- set a seed percentage (1-9999). 100 = 1% Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b sb g[int] -- set a growth percentage (1-9999). Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b sb r[int] -- set a recursion (1-10). Default is 3");
return;
}
else if (parameter.startsWith("s"))
{
final double temp = Integer.parseInt(parameter.replace("s", ""));
if (temp >= SEED_PERCENT_MIN && temp <= SEED_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Seed percent set to: " + temp / 100 + "%");
this.seedPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Seed percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("g"))
{
final double temp = Integer.parseInt(parameter.replace("g", ""));
if (temp >= GROW_PERCENT_MIN && temp <= GROW_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Growth percent set to: " + temp / 100 + "%");
this.growPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Growth percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("r"))
{
final int temp = Integer.parseInt(parameter.replace("r", ""));
if (temp >= SPLATREC_PERCENT_MIN && temp <= SPLATREC_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Recursions set to: " + temp);
this.splatterRecursions = temp;
}
else
{
v.sendMessage(ChatColor.RED + "Recursions must be an integer 1-10!");
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.splatterball";
}
}

Datei anzeigen

@ -0,0 +1,253 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import java.util.Random;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Splatter_Brushes
*
* @author Voxel
*/
public class SplatterDiscBrush extends PerformBrush
{
private static final int GROW_PERCENT_MIN = 1;
private static final int GROW_PERCENT_DEFAULT = 1000;
private static final int GROW_PERCENT_MAX = 9999;
private static final int SEED_PERCENT_MIN = 1;
private static final int SEED_PERCENT_DEFAULT = 1000;
private static final int SEED_PERCENT_MAX = 9999;
private static final int SPLATREC_PERCENT_MIN = 1;
private static final int SPLATREC_PERCENT_DEFAULT = 3;
private static final int SPLATREC_PERCENT_MAX = 10;
private int seedPercent; // Chance block on first pass is made active
private int growPercent; // chance block on recursion pass is made active
private int splatterRecursions; // How many times you grow the seeds
private Random generator = new Random();
/**
*
*/
public SplatterDiscBrush()
{
this.setName("Splatter Disc");
}
private void splatterDisc(final SnipeData v, AsyncBlock targetBlock)
{
if (this.seedPercent < SEED_PERCENT_MIN || this.seedPercent > SEED_PERCENT_MAX)
{
v.sendMessage(ChatColor.BLUE + "Seed percent set to: 10%");
this.seedPercent = SEED_PERCENT_DEFAULT;
}
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
v.sendMessage(ChatColor.BLUE + "Growth percent set to: 10%");
this.growPercent = GROW_PERCENT_DEFAULT;
}
if (this.splatterRecursions < SPLATREC_PERCENT_MIN || this.splatterRecursions > SPLATREC_PERCENT_MAX)
{
v.sendMessage(ChatColor.BLUE + "Recursions set to: 3");
this.splatterRecursions = SPLATREC_PERCENT_DEFAULT;
}
final int[][] splat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
// Seed the array
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
if (this.generator.nextInt(SEED_PERCENT_MAX + 1) <= this.seedPercent)
{
splat[x][y] = 1;
}
}
}
// Grow the seeds
final int gref = this.growPercent;
int growcheck;
final int[][] tempSplat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
for (int r = 0; r < this.splatterRecursions; r++)
{
this.growPercent = gref - ((gref / this.splatterRecursions) * (r));
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
tempSplat[x][y] = splat[x][y]; // prime tempsplat
growcheck = 0;
if (splat[x][y] == 0)
{
if (x != 0 && splat[x - 1][y] == 1)
{
growcheck++;
}
if (y != 0 && splat[x][y - 1] == 1)
{
growcheck++;
}
if (x != 2 * v.getBrushSize() && splat[x + 1][y] == 1)
{
growcheck++;
}
if (y != 2 * v.getBrushSize() && splat[x][y + 1] == 1)
{
growcheck++;
}
}
if (growcheck >= 1 && this.generator.nextInt(GROW_PERCENT_MAX + 1) <= this.growPercent)
{
tempSplat[x][y] = 1; // prevent bleed into splat
}
}
}
// integrate tempsplat back into splat at end of iteration
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
splat[x][y] = tempSplat[x][y];
}
}
}
this.growPercent = gref;
// Fill 1x1 holes
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
if (splat[Math.max(x - 1, 0)][y] == 1 && splat[Math.min(x + 1, 2 * v.getBrushSize())][y] == 1 && splat[x][Math.max(0, y - 1)] == 1 && splat[x][Math.min(2 * v.getBrushSize(), y + 1)] == 1)
{
splat[x][y] = 1;
}
}
}
// Make the changes
final double rSquared = Math.pow(v.getBrushSize() + 1, 2);
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
final double xSquared = Math.pow(x - v.getBrushSize() - 1, 2);
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
if (splat[x][y] == 1 && xSquared + Math.pow(y - v.getBrushSize() - 1, 2) <= rSquared)
{
current.perform(targetBlock.getRelative(x - v.getBrushSize(), 0, y - v.getBrushSize()));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.splatterDisc(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.splatterDisc(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
if (this.seedPercent < SEED_PERCENT_MIN || this.seedPercent > SEED_PERCENT_MAX)
{
this.seedPercent = SEED_PERCENT_DEFAULT;
}
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
this.growPercent = GROW_PERCENT_DEFAULT;
}
if (this.splatterRecursions < SPLATREC_PERCENT_MIN || this.splatterRecursions > SPLATREC_PERCENT_MAX)
{
this.splatterRecursions = SPLATREC_PERCENT_DEFAULT;
}
vm.brushName("Splatter Disc");
vm.size();
vm.custom(ChatColor.BLUE + "Seed percent set to: " + this.seedPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Growth percent set to: " + this.growPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Recursions set to: " + this.splatterRecursions);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Splatter Disc brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b sd s[int] -- set a seed percentage (1-9999). 100 = 1% Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b sd g[int] -- set a growth percentage (1-9999). Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b sd r[int] -- set a recursion (1-10). Default is 3");
return;
}
else if (parameter.startsWith("s"))
{
final double temp = Integer.parseInt(parameter.replace("s", ""));
if (temp >= SEED_PERCENT_MIN && temp <= SEED_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Seed percent set to: " + temp / 100 + "%");
this.seedPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Seed percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("g"))
{
final double temp = Integer.parseInt(parameter.replace("g", ""));
if (temp >= GROW_PERCENT_MIN && temp <= GROW_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Growth percent set to: " + temp / 100 + "%");
this.growPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Growth percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("r"))
{
final int temp = Integer.parseInt(parameter.replace("r", ""));
if (temp >= SPLATREC_PERCENT_MIN && temp <= SPLATREC_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Recursions set to: " + temp);
this.splatterRecursions = temp;
}
else
{
v.sendMessage(ChatColor.RED + "Recursions must be an integer 1-10!");
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.splatterdisc";
}
}

Datei anzeigen

@ -0,0 +1,453 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import java.util.Random;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Splatter_Overlay_Brush
*
* @author Gavjenks Splatterized blockPositionY Giltwist
*/
public class SplatterOverlayBrush extends PerformBrush
{
private static final int GROW_PERCENT_MIN = 1;
private static final int GROW_PERCENT_DEFAULT = 1000;
private static final int GROW_PERCENT_MAX = 9999;
private static final int SEED_PERCENT_MIN = 1;
private static final int SEED_PERCENT_DEFAULT = 1000;
private static final int SEED_PERCENT_MAX = 9999;
private static final int SPLATREC_PERCENT_MIN = 1;
private static final int SPLATREC_PERCENT_DEFAULT = 3;
private static final int SPLATREC_PERCENT_MAX = 10;
private int seedPercent; // Chance block on first pass is made active
private int growPercent; // chance block on recursion pass is made active
private int splatterRecursions; // How many times you grow the seeds
private int yOffset = 0;
private boolean randomizeHeight = false;
private Random generator = new Random();
private int depth = 3;
private boolean allBlocks = false;
/**
*
*/
public SplatterOverlayBrush()
{
this.setName("Splatter Overlay");
}
@SuppressWarnings("deprecation")
private void sOverlay(final SnipeData v)
{
// Splatter Time
final int[][] splat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
// Seed the array
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
if (this.generator.nextInt(SEED_PERCENT_MAX + 1) <= this.seedPercent)
{
splat[x][y] = 1;
}
}
}
// Grow the seeds
final int gref = this.growPercent;
final int[][] tempSplat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
int growcheck;
for (int r = 0; r < this.splatterRecursions; r++)
{
this.growPercent = gref - ((gref / this.splatterRecursions) * (r));
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
tempSplat[x][y] = splat[x][y]; // prime tempsplat
growcheck = 0;
if (splat[x][y] == 0)
{
if (x != 0 && splat[x - 1][y] == 1)
{
growcheck++;
}
if (y != 0 && splat[x][y - 1] == 1)
{
growcheck++;
}
if (x != 2 * v.getBrushSize() && splat[x + 1][y] == 1)
{
growcheck++;
}
if (y != 2 * v.getBrushSize() && splat[x][y + 1] == 1)
{
growcheck++;
}
}
if (growcheck >= 1 && this.generator.nextInt(GROW_PERCENT_MAX + 1) <= this.growPercent)
{
tempSplat[x][y] = 1; // prevent bleed into splat
}
}
}
// integrate tempsplat back into splat at end of iteration
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
splat[x][y] = tempSplat[x][y];
}
}
}
this.growPercent = gref;
final int[][] memory = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
final double brushSizeSquared = Math.pow(v.getBrushSize() + 0.5, 2);
for (int z = v.getBrushSize(); z >= -v.getBrushSize(); z--)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = this.getTargetBlock().getY(); y > 0; y--)
{
// start scanning from the height you clicked at
if (memory[x + v.getBrushSize()][z + v.getBrushSize()] != 1)
{
// if haven't already found the surface in this column
if ((Math.pow(x, 2) + Math.pow(z, 2)) <= brushSizeSquared && splat[x + v.getBrushSize()][z + v.getBrushSize()] == 1)
{
// if inside of the column && if to be splattered
final int check = this.getBlockIdAt(this.getTargetBlock().getX() + x, y + 1, this.getTargetBlock().getZ() + z);
if (check == 0 || check == 8 || check == 9)
{
// must start at surface... this prevents it filling stuff in if you click in a wall
// and it starts out below surface.
if (!this.allBlocks)
{
// if the override parameter has not been activated, go to the switch that filters out manmade stuff.
BlockTypes type = BlockTypes.get(this.getBlockIdAt(this.getTargetBlock().getX() + x, y, this.getTargetBlock().getZ() + z));
BlockMaterial mat = type.getMaterial();
if (mat.isSolid() && mat.isFullCube() && !mat.hasContainer()) {
final int depth = randomizeHeight ? generator.nextInt(this.depth) : this.depth;
for (int d = this.depth - 1; ((this.depth - d) <= depth); d--) {
if (this.clampY(this.getTargetBlock().getX() + x, y - d, this.getTargetBlock().getZ() + z).getTypeId() != 0) {
// fills down as many layers as you specify in parameters
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y - d + yOffset, this.getTargetBlock().getZ() + z));
// stop it from checking any other blocks in this vertical 1x1 column.
memory[x + v.getBrushSize()][z + v.getBrushSize()] = 1;
}
}
continue;
} else {
continue;
}
}
else
{
final int depth = randomizeHeight ? generator.nextInt(this.depth) : this.depth;
for (int d = this.depth - 1; ((this.depth - d) <= depth); d--)
{
if (this.clampY(this.getTargetBlock().getX() + x, y - d, this.getTargetBlock().getZ() + z).getTypeId() != 0)
{
// fills down as many layers as you specify in parameters
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y - d + yOffset, this.getTargetBlock().getZ() + z));
// stop it from checking any other blocks in this vertical 1x1 column.
memory[x + v.getBrushSize()][z + v.getBrushSize()] = 1;
}
}
}
}
}
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
private void soverlayTwo(final SnipeData v)
{
// Splatter Time
final int[][] splat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
// Seed the array
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
if (this.generator.nextInt(SEED_PERCENT_MAX + 1) <= this.seedPercent)
{
splat[x][y] = 1;
}
}
}
// Grow the seeds
final int gref = this.growPercent;
final int[][] tempsplat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
int growcheck;
for (int r = 0; r < this.splatterRecursions; r++)
{
this.growPercent = gref - ((gref / this.splatterRecursions) * (r));
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
tempsplat[x][y] = splat[x][y]; // prime tempsplat
growcheck = 0;
if (splat[x][y] == 0)
{
if (x != 0 && splat[x - 1][y] == 1)
{
growcheck++;
}
if (y != 0 && splat[x][y - 1] == 1)
{
growcheck++;
}
if (x != 2 * v.getBrushSize() && splat[x + 1][y] == 1)
{
growcheck++;
}
if (y != 2 * v.getBrushSize() && splat[x][y + 1] == 1)
{
growcheck++;
}
}
if (growcheck >= 1 && this.generator.nextInt(GROW_PERCENT_MAX + 1) <= this.growPercent)
{
tempsplat[x][y] = 1; // prevent bleed into splat
}
}
}
// integrate tempsplat back into splat at end of iteration
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
splat[x][y] = tempsplat[x][y];
}
}
}
this.growPercent = gref;
final int[][] memory = new int[v.getBrushSize() * 2 + 1][v.getBrushSize() * 2 + 1];
final double brushSizeSquared = Math.pow(v.getBrushSize() + 0.5, 2);
for (int z = v.getBrushSize(); z >= -v.getBrushSize(); z--)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = this.getTargetBlock().getY(); y > 0; y--)
{ // start scanning from the height you clicked at
if (memory[x + v.getBrushSize()][z + v.getBrushSize()] != 1)
{ // if haven't already found the surface in this column
if ((Math.pow(x, 2) + Math.pow(z, 2)) <= brushSizeSquared && splat[x + v.getBrushSize()][z + v.getBrushSize()] == 1)
{ // if inside of the column...&& if to be splattered
if (this.getBlockIdAt(this.getTargetBlock().getX() + x, y - 1, this.getTargetBlock().getZ() + z) != 0)
{ // if not a floating block (like one of Notch'world pools)
if (this.getBlockIdAt(this.getTargetBlock().getX() + x, y + 1, this.getTargetBlock().getZ() + z) == 0)
{ // must start at surface... this prevents it filling stuff in if
// you click in a wall and it starts out below surface.
if (!this.allBlocks)
{ // if the override parameter has not been activated, go to the switch that filters out manmade stuff.
BlockTypes type = BlockTypes.get(this.getBlockIdAt(this.getTargetBlock().getX() + x, y, this.getTargetBlock().getZ() + z));
BlockMaterial mat = type.getMaterial();
if (mat.isSolid() && mat.isFullCube() && !mat.hasContainer())
{
final int depth = randomizeHeight ? generator.nextInt(this.depth) : this.depth;
for (int d = 1; (d < depth + 1); d++) {
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y + d + yOffset, this.getTargetBlock().getZ() + z)); // fills down as many layers as you specify
// in parameters
memory[x + v.getBrushSize()][z + v.getBrushSize()] = 1; // stop it from checking any other blocks in this vertical 1x1 column.
}
continue;
} else {
continue;
}
}
else
{
final int depth = randomizeHeight ? generator.nextInt(this.depth) : this.depth;
for (int d = 1; (d < depth + 1); d++)
{
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y + d + yOffset, this.getTargetBlock().getZ() + z)); // fills down as many layers as you specify in
// parameters
memory[x + v.getBrushSize()][z + v.getBrushSize()] = 1; // stop it from checking any other blocks in this vertical 1x1 column.
}
}
}
}
}
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.sOverlay(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.soverlayTwo(v);
}
@Override
public final void info(final Message vm)
{
if (this.seedPercent < SEED_PERCENT_MIN || this.seedPercent > SEED_PERCENT_MAX)
{
this.seedPercent = SEED_PERCENT_DEFAULT;
}
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
this.growPercent = GROW_PERCENT_DEFAULT;
}
if (this.splatterRecursions < SPLATREC_PERCENT_MIN || this.splatterRecursions > SPLATREC_PERCENT_MAX)
{
this.splatterRecursions = SPLATREC_PERCENT_DEFAULT;
}
vm.brushName(this.getName());
vm.size();
vm.custom(ChatColor.BLUE + "Seed percent set to: " + this.seedPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Growth percent set to: " + this.growPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Recursions set to: " + this.splatterRecursions);
vm.custom(ChatColor.BLUE + "Y-Offset set to: " + this.yOffset);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
try
{
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Splatter Overlay brush parameters:");
v.sendMessage(ChatColor.AQUA + "d[number] (ex: d3) How many blocks deep you want to replace from the surface.");
v.sendMessage(ChatColor.BLUE + "all (ex: /b over all) Sets the brush to overlay over ALL materials, not just natural surface ones (will no longer ignore trees and buildings). The parameter /some will set it back to default.");
v.sendMessage(ChatColor.AQUA + "/b sover s[int] -- set a seed percentage (1-9999). 100 = 1% Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b sover g[int] -- set a growth percentage (1-9999). Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b sover r[int] -- set a recursion (1-10). Default is 3");
return;
}
else if (parameter.startsWith("d"))
{
this.depth = Integer.parseInt(parameter.replace("d", ""));
v.sendMessage(ChatColor.AQUA + "Depth set to " + this.depth);
if (this.depth < 1)
{
this.depth = 1;
}
}
else if (parameter.startsWith("all"))
{
this.allBlocks = true;
v.sendMessage(ChatColor.BLUE + "Will overlay over any block." + this.depth);
}
else if (parameter.startsWith("some"))
{
this.allBlocks = false;
v.sendMessage(ChatColor.BLUE + "Will overlay only natural block types." + this.depth);
}
else if (par[i].startsWith("s"))
{
final double temp = Integer.parseInt(parameter.replace("s", ""));
if (temp >= SEED_PERCENT_MIN && temp <= SEED_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Seed percent set to: " + temp / 100 + "%");
this.seedPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Seed percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("g"))
{
final double temp = Integer.parseInt(parameter.replace("g", ""));
if (temp >= GROW_PERCENT_MIN && temp <= GROW_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Growth percent set to: " + temp / 100 + "%");
this.growPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Growth percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("randh"))
{
randomizeHeight = !randomizeHeight;
v.sendMessage(ChatColor.RED + "RandomizeHeight set to: " + randomizeHeight);
}
else if (parameter.startsWith("r"))
{
final int temp = Integer.parseInt(parameter.replace("r", ""));
if (temp >= SPLATREC_PERCENT_MIN && temp <= SPLATREC_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Recursions set to: " + temp);
this.splatterRecursions = temp;
}
else
{
v.sendMessage(ChatColor.RED + "Recursions must be an integer 1-10!");
}
}
else if (parameter.startsWith("yoff"))
{
final int temp = Integer.parseInt(parameter.replace("yoff", ""));
if (temp >= SPLATREC_PERCENT_MIN && temp <= SPLATREC_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Y-Offset set to: " + temp);
this.yOffset = temp;
}
else
{
v.sendMessage(ChatColor.RED + "Recursions must be an integer 1-10!");
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
catch (Exception exception)
{
v.sendMessage(String.format("An error occured while processing parameter %s.", parameter));
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.splatteroverlay";
}
}

Datei anzeigen

@ -0,0 +1,274 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import java.util.Random;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Splatter_Brushes
*
* @author Voxel
*/
public class SplatterVoxelBrush extends PerformBrush
{
private static final int GROW_PERCENT_MIN = 1;
private static final int GROW_PERCENT_DEFAULT = 1000;
private static final int GROW_PERCENT_MAX = 9999;
private static final int SEED_PERCENT_MIN = 1;
private static final int SEED_PERCENT_DEFAULT = 1000;
private static final int SEED_PERCENT_MAX = 9999;
private static final int SPLATREC_PERCENT_MIN = 1;
private static final int SPLATREC_PERCENT_DEFAULT = 3;
private static final int SPLATREC_PERCENT_MAX = 10;
private int seedPercent; // Chance block on first pass is made active
private int growPercent; // chance block on recursion pass is made active
private int splatterRecursions; // How many times you grow the seeds
private Random generator = new Random();
/**
*
*/
public SplatterVoxelBrush()
{
this.setName("Splatter Voxel");
}
private void vSplatterBall(final SnipeData v, AsyncBlock targetBlock)
{
if (this.seedPercent < SEED_PERCENT_MIN || this.seedPercent > SEED_PERCENT_MAX)
{
v.sendMessage(ChatColor.BLUE + "Seed percent set to: 10%");
this.seedPercent = SEED_PERCENT_DEFAULT;
}
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
v.sendMessage(ChatColor.BLUE + "Growth percent set to: 10%");
this.growPercent = GROW_PERCENT_DEFAULT;
}
if (this.splatterRecursions < SPLATREC_PERCENT_MIN || this.splatterRecursions > SPLATREC_PERCENT_MAX)
{
v.sendMessage(ChatColor.BLUE + "Recursions set to: 3");
this.splatterRecursions = SPLATREC_PERCENT_DEFAULT;
}
final int[][][] splat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
// Seed the array
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
if (this.generator.nextInt(SEED_PERCENT_MAX + 1) <= this.seedPercent)
{
splat[x][y][z] = 1;
}
}
}
}
// Grow the seeds
final int gref = this.growPercent;
final int[][][] tempSplat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
int growcheck;
for (int r = 0; r < this.splatterRecursions; r++)
{
this.growPercent = gref - ((gref / this.splatterRecursions) * (r));
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
tempSplat[x][y][z] = splat[x][y][z]; // prime tempsplat
growcheck = 0;
if (splat[x][y][z] == 0)
{
if (x != 0 && splat[x - 1][y][z] == 1)
{
growcheck++;
}
if (y != 0 && splat[x][y - 1][z] == 1)
{
growcheck++;
}
if (z != 0 && splat[x][y][z - 1] == 1)
{
growcheck++;
}
if (x != 2 * v.getBrushSize() && splat[x + 1][y][z] == 1)
{
growcheck++;
}
if (y != 2 * v.getBrushSize() && splat[x][y + 1][z] == 1)
{
growcheck++;
}
if (z != 2 * v.getBrushSize() && splat[x][y][z + 1] == 1)
{
growcheck++;
}
}
if (growcheck >= 1 && this.generator.nextInt(GROW_PERCENT_MAX + 1) <= this.growPercent)
{
tempSplat[x][y][z] = 1; // prevent bleed into splat
}
}
}
}
// integrate tempsplat back into splat at end of iteration
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
splat[x][y][z] = tempSplat[x][y][z];
}
}
}
}
this.growPercent = gref;
// Fill 1x1x1 holes
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
if (splat[Math.max(x - 1, 0)][y][z] == 1 && splat[Math.min(x + 1, 2 * v.getBrushSize())][y][z] == 1 && splat[x][Math.max(0, y - 1)][z] == 1 && splat[x][Math.min(2 * v.getBrushSize(), y + 1)][z] == 1)
{
splat[x][y][z] = 1;
}
}
}
}
// Make the changes
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
for (int z = 2 * v.getBrushSize(); z >= 0; z--)
{
if (splat[x][y][z] == 1)
{
current.perform(targetBlock.getRelative(-v.getBrushSize() + x, -v.getBrushSize() + z, -v.getBrushSize() + y));
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.vSplatterBall(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.vSplatterBall(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
if (this.seedPercent < SEED_PERCENT_MIN || this.seedPercent > SEED_PERCENT_MAX)
{
this.seedPercent = SEED_PERCENT_DEFAULT;
}
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
this.growPercent = GROW_PERCENT_DEFAULT;
}
if (this.splatterRecursions < SPLATREC_PERCENT_MIN || this.splatterRecursions > SPLATREC_PERCENT_MAX)
{
this.splatterRecursions = SPLATREC_PERCENT_DEFAULT;
}
vm.brushName("Splatter Voxel");
vm.size();
vm.custom(ChatColor.BLUE + "Seed percent set to: " + this.seedPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Growth percent set to: " + this.growPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Recursions set to: " + this.splatterRecursions);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Splatter Voxel brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b sv s[int] -- set a seed percentage (1-9999). 100 = 1% Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b sv g[int] -- set a growth percentage (1-9999). Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b sv r[int] -- set a recursion (1-10). Default is 3");
return;
}
else if (parameter.startsWith("s"))
{
final double temp = Integer.parseInt(parameter.replace("s", ""));
if (temp >= SEED_PERCENT_MIN && temp <= SEED_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Seed percent set to: " + temp / 100 + "%");
this.seedPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Seed percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("g"))
{
final double temp = Integer.parseInt(parameter.replace("g", ""));
if (temp >= GROW_PERCENT_MIN && temp <= GROW_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Growth percent set to: " + temp / 100 + "%");
this.growPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Growth percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("r"))
{
final int temp = Integer.parseInt(parameter.replace("r", ""));
if (temp >= SPLATREC_PERCENT_MIN && temp <= SPLATREC_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Recursions set to: " + temp);
this.splatterRecursions = temp;
}
else
{
v.sendMessage(ChatColor.RED + "Recursions must be an integer 1-10!");
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.splattervoxel";
}
}

Datei anzeigen

@ -0,0 +1,250 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import java.util.Random;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Splatter_Brushes
*
* @author Voxel
*/
public class SplatterVoxelDiscBrush extends PerformBrush
{
private static final int GROW_PERCENT_MIN = 1;
private static final int GROW_PERCENT_DEFAULT = 1000;
private static final int GROW_PERCENT_MAX = 9999;
private static final int SEED_PERCENT_MIN = 1;
private static final int SEED_PERCENT_DEFAULT = 1000;
private static final int SEED_PERCENT_MAX = 9999;
private static final int SPLATREC_PERCENT_MIN = 1;
private static final int SPLATREC_PERCENT_DEFAULT = 3;
private static final int SPLATREC_PERCENT_MAX = 10;
private int seedPercent; // Chance block on first pass is made active
private int growPercent; // chance block on recursion pass is made active
private int splatterRecursions; // How many times you grow the seeds
private Random generator = new Random();
/**
*
*/
public SplatterVoxelDiscBrush()
{
this.setName("Splatter Voxel Disc");
}
private void vSplatterDisc(final SnipeData v, Block targetBlock)
{
if (this.seedPercent < SEED_PERCENT_MIN || this.seedPercent > SEED_PERCENT_MAX)
{
v.sendMessage(ChatColor.BLUE + "Seed percent set to: 10%");
this.seedPercent = SEED_PERCENT_DEFAULT;
}
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
v.sendMessage(ChatColor.BLUE + "Growth percent set to: 10%");
this.growPercent = GROW_PERCENT_DEFAULT;
}
if (this.splatterRecursions < SPLATREC_PERCENT_MIN || this.splatterRecursions > SPLATREC_PERCENT_MAX)
{
v.sendMessage(ChatColor.BLUE + "Recursions set to: 3");
this.splatterRecursions = SPLATREC_PERCENT_DEFAULT;
}
final int[][] splat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
// Seed the array
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
if (this.generator.nextInt(SEED_PERCENT_MAX + 1) <= this.seedPercent)
{
splat[x][y] = 1;
}
}
}
// Grow the seeds
final int gref = this.growPercent;
final int[][] tempSplat = new int[2 * v.getBrushSize() + 1][2 * v.getBrushSize() + 1];
int growcheck;
for (int r = 0; r < this.splatterRecursions; r++)
{
this.growPercent = gref - ((gref / this.splatterRecursions) * (r));
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
tempSplat[x][y] = splat[x][y]; // prime tempsplat
growcheck = 0;
if (splat[x][y] == 0)
{
if (x != 0 && splat[x - 1][y] == 1)
{
growcheck++;
}
if (y != 0 && splat[x][y - 1] == 1)
{
growcheck++;
}
if (x != 2 * v.getBrushSize() && splat[x + 1][y] == 1)
{
growcheck++;
}
if (y != 2 * v.getBrushSize() && splat[x][y + 1] == 1)
{
growcheck++;
}
}
if (growcheck >= 1 && this.generator.nextInt(GROW_PERCENT_MAX + 1) <= this.growPercent)
{
tempSplat[x][y] = 1; // prevent bleed into splat
}
}
}
// integrate tempsplat back into splat at end of iteration
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
splat[x][y] = tempSplat[x][y];
}
}
}
this.growPercent = gref;
// Fill 1x1 holes
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
if (splat[Math.max(x - 1, 0)][y] == 1 && splat[Math.min(x + 1, 2 * v.getBrushSize())][y] == 1 && splat[x][Math.max(0, y - 1)] == 1 && splat[x][Math.min(2 * v.getBrushSize(), y + 1)] == 1)
{
splat[x][y] = 1;
}
}
}
// Make the changes
for (int x = 2 * v.getBrushSize(); x >= 0; x--)
{
for (int y = 2 * v.getBrushSize(); y >= 0; y--)
{
if (splat[x][y] == 1)
{
this.current.perform(this.clampY(targetBlock.getX() - v.getBrushSize() + x, targetBlock.getY(), targetBlock.getZ() - v.getBrushSize() + y));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.vSplatterDisc(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.vSplatterDisc(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
if (this.seedPercent < SEED_PERCENT_MIN || this.seedPercent > SEED_PERCENT_MAX)
{
this.seedPercent = SEED_PERCENT_DEFAULT;
}
if (this.growPercent < GROW_PERCENT_MIN || this.growPercent > GROW_PERCENT_MAX)
{
this.growPercent = GROW_PERCENT_DEFAULT;
}
if (this.splatterRecursions < SPLATREC_PERCENT_MIN || this.splatterRecursions > SPLATREC_PERCENT_MAX)
{
this.splatterRecursions = SPLATREC_PERCENT_DEFAULT;
}
vm.brushName("Splatter Voxel Disc");
vm.size();
vm.custom(ChatColor.BLUE + "Seed percent set to: " + this.seedPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Growth percent set to: " + this.growPercent / 100 + "%");
vm.custom(ChatColor.BLUE + "Recursions set to: " + this.splatterRecursions);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i];
if (parameter.equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Splatter Voxel Disc brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b svd s[int] -- set a seed percentage (1-9999). 100 = 1% Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b svd g[int] -- set a growth percentage (1-9999). Default is 1000");
v.sendMessage(ChatColor.AQUA + "/b svd r[int] -- set a recursion (1-10). Default is 3");
return;
}
else if (parameter.startsWith("s"))
{
final double temp = Integer.parseInt(parameter.replace("s", ""));
if (temp >= SEED_PERCENT_MIN && temp <= SEED_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Seed percent set to: " + temp / 100 + "%");
this.seedPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Seed percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("g"))
{
final double temp = Integer.parseInt(parameter.replace("g", ""));
if (temp >= GROW_PERCENT_MIN && temp <= GROW_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Growth percent set to: " + temp / 100 + "%");
this.growPercent = (int) temp;
}
else
{
v.sendMessage(ChatColor.RED + "Growth percent must be an integer 1-9999!");
}
}
else if (parameter.startsWith("r"))
{
final int temp = Integer.parseInt(parameter.replace("r", ""));
if (temp >= SPLATREC_PERCENT_MIN && temp <= SPLATREC_PERCENT_MAX)
{
v.sendMessage(ChatColor.AQUA + "Recursions set to: " + temp);
this.splatterRecursions = temp;
}
else
{
v.sendMessage(ChatColor.RED + "Recursions must be an integer 1-10!");
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.splattervoxeldisc";
}
}

Datei anzeigen

@ -0,0 +1,313 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import java.util.ArrayList;
/**
* FOR ANY BRUSH THAT USES A SPLINE, EXTEND THAT BRUSH FROM THIS BRUSH!!! That way, the spline calculations are already there. Also, the UI for
* the splines will be included.
*
* @author psanker
*/
public class SplineBrush extends PerformBrush
{
private final ArrayList<Block> endPts = new ArrayList<Block>();
private final ArrayList<Block> ctrlPts = new ArrayList<Block>();
protected ArrayList<Point> spline = new ArrayList<Point>();
protected boolean set;
protected boolean ctrl;
protected String[] sparams = {"ss", "sc", "clear"};
public SplineBrush()
{
this.setName("Spline");
}
public final void addToSet(final SnipeData v, final boolean ep, Block targetBlock)
{
if (ep)
{
if (this.endPts.contains(targetBlock) || this.endPts.size() == 2)
{
return;
}
this.endPts.add(targetBlock);
v.sendMessage(ChatColor.GRAY + "Added block " + ChatColor.RED + "(" + targetBlock.getX() + ", " + targetBlock.getY() + ", " + targetBlock.getZ() + ") " + ChatColor.GRAY + "to endpoint selection");
return;
}
if (this.ctrlPts.contains(targetBlock) || this.ctrlPts.size() == 2)
{
return;
}
this.ctrlPts.add(targetBlock);
v.sendMessage(ChatColor.GRAY + "Added block " + ChatColor.RED + "(" + targetBlock.getX() + ", " + targetBlock.getY() + ", " + targetBlock.getZ() + ") " + ChatColor.GRAY
+ "to control point selection");
}
public final void removeFromSet(final SnipeData v, final boolean ep, Block targetBlock)
{
if (ep)
{
if (!this.endPts.contains(targetBlock))
{
v.sendMessage(ChatColor.RED + "That block is not in the endpoint selection set.");
return;
}
this.endPts.add(targetBlock);
v.sendMessage(ChatColor.GRAY + "Removed block " + ChatColor.RED + "(" + targetBlock.getX() + ", " + targetBlock.getY() + ", " + targetBlock.getZ() + ") " + ChatColor.GRAY
+ "from endpoint selection");
return;
}
if (!this.ctrlPts.contains(targetBlock))
{
v.sendMessage(ChatColor.RED + "That block is not in the control point selection set.");
return;
}
this.ctrlPts.remove(targetBlock);
v.sendMessage(ChatColor.GRAY + "Removed block " + ChatColor.RED + "(" + targetBlock.getX() + ", " + targetBlock.getY() + ", " + targetBlock.getZ() + ") " + ChatColor.GRAY
+ "from control point selection");
}
public final boolean spline(final Point start, final Point end, final Point c1, final Point c2, final SnipeData v)
{
this.spline.clear();
try
{
final Point c = (c1.subtract(start)).multiply(3);
final Point b = ((c2.subtract(c1)).multiply(3)).subtract(c);
final Point a = ((end.subtract(start)).subtract(c)).subtract(b);
for (double t = 0.0; t < 1.0; t += 0.01)
{
final int px = (int) Math.round((a.getX() * (t * t * t)) + (b.getX() * (t * t)) + (c.getX() * t) + this.endPts.get(0).getX());
final int py = (int) Math.round((a.getY() * (t * t * t)) + (b.getY() * (t * t)) + (c.getY() * t) + this.endPts.get(0).getY());
final int pz = (int) Math.round((a.getZ() * (t * t * t)) + (b.getZ() * (t * t)) + (c.getZ() * t) + this.endPts.get(0).getZ());
if (!this.spline.contains(new Point(px, py, pz)))
{
this.spline.add(new Point(px, py, pz));
}
}
return true;
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Not enough points selected; " + this.endPts.size() + " endpoints, " + this.ctrlPts.size() + " control points");
return false;
}
}
protected final void render(final SnipeData v)
{
if (this.spline.isEmpty())
{
return;
}
for (final Point point : this.spline)
{
this.current.perform(this.clampY(point.getX(), point.getY(), point.getZ()));
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
if (this.set)
{
this.removeFromSet(v, true, this.getTargetBlock());
}
else if (this.ctrl)
{
this.removeFromSet(v, false, this.getTargetBlock());
}
}
protected final void clear(final SnipeData v)
{
this.spline.clear();
this.ctrlPts.clear();
this.endPts.clear();
v.sendMessage(ChatColor.GRAY + "Bezier curve cleared.");
}
@Override
protected final void powder(final SnipeData v)
{
if (this.set)
{
this.addToSet(v, true, this.getTargetBlock());
}
if (this.ctrl)
{
this.addToSet(v, false, this.getTargetBlock());
}
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
if (this.set)
{
vm.custom(ChatColor.GRAY + "Endpoint selection mode ENABLED.");
}
else if (this.ctrl)
{
vm.custom(ChatColor.GRAY + "Control point selection mode ENABLED.");
}
else
{
vm.custom(ChatColor.AQUA + "No selection mode enabled.");
}
}
@Override
public final void parameters(final String[] par, final com.thevoxelbox.voxelsniper.SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
if (par[i].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Spline brush parameters");
v.sendMessage(ChatColor.AQUA + "ss: Enable endpoint selection mode for desired curve");
v.sendMessage(ChatColor.AQUA + "sc: Enable control point selection mode for desired curve");
v.sendMessage(ChatColor.AQUA + "clear: Clear out the curve selection");
v.sendMessage(ChatColor.AQUA + "ren: Render curve from control points");
return;
}
if (par[i].equalsIgnoreCase("sc"))
{
if (!this.ctrl)
{
this.set = false;
this.ctrl = true;
v.sendMessage(ChatColor.GRAY + "Control point selection mode ENABLED.");
}
else
{
this.ctrl = false;
v.sendMessage(ChatColor.AQUA + "Control point selection mode disabled.");
}
}
else if (par[i].equalsIgnoreCase("ss"))
{
if (!this.set)
{
this.set = true;
this.ctrl = false;
v.sendMessage(ChatColor.GRAY + "Endpoint selection mode ENABLED.");
}
else
{
this.set = false;
v.sendMessage(ChatColor.AQUA + "Endpoint selection mode disabled.");
}
}
else if (par[i].equalsIgnoreCase("clear"))
{
this.clear(v);
}
else if (par[i].equalsIgnoreCase("ren"))
{
if (this.spline(new Point(this.endPts.get(0)), new Point(this.endPts.get(1)), new Point(this.ctrlPts.get(0)), new Point(this.ctrlPts.get(1)), v))
{
this.render(v);
}
}
else
{
v.sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
// Vector class for splines
protected class Point
{
private int x;
private int y;
private int z;
public Point(final Block b)
{
this.setX(b.getX());
this.setY(b.getY());
this.setZ(b.getZ());
}
public Point(final int x, final int y, final int z)
{
this.setX(x);
this.setY(y);
this.setZ(z);
}
public final Point add(final Point p)
{
return new Point(this.getX() + p.getX(), this.getY() + p.getY(), this.getZ() + p.getZ());
}
public final Point multiply(final int scalar)
{
return new Point(this.getX() * scalar, this.getY() * scalar, this.getZ() * scalar);
}
public final Point subtract(final Point p)
{
return new Point(this.getX() - p.getX(), this.getY() - p.getY(), this.getZ() - p.getZ());
}
public int getX()
{
return x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
public int getZ()
{
return z;
}
public void setZ(int z)
{
this.z = z;
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.spline";
}
}

Datei anzeigen

@ -0,0 +1,348 @@
package com.thevoxelbox.voxelsniper.brush;
import java.util.HashSet;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
*
*/
public class StampBrush extends Brush
{
/**
* @author Voxel
*/
protected class BlockWrapper
{
public int id;
public int x;
public int y;
public int z;
public int d;
/**
* @param b
* @param blx
* @param bly
* @param blz
*/
@SuppressWarnings("deprecation")
public BlockWrapper(final AsyncBlock b, final int blx, final int bly, final int blz)
{
this.id = b.getTypeId();
this.d = b.getPropertyId();
this.x = blx;
this.y = bly;
this.z = blz;
}
}
/**
* @author Monofraps
*/
protected enum StampType
{
NO_AIR, FILL, DEFAULT
}
protected HashSet<BlockWrapper> clone = new HashSet<BlockWrapper>();
protected HashSet<BlockWrapper> fall = new HashSet<BlockWrapper>();
protected HashSet<BlockWrapper> drop = new HashSet<BlockWrapper>();
protected HashSet<BlockWrapper> solid = new HashSet<BlockWrapper>();
protected Undo undo;
protected boolean sorted = false;
protected StampType stamp = StampType.DEFAULT;
/**
*
*/
public StampBrush()
{
this.setName("Stamp");
}
/**
*
*/
public final void reSort()
{
this.sorted = false;
}
/**
* @param id
*
* @return
*/
protected final boolean falling(final int id)
{
return (id > 7 && id < 14);
}
/**
* @param id
*
* @return
*/
protected final boolean fallsOff(final int id)
{
return (BlockTypes.get(id).getMaterial().isFragileWhenPushed());
}
/**
* @param cb
*/
@SuppressWarnings("deprecation")
protected final void setBlock(final BlockWrapper cb)
{
final AsyncBlock block = this.clampY(this.getTargetBlock().getX() + cb.x, this.getTargetBlock().getY() + cb.y, this.getTargetBlock().getZ() + cb.z);
this.undo.put(block);
block.setTypeId(cb.id);
block.setPropertyId(cb.d);
}
/**
* @param cb
*/
@SuppressWarnings("deprecation")
protected final void setBlockFill(final BlockWrapper cb)
{
final AsyncBlock block = this.clampY(this.getTargetBlock().getX() + cb.x, this.getTargetBlock().getY() + cb.y, this.getTargetBlock().getZ() + cb.z);
if (block.isEmpty())
{
this.undo.put(block);
block.setTypeId(cb.id);
block.setPropertyId(cb.d);
}
}
/**
* @param type
*/
protected final void setStamp(final StampType type)
{
this.stamp = type;
}
/**
* @param v
*/
protected final void stamp(final SnipeData v)
{
this.undo = new Undo();
if (this.sorted)
{
for (final BlockWrapper block : this.solid)
{
this.setBlock(block);
}
for (final BlockWrapper block : this.drop)
{
this.setBlock(block);
}
for (final BlockWrapper block : this.fall)
{
this.setBlock(block);
}
}
else
{
this.fall.clear();
this.drop.clear();
this.solid.clear();
for (final BlockWrapper block : this.clone)
{
if (this.fallsOff(block.id))
{
this.fall.add(block);
}
else if (this.falling(block.id))
{
this.drop.add(block);
}
else
{
this.solid.add(block);
this.setBlock(block);
}
}
for (final BlockWrapper block : this.drop)
{
this.setBlock(block);
}
for (final BlockWrapper block : this.fall)
{
this.setBlock(block);
}
this.sorted = true;
}
v.owner().storeUndo(this.undo);
}
/**
* @param v
*/
protected final void stampFill(final SnipeData v)
{
this.undo = new Undo();
if (this.sorted)
{
for (final BlockWrapper block : this.solid)
{
this.setBlockFill(block);
}
for (final BlockWrapper block : this.drop)
{
this.setBlockFill(block);
}
for (final BlockWrapper block : this.fall)
{
this.setBlockFill(block);
}
}
else
{
this.fall.clear();
this.drop.clear();
this.solid.clear();
for (final BlockWrapper block : this.clone)
{
if (this.fallsOff(block.id))
{
this.fall.add(block);
}
else if (this.falling(block.id))
{
this.drop.add(block);
}
else if (block.id != 0)
{
this.solid.add(block);
this.setBlockFill(block);
}
}
for (final BlockWrapper block : this.drop)
{
this.setBlockFill(block);
}
for (final BlockWrapper block : this.fall)
{
this.setBlockFill(block);
}
this.sorted = true;
}
v.owner().storeUndo(this.undo);
}
/**
* @param v
*/
protected final void stampNoAir(final SnipeData v)
{
this.undo = new Undo();
if (this.sorted)
{
for (final BlockWrapper block : this.solid)
{
this.setBlock(block);
}
for (final BlockWrapper block : this.drop)
{
this.setBlock(block);
}
for (final BlockWrapper block : this.fall)
{
this.setBlock(block);
}
}
else
{
this.fall.clear();
this.drop.clear();
this.solid.clear();
for (final BlockWrapper block : this.clone)
{
if (this.fallsOff(block.id))
{
this.fall.add(block);
}
else if (this.falling(block.id))
{
this.drop.add(block);
}
else if (block.id != 0)
{
this.solid.add(block);
this.setBlock(block);
}
}
for (final BlockWrapper block : this.drop)
{
this.setBlock(block);
}
for (final BlockWrapper block : this.fall)
{
this.setBlock(block);
}
this.sorted = true;
}
v.owner().storeUndo(this.undo);
}
@Override
protected final void arrow(final SnipeData v)
{
switch (this.stamp)
{
case DEFAULT:
this.stamp(v);
break;
case NO_AIR:
this.stampNoAir(v);
break;
case FILL:
this.stampFill(v);
break;
default:
v.sendMessage(ChatColor.DARK_RED + "Error while stamping! Report");
break;
}
}
@Override
protected void powder(final SnipeData v)
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void info(final Message vm)
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.stamp";
}
}

Datei anzeigen

@ -0,0 +1,461 @@
package com.thevoxelbox.voxelsniper.brush;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.GZIPInputStream;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.io.PGZIPOutputStream;
import com.google.common.io.Files;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
/**
* This is paste only currently. Assumes files exist, and thus has no usefulness until I add in saving stencils later. Uses sniper-exclusive stencil format: 3
* shorts for X,Z,Y size of cuboid 3 shorts for X,Z,Y offsets from the -X,-Z,-Y corner. This is the reference point for pasting, corresponding to where you
* click your brush. 1 long integer saying how many runs of blocks are in the schematic (data is compressed into runs) 1 per run: ( 1 boolean: true = compressed
* line ahead, false = locally unique block ahead. This wastes a bit instead of a byte, and overall saves space, as long as at least 1/8 of all RUNS are going
* to be size 1, which in Minecraft is almost definitely true. IF boolean was true, next unsigned byte stores the number of consecutive blocks of the same type,
* up to 256. IF boolean was false, there is no byte here, goes straight to ID and data instead, which applies to just one block. 2 bytes to identify type of
* block. First byte is ID, second is data. This applies to every one of the line of consecutive blocks if boolean was true. )
*
* TODO: Make limit a config option
*
* @author Gavjenks
*/
public class StencilBrush extends Brush
{
private byte pasteOption = 1; // 0 = full, 1 = fill, 2 = replace
private String filename = "NoFileLoaded";
private short x;
private short z;
private short y;
private short xRef;
private short zRef;
private short yRef;
private byte pasteParam = 0;
private int[] firstPoint = new int[3];
private int[] secondPoint = new int[3];
private int[] pastePoint = new int[3];
private byte point = 1;
/**
*
*/
public StencilBrush()
{
this.setName("Stencil");
}
@SuppressWarnings("deprecation")
private void stencilPaste(final SnipeData v)
{
if (this.filename.matches("NoFileLoaded"))
{
v.sendMessage(ChatColor.RED + "You did not specify a filename. This is required.");
return;
}
final Undo undo = new Undo();
final File file = new File("plugins/VoxelSniper/stencils/" + this.filename + ".vstencil");
if (file.exists())
{
try
{
final FaweInputStream in = new FaweInputStream(new DataInputStream(new GZIPInputStream(new BufferedInputStream(new FileInputStream(file)))));
this.x = in.readShort();
this.z = in.readShort();
this.y = in.readShort();
this.xRef = in.readShort();
this.zRef = in.readShort();
this.yRef = in.readShort();
final int numRuns = in.readInt();
int currX = -this.xRef; // so if your ref point is +5 x, you want to start pasting -5 blocks from the clicked point (the reference) to get the
// corner, for example.
int currZ = -this.zRef;
int currY = -this.yRef;
int id;
int blockPositionX = getTargetBlock().getX();
int blockPositionY = getTargetBlock().getY();
int blockPositionZ = getTargetBlock().getZ();
if (this.pasteOption == 0)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = in.readVarInt();
for (int j = 0; j < numLoops; j++)
{
undo.put(this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ));
this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ).setCombinedId(id);
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
else
{
undo.put(this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ));
int combined = in.readVarInt();
this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ).setCombinedId(combined);
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
}
else if (this.pasteOption == 1)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readVarInt());
for (int j = 0; j < numLoops; j++)
{
if (!BlockTypes.getFromStateId(id).getMaterial().isAir() && this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ).isEmpty())
{
undo.put(this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ));
this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ).setCombinedId(id);
}
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readVarInt());
if (!BlockTypes.getFromStateId(id).getMaterial().isAir() && this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ).isEmpty())
{
undo.put(this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ));
// v.sendMessage("currX:" + currX + " currZ:"+currZ + " currY:" + currY + " id:" + id + " data:" + data);
this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ).setCombinedId(id);
}
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
}
else
{ // replace
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readVarInt());
for (int j = 0; j < (numLoops); j++)
{
if (!BlockTypes.getFromStateId(id).getMaterial().isAir())
{
undo.put(this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ));
this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ).setCombinedId(id);
}
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readVarInt());
if (id != 0)
{
undo.put(this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ));
this.clampY(blockPositionX + currX, blockPositionY + currY, blockPositionZ + currZ).setCombinedId(id);
}
currX++;
if (currX == this.x)
{
currX = 0;
currZ++;
if (currZ == this.z)
{
currZ = 0;
currY++;
}
}
}
}
}
in.close();
v.owner().storeUndo(undo);
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Something went wrong.");
exception.printStackTrace();
}
}
else
{
v.sendMessage(ChatColor.RED + "You need to type a stencil name / your specified stencil does not exist.");
}
}
@SuppressWarnings("deprecation")
private void stencilSave(final SnipeData v)
{
final File file = new File("plugins/VoxelSniper/stencils/" + this.filename + ".vstencil");
try
{
this.x = (short) (Math.abs((this.firstPoint[0] - this.secondPoint[0])) + 1);
this.z = (short) (Math.abs((this.firstPoint[1] - this.secondPoint[1])) + 1);
this.y = (short) (Math.abs((this.firstPoint[2] - this.secondPoint[2])) + 1);
this.xRef = (short) ((this.firstPoint[0] > this.secondPoint[0]) ? (this.pastePoint[0] - this.secondPoint[0]) : (this.pastePoint[0] - this.firstPoint[0]));
this.zRef = (short) ((this.firstPoint[1] > this.secondPoint[1]) ? (this.pastePoint[1] - this.secondPoint[1]) : (this.pastePoint[1] - this.firstPoint[1]));
this.yRef = (short) ((this.firstPoint[2] > this.secondPoint[2]) ? (this.pastePoint[2] - this.secondPoint[2]) : (this.pastePoint[2] - this.firstPoint[2]));
if ((this.x * this.y * this.z) > 50000)
{
v.sendMessage(ChatColor.AQUA + "Volume exceeds maximum limit.");
return;
}
Files.createParentDirs(file);
file.createNewFile();
final FaweOutputStream out = new FaweOutputStream(new DataOutputStream(new PGZIPOutputStream(new BufferedOutputStream(new FileOutputStream(file)))));
int blockPositionX = (this.firstPoint[0] > this.secondPoint[0]) ? this.secondPoint[0] : this.firstPoint[0];
int blockPositionZ = (this.firstPoint[1] > this.secondPoint[1]) ? this.secondPoint[1] : this.firstPoint[1];
int blockPositionY = (this.firstPoint[2] > this.secondPoint[2]) ? this.secondPoint[2] : this.firstPoint[2];
out.writeShort(this.x);
out.writeShort(this.z);
out.writeShort(this.y);
out.writeShort(this.xRef);
out.writeShort(this.zRef);
out.writeShort(this.yRef);
v.sendMessage(ChatColor.AQUA + "Volume: " + this.x * this.z * this.y + " blockPositionX:" + blockPositionX + " blockPositionZ:" + blockPositionZ + " blockPositionY:" + blockPositionY);
int[] blockArray = new int[this.x * this.z * this.y];
byte[] runSizeArray = new byte[this.x * this.z * this.y];
int lastId = (this.getWorld().getBlockAt(blockPositionX, blockPositionY, blockPositionZ).getCombinedId());
int thisId;
int counter = 0;
int arrayIndex = 0;
for (int y = 0; y < this.y; y++)
{
for (int z = 0; z < this.z; z++)
{
for (int x = 0; x < this.x; x++)
{
AsyncBlock currentBlock = getWorld().getBlockAt(blockPositionX + x, blockPositionY + y, blockPositionZ + z);
thisId = (currentBlock.getCombinedId());
if (thisId != lastId || counter == 255)
{
blockArray[arrayIndex] = lastId;
runSizeArray[arrayIndex] = (byte) (counter - 128);
arrayIndex++;
counter = 1;
lastId = thisId;
}
else
{
counter++;
lastId = thisId;
}
}
}
}
blockArray[arrayIndex] = lastId; // saving last run, which will always be left over.
runSizeArray[arrayIndex] = (byte) (counter - 128);
out.writeInt(arrayIndex + 1);
// v.sendMessage("number of runs = " + arrayIndex);
for (int i = 0; i < arrayIndex + 1; i++)
{
if (runSizeArray[i] > -127)
{
out.writeBoolean(true);
out.writeByte(runSizeArray[i]);
out.writeVarInt(blockArray[i]);
}
else
{
out.writeBoolean(false);
out.writeVarInt(blockArray[i]);
}
}
v.sendMessage(ChatColor.BLUE + "Saved as '" + this.filename + "'.");
out.close();
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Something went wrong.");
exception.printStackTrace();
}
}
@Override
protected final void arrow(final SnipeData v)
{ // will be used to copy/save later on?
if (this.point == 1)
{
this.firstPoint[0] = this.getTargetBlock().getX();
this.firstPoint[1] = this.getTargetBlock().getZ();
this.firstPoint[2] = this.getTargetBlock().getY();
v.sendMessage(ChatColor.GRAY + "First point");
v.sendMessage("X:" + this.firstPoint[0] + " Z:" + this.firstPoint[1] + " Y:" + this.firstPoint[2]);
this.point = 2;
}
else if (this.point == 2)
{
this.secondPoint[0] = this.getTargetBlock().getX();
this.secondPoint[1] = this.getTargetBlock().getZ();
this.secondPoint[2] = this.getTargetBlock().getY();
if ((Math.abs(this.firstPoint[0] - this.secondPoint[0]) * Math.abs(this.firstPoint[1] - this.secondPoint[1]) * Math.abs(this.firstPoint[2] - this.secondPoint[2])) > 5000000)
{
v.sendMessage(ChatColor.DARK_RED + "Area selected is too large. (Limit is 5,000,000 blocks)");
this.point = 1;
}
else
{
v.sendMessage(ChatColor.GRAY + "Second point");
v.sendMessage("X:" + this.secondPoint[0] + " Z:" + this.secondPoint[1] + " Y:" + this.secondPoint[2]);
this.point = 3;
}
}
else if (this.point == 3)
{
this.pastePoint[0] = this.getTargetBlock().getX();
this.pastePoint[1] = this.getTargetBlock().getZ();
this.pastePoint[2] = this.getTargetBlock().getY();
v.sendMessage(ChatColor.GRAY + "Paste Reference point");
v.sendMessage("X:" + this.pastePoint[0] + " Z:" + this.pastePoint[1] + " Y:" + this.pastePoint[2]);
this.point = 1;
this.stencilSave(v);
}
}
@Override
protected final void powder(final SnipeData v)
{ // will be used to paste later on
this.stencilPaste(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom("File loaded: " + this.filename);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Stencil brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b schem [optional: 'full' 'fill' or 'replace', with fill as default] [name] -- Loads the specified schematic. Allowed size of schematic is based on rank. Full/fill/replace must come first. Full = paste all blocks, fill = paste only into air blocks, replace = paste full blocks in only, but replace anything in their way.");
v.sendMessage(ChatColor.BLUE + "Size of the stencils you are allowed to paste depends on rank (member / lite, sniper, curator, admin)");
return;
}
else if (par[1].equalsIgnoreCase("full"))
{
this.pasteOption = 0;
this.pasteParam = 1;
}
else if (par[1].equalsIgnoreCase("fill"))
{
this.pasteOption = 1;
this.pasteParam = 1;
}
else if (par[1].equalsIgnoreCase("replace"))
{
this.pasteOption = 2;
this.pasteParam = 1;
}
try
{
this.filename = par[1 + this.pasteParam];
final File file = new File("plugins/VoxelSniper/stencils/" + this.filename + ".vstencil");
if (file.exists())
{
v.sendMessage(ChatColor.RED + "Stencil '" + this.filename + "' exists and was loaded. Make sure you are using powder if you do not want any chance of overwriting the file.");
}
else
{
v.sendMessage(ChatColor.AQUA + "Stencil '" + this.filename + "' does not exist. Ready to be saved to, but cannot be pasted.");
}
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "You need to type a stencil name.");
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.stencil";
}
}

Datei anzeigen

@ -0,0 +1,984 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import org.bukkit.ChatColor;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Scanner;
/**
* @author Gavjenks
*/
public class StencilListBrush extends Brush
{
private byte pasteOption = 1; // 0 = full, 1 = fill, 2 = replace
private String filename = "NoFileLoaded";
private short x;
private short z;
private short y;
private short xRef;
private short zRef;
private short yRef;
private byte pasteParam = 0;
private HashMap<Integer, String> stencilList = new HashMap<Integer, String>();
/**
*
*/
public StencilListBrush()
{
this.setName("StencilList");
}
private String readRandomStencil(final SnipeData v)
{
double rand = Math.random() * (this.stencilList.size());
final int choice = (int) rand;
return this.stencilList.get(choice);
}
private void readStencilList(final String listname, final SnipeData v)
{
final File file = new File("plugins/VoxelSniper/stencilLists/" + this.filename + ".txt");
if (file.exists())
{
try
{
final Scanner scanner = new Scanner(file);
int counter = 0;
while (scanner.hasNext())
{
this.stencilList.put(counter, scanner.nextLine());
counter++;
}
scanner.close();
}
catch (final Exception exception)
{
exception.printStackTrace();
}
}
}
@SuppressWarnings("deprecation")
private void stencilPaste(final SnipeData v)
{
if (this.filename.matches("NoFileLoaded"))
{
v.sendMessage(ChatColor.RED + "You did not specify a filename for the list. This is required.");
return;
}
final String stencilName = this.readRandomStencil(v);
v.sendMessage(stencilName);
final Undo undo = new Undo();
final File file = new File("plugins/VoxelSniper/stencils/" + stencilName + ".vstencil");
if (file.exists())
{
try
{
final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
this.x = in.readShort();
this.z = in.readShort();
this.y = in.readShort();
this.xRef = in.readShort();
this.zRef = in.readShort();
this.yRef = in.readShort();
final int numRuns = in.readInt();
// Something here that checks ranks using sanker'world thingie he added to Sniper and boots you out with error message if too big.
final int volume = this.x * this.y * this.z;
v.owner().getPlayer().sendMessage(ChatColor.AQUA + this.filename + " pasted. Volume is " + volume + " blocks.");
int currX = -this.xRef; // so if your ref point is +5 x, you want to start pasting -5 blocks from the clicked point (the reference) to get the
// corner, for example.
int currZ = -this.zRef;
int currY = -this.yRef;
int id;
int data;
if (this.pasteOption == 0)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < numLoops; j++)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
else
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId((in.readByte() + 128), (in.readByte() + 128), false);
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
}
else if (this.pasteOption == 1)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < numLoops; j++)
{
if (id != 0 && this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).isEmpty())
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, (data), false);
}
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readByte() + 128);
data = (in.readByte() + 128);
if (id != 0 && this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).isEmpty())
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, (data), false);
}
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
}
else
{ // replace
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < (numLoops); j++)
{
if (id != 0)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
}
currX++;
if (currX == this.x - this.xRef)
{
currX = -this.xRef;
currZ++;
if (currZ == this.z - this.zRef)
{
currZ = -this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readByte() + 128);
data = (in.readByte() + 128);
if (id != 0)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
}
currX++;
if (currX == this.x)
{
currX = 0;
currZ++;
if (currZ == this.z)
{
currZ = 0;
currY++;
}
}
}
}
}
in.close();
v.owner().storeUndo(undo);
}
catch (final Exception exception)
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
exception.printStackTrace();
}
}
else
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "You need to type a stencil name / your specified stencil does not exist.");
}
}
@SuppressWarnings("deprecation")
private void stencilPaste180(final SnipeData v)
{
if (this.filename.matches("NoFileLoaded"))
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "You did not specify a filename for the list. This is required.");
return;
}
final String stencilName = this.readRandomStencil(v);
final Undo undo = new Undo();
final File file = new File("plugins/VoxelSniper/stencils/" + stencilName + ".vstencil");
if (file.exists())
{
try
{
final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
this.x = in.readShort();
this.z = in.readShort();
this.y = in.readShort();
this.xRef = in.readShort();
this.zRef = in.readShort();
this.yRef = in.readShort();
final int numRuns = in.readInt();
// Something here that checks ranks using sanker'world thingie he added to Sniper and boots you out with error message if too big.
final int volume = this.x * this.y * this.z;
v.owner().getPlayer().sendMessage(ChatColor.AQUA + this.filename + " pasted. Volume is " + volume + " blocks.");
int currX = +this.xRef; // so if your ref point is +5 x, you want to start pasting -5 blocks from the clicked point (the reference) to get the
// corner, for example.
int currZ = +this.zRef;
int currY = -this.yRef;
int id;
int data;
if (this.pasteOption == 0)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < numLoops; j++)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
currX--;
if (currX == -this.x + this.xRef)
{
currX = this.xRef;
currZ--;
if (currZ == -this.z + this.zRef)
{
currZ = +this.zRef;
currY++;
}
}
}
}
else
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId((in.readByte() + 128), (in.readByte() + 128), false);
currX--;
if (currX == -this.x + this.xRef)
{
currX = this.xRef;
currZ--;
if (currZ == -this.z + this.zRef)
{
currZ = +this.zRef;
currY++;
}
}
}
}
}
else if (this.pasteOption == 1)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < numLoops; j++)
{
if (id != 0 && this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).isEmpty())
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, (data), false);
}
currX--;
if (currX == -this.x + this.xRef)
{
currX = this.xRef;
currZ--;
if (currZ == -this.z + this.zRef)
{
currZ = +this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readByte() + 128);
data = (in.readByte() + 128);
if (id != 0 && this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).isEmpty())
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, (data), false);
}
currX--;
if (currX == -this.x + this.xRef)
{
currX = this.xRef;
currZ--;
if (currZ == -this.z + this.zRef)
{
currZ = +this.zRef;
currY++;
}
}
}
}
}
else
{ // replace
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < (numLoops); j++)
{
if (id != 0)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
}
currX--;
if (currX == -this.x + this.xRef)
{
currX = this.xRef;
currZ--;
if (currZ == -this.z + this.zRef)
{
currZ = +this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readByte() + 128);
data = (in.readByte() + 128);
if (id != 0)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
}
currX--;
if (currX == -this.x + this.xRef)
{
currX = this.xRef;
currZ--;
if (currZ == -this.z + this.zRef)
{
currZ = +this.zRef;
currY++;
}
}
}
}
}
in.close();
v.owner().storeUndo(undo);
}
catch (final Exception exception)
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
exception.printStackTrace();
}
}
else
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "You need to type a stencil name / your specified stencil does not exist.");
}
}
@SuppressWarnings("deprecation")
private void stencilPaste270(final SnipeData v)
{
if (this.filename.matches("NoFileLoaded"))
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "You did not specify a filename for the list. This is required.");
return;
}
final String stencilName = this.readRandomStencil(v);
final Undo undo = new Undo();
final File file = new File("plugins/VoxelSniper/stencils/" + stencilName + ".vstencil");
if (file.exists())
{
try
{
final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
this.x = in.readShort();
this.z = in.readShort();
this.y = in.readShort();
this.xRef = in.readShort();
this.zRef = in.readShort();
this.yRef = in.readShort();
final int numRuns = in.readInt();
// Something here that checks ranks using sanker'world thingie he added to Sniper and boots you out with error message if too big.
final int volume = this.x * this.y * this.z;
v.owner().getPlayer().sendMessage(ChatColor.AQUA + this.filename + " pasted. Volume is " + volume + " blocks.");
int currX = +this.zRef; // so if your ref point is +5 x, you want to start pasting -5 blocks from the clicked point (the reference) to get the
// corner, for example.
int currZ = -this.xRef;
int currY = -this.yRef;
int id;
int data;
if (this.pasteOption == 0)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < numLoops; j++)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
currZ++;
if (currZ == this.x - this.xRef)
{
currZ = -this.xRef;
currX--;
if (currX == -this.z + this.zRef)
{
currX = +this.zRef;
currY++;
}
}
}
}
else
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId((in.readByte() + 128), (in.readByte() + 128), false);
currZ++;
currZ++;
if (currZ == this.x - this.xRef)
{
currZ = -this.xRef;
currX--;
if (currX == -this.z + this.zRef)
{
currX = +this.zRef;
currY++;
}
}
}
}
}
else if (this.pasteOption == 1)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < numLoops; j++)
{
if (id != 0 && this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).isEmpty())
{ // no reason to paste air over
// air, and it prevents us
// most of the time from
// having to even check the
// block.
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, (data), false);
}
currZ++;
if (currZ == this.x - this.xRef)
{
currZ = -this.xRef;
currX--;
if (currX == -this.z + this.zRef)
{
currX = +this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readByte() + 128);
data = (in.readByte() + 128);
if (id != 0 && this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).isEmpty())
{ // no reason to paste air over
// air, and it prevents us most of
// the time from having to even
// check the block.
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, (data), false);
}
currZ++;
if (currZ == this.x - this.xRef)
{
currZ = -this.xRef;
currX--;
if (currX == -this.z + this.zRef)
{
currX = +this.zRef;
currY++;
}
}
}
}
}
else
{ // replace
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < (numLoops); j++)
{
if (id != 0)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
}
currZ++;
if (currZ == this.x - this.xRef)
{
currZ = -this.xRef;
currX--;
if (currX == -this.z + this.zRef)
{
currX = +this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readByte() + 128);
data = (in.readByte() + 128);
if (id != 0)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
}
currZ++;
if (currZ == this.x - this.xRef)
{
currZ = -this.xRef;
currX--;
if (currX == -this.z + this.zRef)
{
currX = +this.zRef;
currY++;
}
}
}
}
}
in.close();
v.owner().storeUndo(undo);
}
catch (final Exception exception)
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
exception.printStackTrace();
}
}
else
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "You need to type a stencil name / your specified stencil does not exist.");
}
}
@SuppressWarnings("deprecation")
private void stencilPaste90(final SnipeData v)
{
if (this.filename.matches("NoFileLoaded"))
{
v.sendMessage(ChatColor.RED + "You did not specify a filename for the list. This is required.");
return;
}
final String stencilName = this.readRandomStencil(v);
final Undo undo = new Undo();
final File file = new File("plugins/VoxelSniper/stencils/" + stencilName + ".vstencil");
if (file.exists())
{
try
{
final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
this.x = in.readShort();
this.z = in.readShort();
this.y = in.readShort();
this.xRef = in.readShort();
this.zRef = in.readShort();
this.yRef = in.readShort();
final int numRuns = in.readInt();
// Something here that checks ranks using sanker'world thingie he added to Sniper and boots you out with error message if too big.
final int volume = this.x * this.y * this.z;
v.sendMessage(ChatColor.AQUA + this.filename + " pasted. Volume is " + volume + " blocks.");
int currX = -this.zRef; // so if your ref point is +5 x, you want to start pasting -5 blocks from the clicked point (the reference) to get the
// corner, for example.
int currZ = +this.xRef;
int currY = -this.yRef;
int id;
int data;
if (this.pasteOption == 0)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < numLoops; j++)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
currZ--;
if (currZ == -this.x + this.xRef)
{
currZ = this.xRef;
currX++;
if (currX == this.z - this.zRef)
{
currX = -this.zRef;
currY++;
}
}
}
}
else
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId((in.readByte() + 128), (in.readByte() + 128), false);
currZ--;
if (currZ == -this.x + this.xRef)
{
currZ = this.xRef;
currX++;
if (currX == this.z - this.zRef)
{
currX = -this.zRef;
currY++;
}
}
}
}
}
else if (this.pasteOption == 1)
{
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < numLoops; j++)
{
if (id != 0 && this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).isEmpty())
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, (data), false);
}
currZ--;
if (currZ == -this.x + this.xRef)
{
currZ = this.xRef;
currX++;
if (currX == this.z - this.zRef)
{
currX = -this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readByte() + 128);
data = (in.readByte() + 128);
if (id != 0 && this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).isEmpty())
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, (data), false);
}
currZ--;
if (currZ == -this.x + this.xRef)
{
currZ = this.xRef;
currX++;
if (currX == this.z - this.zRef)
{
currX = -this.zRef;
currY++;
}
}
}
}
}
else
{ // replace
for (int i = 1; i < numRuns + 1; i++)
{
if (in.readBoolean())
{
final int numLoops = in.readByte() + 128;
id = (in.readByte() + 128);
data = (in.readByte() + 128);
for (int j = 0; j < (numLoops); j++)
{
if (id != 0)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
}
currZ--;
if (currZ == -this.x + this.xRef)
{
currZ = this.xRef;
currX++;
if (currX == this.z - this.zRef)
{
currX = -this.zRef;
currY++;
}
}
}
}
else
{
id = (in.readByte() + 128);
data = (in.readByte() + 128);
if (id != 0)
{
undo.put(this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ));
this.clampY(this.getTargetBlock().getX() + currX, this.getTargetBlock().getY() + currY, this.getTargetBlock().getZ() + currZ).setTypeIdAndPropertyId(id, data, false);
}
currZ--;
if (currZ == -this.x + this.xRef)
{
currZ = this.xRef;
currX++;
if (currX == this.z - this.zRef)
{
currX = -this.zRef;
currY++;
}
}
}
}
}
in.close();
v.owner().storeUndo(undo);
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "Something went wrong.");
exception.printStackTrace();
}
}
else
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "You need to type a stencil name / your specified stencil does not exist.");
}
}
private void stencilPasteRotation(final SnipeData v)
{
// just randomly chooses a rotation and then calls stencilPaste.
this.readStencilList(this.filename, v);
final double random = Math.random();
if (random < 0.26)
{
this.stencilPaste(v);
}
else if (random < 0.51)
{
this.stencilPaste90(v);
}
else if (random < 0.76)
{
this.stencilPaste180(v);
}
else
{
this.stencilPaste270(v);
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.stencilPaste(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.stencilPasteRotation(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.custom("File loaded: " + this.filename);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Stencil List brush Parameters:");
v.sendMessage(ChatColor.AQUA + "/b schem [optional: 'full' 'fill' or 'replace', with fill as default] [name] -- Loads the specified stencil list. Full/fill/replace must come first. Full = paste all blocks, fill = paste only into air blocks, replace = paste full blocks in only, but replace anything in their way.");
return;
}
else if (par[1].equalsIgnoreCase("full"))
{
this.pasteOption = 0;
this.pasteParam = 1;
}
else if (par[1].equalsIgnoreCase("fill"))
{
this.pasteOption = 1;
this.pasteParam = 1;
}
else if (par[1].equalsIgnoreCase("replace"))
{
this.pasteOption = 2;
this.pasteParam = 1;
}
try
{
this.filename = par[1 + this.pasteParam];
final File file = new File("plugins/VoxelSniper/stencilLists/" + this.filename + ".txt");
if (file.exists())
{
v.sendMessage(ChatColor.RED + "Stencil List '" + this.filename + "' exists and was loaded.");
this.readStencilList(this.filename, v);
}
else
{
v.sendMessage(ChatColor.AQUA + "Stencil List '" + this.filename + "' does not exist. This brush will not function without a valid stencil list.");
this.filename = "NoFileLoaded";
}
}
catch (final Exception exception)
{
v.sendMessage(ChatColor.RED + "You need to type a stencil name.");
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.stencillist";
}
}

Datei anzeigen

@ -0,0 +1,238 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Three-Point_Circle_Brush
*
* @author Giltwist
*/
public class ThreePointCircleBrush extends PerformBrush
{
private Vector coordsOne;
private Vector coordsTwo;
private Vector coordsThree;
private Tolerance tolerance = Tolerance.DEFAULT;
/**
* Default Constructor.
*/
public ThreePointCircleBrush()
{
this.setName("3-Point Circle");
}
@Override
protected final void arrow(final SnipeData v)
{
if (this.coordsOne == null)
{
this.coordsOne = this.getTargetBlock().getLocation().toVector();
v.sendMessage(ChatColor.GRAY + "First Corner set.");
}
else if (this.coordsTwo == null)
{
this.coordsTwo = this.getTargetBlock().getLocation().toVector();
v.sendMessage(ChatColor.GRAY + "Second Corner set.");
}
else if (this.coordsThree == null)
{
this.coordsThree = this.getTargetBlock().getLocation().toVector();
v.sendMessage(ChatColor.GRAY + "Third Corner set.");
}
else
{
this.coordsOne = this.getTargetBlock().getLocation().toVector();
this.coordsTwo = null;
this.coordsThree = null;
v.sendMessage(ChatColor.GRAY + "First Corner set.");
}
}
@Override
protected final void powder(final SnipeData v)
{
if (this.coordsOne == null || this.coordsTwo == null || this.coordsThree == null)
{
return;
}
// Calculate triangle defining vectors
final Vector vectorOne = this.coordsTwo.clone();
vectorOne.subtract(this.coordsOne);
final Vector vectorTwo = this.coordsThree.clone();
vectorTwo.subtract(this.coordsOne);
final Vector vectorThree = this.coordsThree.clone();
vectorThree.subtract(vectorTwo);
// Redundant data check
if (vectorOne.length() == 0 || vectorTwo.length() == 0 || vectorThree.length() == 0 || vectorOne.angle(vectorTwo) == 0 || vectorOne.angle(vectorThree) == 0 || vectorThree.angle(vectorTwo) == 0)
{
v.sendMessage(ChatColor.RED + "ERROR: Invalid points, try again.");
this.coordsOne = null;
this.coordsTwo = null;
this.coordsThree = null;
return;
}
// Calculate normal vector of the plane.
final Vector normalVector = vectorOne.clone();
normalVector.crossProduct(vectorTwo);
// Calculate constant term of the plane.
final double planeConstant = normalVector.getX() * this.coordsOne.getX() + normalVector.getY() * this.coordsOne.getY() + normalVector.getZ() * this.coordsOne.getZ();
final Vector midpointOne = this.coordsOne.getMidpoint(this.coordsTwo);
final Vector midpointTwo = this.coordsOne.getMidpoint(this.coordsThree);
// Find perpendicular vectors to two sides in the plane
final Vector perpendicularOne = normalVector.clone();
perpendicularOne.crossProduct(vectorOne);
final Vector perpendicularTwo = normalVector.clone();
perpendicularTwo.crossProduct(vectorTwo);
// determine value of parametric variable at intersection of two perpendicular bisectors
final Vector tNumerator = midpointTwo.clone();
tNumerator.subtract(midpointOne);
tNumerator.crossProduct(perpendicularTwo);
final Vector tDenominator = perpendicularOne.clone();
tDenominator.crossProduct(perpendicularTwo);
final double t = tNumerator.length() / tDenominator.length();
// Calculate Circumcenter and Brushcenter.
final Vector circumcenter = new Vector();
circumcenter.copy(perpendicularOne);
circumcenter.multiply(t);
circumcenter.add(midpointOne);
final Vector brushCenter = new Vector(Math.round(circumcenter.getX()), Math.round(circumcenter.getY()), Math.round(circumcenter.getZ()));
// Calculate radius of circumcircle and determine brushsize
final double radius = circumcenter.distance(new Vector(this.coordsOne.getX(), this.coordsOne.getY(), this.coordsOne.getZ()));
final int brushSize = NumberConversions.ceil(radius) + 1;
for (int x = -brushSize; x <= brushSize; x++)
{
for (int y = -brushSize; y <= brushSize; y++)
{
for (int z = -brushSize; z <= brushSize; z++)
{
// Calculate distance from center
final double tempDistance = Math.pow(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2), .5);
// gets corner-on blocks
final double cornerConstant = normalVector.getX() * (circumcenter.getX() + x) + normalVector.getY() * (circumcenter.getY() + y) + normalVector.getZ() * (circumcenter.getZ() + z);
// gets center-on blocks
final double centerConstant = normalVector.getX() * (circumcenter.getX() + x + .5) + normalVector.getY() * (circumcenter.getY() + y + .5) + normalVector.getZ() * (circumcenter.getZ() + z + .5);
// Check if point is within sphere and on plane (some tolerance given)
if (tempDistance <= radius && (Math.abs(cornerConstant - planeConstant) < this.tolerance.getValue() || Math.abs(centerConstant - planeConstant) < this.tolerance.getValue()))
{
this.current.perform(this.clampY(brushCenter.getBlockX() + x, brushCenter.getBlockY() + y, brushCenter.getBlockZ() + z));
}
}
}
}
v.sendMessage(ChatColor.GREEN + "Done.");
v.owner().storeUndo(this.current.getUndo());
// Reset Brush
this.coordsOne = null;
this.coordsTwo = null;
this.coordsThree = null;
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
switch (this.tolerance)
{
case ACCURATE:
vm.custom(ChatColor.GOLD + "Mode: Accurate");
break;
case DEFAULT:
vm.custom(ChatColor.GOLD + "Mode: Default");
break;
case SMOOTH:
vm.custom(ChatColor.GOLD + "Mode: Smooth");
break;
default:
vm.custom(ChatColor.GOLD + "Mode: Unknown");
break;
}
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.YELLOW + "3-Point Circle Brush instructions: Select three corners with the arrow brush, then generate the Circle with the powder brush.");
String toleranceOptions = "";
for (final Tolerance tolerance : Tolerance.values())
{
if (!toleranceOptions.isEmpty())
{
toleranceOptions += "|";
}
toleranceOptions += tolerance.name().toLowerCase();
}
v.sendMessage(ChatColor.GOLD + "/b tpc " + toleranceOptions + " -- Toggle the calculations to emphasize accuracy or smoothness");
return;
}
for (int i = 1; i < par.length; i++)
{
final String parameter = par[i].toUpperCase();
try
{
this.tolerance = Tolerance.valueOf(parameter);
v.sendMessage(ChatColor.AQUA + "Brush set to " + this.tolerance.name().toLowerCase() + " tolerance.");
return;
}
catch (final IllegalArgumentException exception)
{
v.getVoxelMessage().brushMessage("No such tolerance.");
}
}
}
/**
* Enumeration on Tolerance values.
*
* @author MikeMatrix
*/
private enum Tolerance
{
DEFAULT(1000), ACCURATE(10), SMOOTH(2000);
private int value;
Tolerance(final int value)
{
this.value = value;
}
public int getValue()
{
return this.value;
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.threepointcircle";
}
}

Datei anzeigen

@ -0,0 +1,132 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.bukkit.wrapper.AsyncBlockState;
import com.google.common.base.Objects;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.Undo;
import com.thevoxelbox.voxelsniper.util.UndoDelegate;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.TreeType;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Tree_Brush
*
* @author Mick
*/
public class TreeSnipeBrush extends Brush
{
private TreeType treeType = TreeType.TREE;
/**
*
*/
public TreeSnipeBrush()
{
this.setName("Tree Snipe");
}
@SuppressWarnings("deprecation")
private void single(final SnipeData v, AsyncBlock targetBlock)
{
UndoDelegate undoDelegate = new UndoDelegate(targetBlock.getWorld());
AsyncBlock blockBelow = targetBlock.getRelative(BlockFace.DOWN);
AsyncBlockState currentState = blockBelow.getState();
undoDelegate.setBlock(blockBelow);
blockBelow.setType(Material.GRASS);
this.getWorld().generateTree(targetBlock.getLocation(), this.treeType, undoDelegate);
Undo undo = undoDelegate.getUndo();
blockBelow.setTypeIdAndPropertyId(currentState.getTypeId(), currentState.getPropertyId(), true);
undo.put(blockBelow);
v.owner().storeUndo(undo);
}
private int getYOffset()
{
for (int i = 1; i < (getTargetBlock().getWorld().getMaxHeight() - 1 - getTargetBlock().getY()); i++)
{
if (Objects.equal(getTargetBlock().getRelative(0, i + 1, 0).getType(), Material.AIR))
{
return i;
}
}
return 0;
}
private void printTreeType(final Message vm)
{
String printout = "";
boolean delimiterHelper = true;
for (final TreeType treeType : TreeType.values())
{
if (delimiterHelper)
{
delimiterHelper = false;
}
else
{
printout += ", ";
}
printout += ((treeType.equals(this.treeType)) ? ChatColor.GRAY + treeType.name().toLowerCase() : ChatColor.DARK_GRAY + treeType.name().toLowerCase()) + ChatColor.WHITE;
}
vm.custom(printout);
}
@Override
protected final void arrow(final SnipeData v)
{
AsyncBlock targetBlock = getTargetBlock().getRelative(0, getYOffset(), 0);
this.single(v, targetBlock);
}
@Override
protected final void powder(final SnipeData v)
{
this.single(v, getTargetBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
this.printTreeType(vm);
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
if (par[i].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Tree snipe brush:");
v.sendMessage(ChatColor.AQUA + "/b t treetype");
this.printTreeType(v.getVoxelMessage());
return;
}
try
{
this.treeType = TreeType.valueOf(par[i].toUpperCase());
this.printTreeType(v.getVoxelMessage());
}
catch (final IllegalArgumentException exception)
{
v.getVoxelMessage().brushMessage("No such tree type.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.treesnipe";
}
}

Datei anzeigen

@ -0,0 +1,334 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Triangle_Brush
*
* @author Giltwist
*/
public class TriangleBrush extends PerformBrush
{
private double[] coordsOne = new double[3]; // Three corners
private double[] coordsTwo = new double[3];
private double[] coordsThree = new double[3];
private int cornernumber = 1;
private double[] currentCoords = new double[3]; // For loop tracking
private double[] vectorOne = new double[3]; // Point 1 to 2
private double[] vectorTwo = new double[3]; // Point 1 to 3
private double[] vectorThree = new double[3]; // Point 2 to 3, for area calculations
private double[] normalVector = new double[3];
/**
*
*/
public TriangleBrush()
{
this.setName("Triangle");
}
private void triangleA(final SnipeData v)
{
switch (this.cornernumber)
{
case 1:
this.coordsOne[0] = this.getTargetBlock().getX() + .5 * this.getTargetBlock().getX() / Math.abs(this.getTargetBlock().getX()); // I hate you sometimes, Notch. Really? Every quadrant is
// different?
this.coordsOne[1] = this.getTargetBlock().getY() + .5;
this.coordsOne[2] = this.getTargetBlock().getZ() + .5 * this.getTargetBlock().getZ() / Math.abs(this.getTargetBlock().getZ());
this.cornernumber = 2;
v.sendMessage(ChatColor.GRAY + "First Corner set.");
break;
case 2:
this.coordsTwo[0] = this.getTargetBlock().getX() + .5 * this.getTargetBlock().getX() / Math.abs(this.getTargetBlock().getX()); // I hate you sometimes, Notch. Really? Every quadrant is
// different?
this.coordsTwo[1] = this.getTargetBlock().getY() + .5;
this.coordsTwo[2] = this.getTargetBlock().getZ() + .5 * this.getTargetBlock().getZ() / Math.abs(this.getTargetBlock().getZ());
this.cornernumber = 3;
v.sendMessage(ChatColor.GRAY + "Second Corner set.");
break;
case 3:
this.coordsThree[0] = this.getTargetBlock().getX() + .5 * this.getTargetBlock().getX() / Math.abs(this.getTargetBlock().getX()); // I hate you sometimes, Notch. Really? Every quadrant is
// different?
this.coordsThree[1] = this.getTargetBlock().getY() + .5;
this.coordsThree[2] = this.getTargetBlock().getZ() + .5 * this.getTargetBlock().getZ() / Math.abs(this.getTargetBlock().getZ());
this.cornernumber = 1;
v.sendMessage(ChatColor.GRAY + "Third Corner set.");
break;
default:
break;
}
}
private void triangleP(final SnipeData v)
{
double lengthOne = 0;
double lengthTwo = 0;
double lengthThree = 0;
double heronBig = 0;
// Calculate slope vectors
for (int i = 0; i < 3; i++)
{
this.vectorOne[i] = this.coordsTwo[i] - this.coordsOne[i];
this.vectorTwo[i] = this.coordsThree[i] - this.coordsOne[i];
this.vectorThree[i] = this.coordsThree[i] - this.coordsTwo[i];
}
// Calculate the cross product of vectorone and vectortwo
this.normalVector[0] = this.vectorOne[1] * this.vectorTwo[2] - this.vectorOne[2] * this.vectorTwo[1];
this.normalVector[1] = this.vectorOne[2] * this.vectorTwo[0] - this.vectorOne[0] * this.vectorTwo[2];
this.normalVector[2] = this.vectorOne[0] * this.vectorTwo[1] - this.vectorOne[1] * this.vectorTwo[0];
// Calculate magnitude of slope vectors
lengthOne = Math.pow(Math.pow(this.vectorOne[0], 2) + Math.pow(this.vectorOne[1], 2) + Math.pow(this.vectorOne[2], 2), .5);
lengthTwo = Math.pow(Math.pow(this.vectorTwo[0], 2) + Math.pow(this.vectorTwo[1], 2) + Math.pow(this.vectorTwo[2], 2), .5);
lengthThree = Math.pow(Math.pow(this.vectorThree[0], 2) + Math.pow(this.vectorThree[1], 2) + Math.pow(this.vectorThree[2], 2), .5);
// Bigger vector determines brush size
final int brushSize = (int) Math.ceil((lengthOne > lengthTwo) ? lengthOne : lengthTwo);
// Calculate constant term
final double planeConstant = this.normalVector[0] * this.coordsOne[0] + this.normalVector[1] * this.coordsOne[1] + this.normalVector[2] * this.coordsOne[2];
// Calculate the area of the full triangle
heronBig = .25 * Math.pow(Math.pow(Math.pow(lengthOne, 2) + Math.pow(lengthTwo, 2) + Math.pow(lengthThree, 2), 2) - 2 * (Math.pow(lengthOne, 4) + Math.pow(lengthTwo, 4) + Math.pow(lengthThree, 4)), .5);
if (lengthOne == 0 || lengthTwo == 0 || (this.coordsOne[0] == 0 && this.coordsOne[1] == 0 && this.coordsOne[2] == 0) || (this.coordsTwo[0] == 0 && this.coordsTwo[1] == 0 && this.coordsTwo[2] == 0) || (this.coordsThree[0] == 0 && this.coordsThree[1] == 0 && this.coordsThree[2] == 0))
{
v.sendMessage(ChatColor.RED + "ERROR: Invalid corners, please try again.");
}
else
{
// Make the Changes
final double[] cVectorOne = new double[3];
final double[] cVectorTwo = new double[3];
final double[] cVectorThree = new double[3];
for (int y = -brushSize; y <= brushSize; y++)
{ // X DEPENDENT
for (int z = -brushSize; z <= brushSize; z++)
{
this.currentCoords[1] = this.coordsOne[1] + y;
this.currentCoords[2] = this.coordsOne[2] + z;
this.currentCoords[0] = (planeConstant - this.normalVector[1] * this.currentCoords[1] - this.normalVector[2] * this.currentCoords[2]) / this.normalVector[0];
// Area of triangle currentcoords, coordsone, coordstwo
for (int i = 0; i < 3; i++)
{
cVectorOne[i] = this.coordsTwo[i] - this.coordsOne[i];
cVectorTwo[i] = this.currentCoords[i] - this.coordsOne[i];
cVectorThree[i] = this.currentCoords[i] - this.coordsTwo[i];
}
double cLengthOne = Math.pow(Math.pow(cVectorOne[0], 2) + Math.pow(cVectorOne[1], 2) + Math.pow(cVectorOne[2], 2), .5);
double cLengthTwo = Math.pow(Math.pow(cVectorTwo[0], 2) + Math.pow(cVectorTwo[1], 2) + Math.pow(cVectorTwo[2], 2), .5);
double cLengthThree = Math.pow(Math.pow(cVectorThree[0], 2) + Math.pow(cVectorThree[1], 2) + Math.pow(cVectorThree[2], 2), .5);
final double heronOne = .25 * Math.pow(Math.pow(Math.pow(cLengthOne, 2) + Math.pow(cLengthTwo, 2) + Math.pow(cLengthThree, 2), 2) - 2 * (Math.pow(cLengthOne, 4) + Math.pow(cLengthTwo, 4) + Math.pow(cLengthThree, 4)), .5);
// Area of triangle currentcoords, coordsthree, coordstwo
for (int i = 0; i < 3; i++)
{
cVectorOne[i] = this.coordsTwo[i] - this.coordsThree[i];
cVectorTwo[i] = this.currentCoords[i] - this.coordsThree[i];
cVectorThree[i] = this.currentCoords[i] - this.coordsTwo[i];
}
cLengthOne = Math.pow(Math.pow(cVectorOne[0], 2) + Math.pow(cVectorOne[1], 2) + Math.pow(cVectorOne[2], 2), .5);
cLengthTwo = Math.pow(Math.pow(cVectorTwo[0], 2) + Math.pow(cVectorTwo[1], 2) + Math.pow(cVectorTwo[2], 2), .5);
cLengthThree = Math.pow(Math.pow(cVectorThree[0], 2) + Math.pow(cVectorThree[1], 2) + Math.pow(cVectorThree[2], 2), .5);
final double heronTwo = .25 * Math.pow(Math.pow(Math.pow(cLengthOne, 2) + Math.pow(cLengthTwo, 2) + Math.pow(cLengthThree, 2), 2) - 2 * (Math.pow(cLengthOne, 4) + Math.pow(cLengthTwo, 4) + Math.pow(cLengthThree, 4)), .5);
// Area of triangle currentcoords, coordsthree, coordsone
for (int i = 0; i < 3; i++)
{
cVectorOne[i] = this.coordsOne[i] - this.coordsThree[i];
cVectorTwo[i] = this.currentCoords[i] - this.coordsThree[i];
cVectorThree[i] = this.currentCoords[i] - this.coordsOne[i];
}
cLengthOne = Math.pow(Math.pow(cVectorOne[0], 2) + Math.pow(cVectorOne[1], 2) + Math.pow(cVectorOne[2], 2), .5);
cLengthTwo = Math.pow(Math.pow(cVectorTwo[0], 2) + Math.pow(cVectorTwo[1], 2) + Math.pow(cVectorTwo[2], 2), .5);
cLengthThree = Math.pow(Math.pow(cVectorThree[0], 2) + Math.pow(cVectorThree[1], 2) + Math.pow(cVectorThree[2], 2), .5);
final double heronThree = .25 * Math.pow(Math.pow(Math.pow(cLengthOne, 2) + Math.pow(cLengthTwo, 2) + Math.pow(cLengthThree, 2), 2) - 2 * (Math.pow(cLengthOne, 4) + Math.pow(cLengthTwo, 4) + Math.pow(cLengthThree, 4)), .5);
final double barycentric = (heronOne + heronTwo + heronThree) / heronBig;
if (barycentric <= 1.1)
{
this.current.perform(this.clampY((int) this.currentCoords[0], (int) this.currentCoords[1], (int) this.currentCoords[2]));
}
}
} // END X DEPENDENT
for (int x = -brushSize; x <= brushSize; x++)
{ // Y DEPENDENT
for (int z = -brushSize; z <= brushSize; z++)
{
this.currentCoords[0] = this.coordsOne[0] + x;
this.currentCoords[2] = this.coordsOne[2] + z;
this.currentCoords[1] = (planeConstant - this.normalVector[0] * this.currentCoords[0] - this.normalVector[2] * this.currentCoords[2]) / this.normalVector[1];
// Area of triangle currentcoords, coordsone, coordstwo
for (int i = 0; i < 3; i++)
{
cVectorOne[i] = this.coordsTwo[i] - this.coordsOne[i];
cVectorTwo[i] = this.currentCoords[i] - this.coordsOne[i];
cVectorThree[i] = this.currentCoords[i] - this.coordsTwo[i];
}
double cLengthOne = Math.pow(Math.pow(cVectorOne[0], 2) + Math.pow(cVectorOne[1], 2) + Math.pow(cVectorOne[2], 2), .5);
double cLengthTwo = Math.pow(Math.pow(cVectorTwo[0], 2) + Math.pow(cVectorTwo[1], 2) + Math.pow(cVectorTwo[2], 2), .5);
double cLengthThree = Math.pow(Math.pow(cVectorThree[0], 2) + Math.pow(cVectorThree[1], 2) + Math.pow(cVectorThree[2], 2), .5);
final double heronOne = .25 * Math.pow(Math.pow(Math.pow(cLengthOne, 2) + Math.pow(cLengthTwo, 2) + Math.pow(cLengthThree, 2), 2) - 2 * (Math.pow(cLengthOne, 4) + Math.pow(cLengthTwo, 4) + Math.pow(cLengthThree, 4)), .5);
// Area of triangle currentcoords, coordsthree, coordstwo
for (int i = 0; i < 3; i++)
{
cVectorOne[i] = this.coordsTwo[i] - this.coordsThree[i];
cVectorTwo[i] = this.currentCoords[i] - this.coordsThree[i];
cVectorThree[i] = this.currentCoords[i] - this.coordsTwo[i];
}
cLengthOne = Math.pow(Math.pow(cVectorOne[0], 2) + Math.pow(cVectorOne[1], 2) + Math.pow(cVectorOne[2], 2), .5);
cLengthTwo = Math.pow(Math.pow(cVectorTwo[0], 2) + Math.pow(cVectorTwo[1], 2) + Math.pow(cVectorTwo[2], 2), .5);
cLengthThree = Math.pow(Math.pow(cVectorThree[0], 2) + Math.pow(cVectorThree[1], 2) + Math.pow(cVectorThree[2], 2), .5);
final double heronTwo = .25 * Math.pow(Math.pow(Math.pow(cLengthOne, 2) + Math.pow(cLengthTwo, 2) + Math.pow(cLengthThree, 2), 2) - 2 * (Math.pow(cLengthOne, 4) + Math.pow(cLengthTwo, 4) + Math.pow(cLengthThree, 4)), .5);
// Area of triangle currentcoords, coordsthree, coordsone
for (int i = 0; i < 3; i++)
{
cVectorOne[i] = this.coordsOne[i] - this.coordsThree[i];
cVectorTwo[i] = this.currentCoords[i] - this.coordsThree[i];
cVectorThree[i] = this.currentCoords[i] - this.coordsOne[i];
}
cLengthOne = Math.pow(Math.pow(cVectorOne[0], 2) + Math.pow(cVectorOne[1], 2) + Math.pow(cVectorOne[2], 2), .5);
cLengthTwo = Math.pow(Math.pow(cVectorTwo[0], 2) + Math.pow(cVectorTwo[1], 2) + Math.pow(cVectorTwo[2], 2), .5);
cLengthThree = Math.pow(Math.pow(cVectorThree[0], 2) + Math.pow(cVectorThree[1], 2) + Math.pow(cVectorThree[2], 2), .5);
final double heronThree = .25 * Math.pow(Math.pow(Math.pow(cLengthOne, 2) + Math.pow(cLengthTwo, 2) + Math.pow(cLengthThree, 2), 2) - 2 * (Math.pow(cLengthOne, 4) + Math.pow(cLengthTwo, 4) + Math.pow(cLengthThree, 4)), .5);
final double barycentric = (heronOne + heronTwo + heronThree) / heronBig;
if (barycentric <= 1.1)
{
this.current.perform(this.clampY((int) this.currentCoords[0], (int) this.currentCoords[1], (int) this.currentCoords[2]));
}
}
} // END Y DEPENDENT
for (int x = -brushSize; x <= brushSize; x++)
{ // Z DEPENDENT
for (int y = -brushSize; y <= brushSize; y++)
{
this.currentCoords[0] = this.coordsOne[0] + x;
this.currentCoords[1] = this.coordsOne[1] + y;
this.currentCoords[2] = (planeConstant - this.normalVector[0] * this.currentCoords[0] - this.normalVector[1] * this.currentCoords[1]) / this.normalVector[2];
// Area of triangle currentcoords, coordsone, coordstwo
for (int i = 0; i < 3; i++)
{
cVectorOne[i] = this.coordsTwo[i] - this.coordsOne[i];
cVectorTwo[i] = this.currentCoords[i] - this.coordsOne[i];
cVectorThree[i] = this.currentCoords[i] - this.coordsTwo[i];
}
double cLengthOne = Math.pow(Math.pow(cVectorOne[0], 2) + Math.pow(cVectorOne[1], 2) + Math.pow(cVectorOne[2], 2), .5);
double cLengthTwo = Math.pow(Math.pow(cVectorTwo[0], 2) + Math.pow(cVectorTwo[1], 2) + Math.pow(cVectorTwo[2], 2), .5);
double cLengthThree = Math.pow(Math.pow(cVectorThree[0], 2) + Math.pow(cVectorThree[1], 2) + Math.pow(cVectorThree[2], 2), .5);
final double heronOne = .25 * Math.pow(Math.pow(Math.pow(cLengthOne, 2) + Math.pow(cLengthTwo, 2) + Math.pow(cLengthThree, 2), 2) - 2 * (Math.pow(cLengthOne, 4) + Math.pow(cLengthTwo, 4) + Math.pow(cLengthThree, 4)), .5);
// Area of triangle currentcoords, coordsthree, coordstwo
for (int i = 0; i < 3; i++)
{
cVectorOne[i] = this.coordsTwo[i] - this.coordsThree[i];
cVectorTwo[i] = this.currentCoords[i] - this.coordsThree[i];
cVectorThree[i] = this.currentCoords[i] - this.coordsTwo[i];
}
cLengthOne = Math.pow(Math.pow(cVectorOne[0], 2) + Math.pow(cVectorOne[1], 2) + Math.pow(cVectorOne[2], 2), .5);
cLengthTwo = Math.pow(Math.pow(cVectorTwo[0], 2) + Math.pow(cVectorTwo[1], 2) + Math.pow(cVectorTwo[2], 2), .5);
cLengthThree = Math.pow(Math.pow(cVectorThree[0], 2) + Math.pow(cVectorThree[1], 2) + Math.pow(cVectorThree[2], 2), .5);
final double heronTwo = .25 * Math.pow(Math.pow(Math.pow(cLengthOne, 2) + Math.pow(cLengthTwo, 2) + Math.pow(cLengthThree, 2), 2) - 2 * (Math.pow(cLengthOne, 4) + Math.pow(cLengthTwo, 4) + Math.pow(cLengthThree, 4)), .5);
// Area of triangle currentcoords, coordsthree, coordsone
for (int i = 0; i < 3; i++)
{
cVectorOne[i] = this.coordsOne[i] - this.coordsThree[i];
cVectorTwo[i] = this.currentCoords[i] - this.coordsThree[i];
cVectorThree[i] = this.currentCoords[i] - this.coordsOne[i];
}
cLengthOne = Math.pow(Math.pow(cVectorOne[0], 2) + Math.pow(cVectorOne[1], 2) + Math.pow(cVectorOne[2], 2), .5);
cLengthTwo = Math.pow(Math.pow(cVectorTwo[0], 2) + Math.pow(cVectorTwo[1], 2) + Math.pow(cVectorTwo[2], 2), .5);
cLengthThree = Math.pow(Math.pow(cVectorThree[0], 2) + Math.pow(cVectorThree[1], 2) + Math.pow(cVectorThree[2], 2), .5);
final double heronThree = .25 * Math.pow(Math.pow(Math.pow(cLengthOne, 2) + Math.pow(cLengthTwo, 2) + Math.pow(cLengthThree, 2), 2) - 2 * (Math.pow(cLengthOne, 4) + Math.pow(cLengthTwo, 4) + Math.pow(cLengthThree, 4)), .5);
final double barycentric = (heronOne + heronTwo + heronThree) / heronBig;
// VoxelSniper.log.info("Bary: "+barycentric+", hb: "+heronbig+", h1: "+heronone+", h2: "+herontwo+", h3: "+heronthree);
if (barycentric <= 1.1)
{
this.current.perform(this.clampY((int) this.currentCoords[0], (int) this.currentCoords[1], (int) this.currentCoords[2]));
}
}
} // END Z DEPENDENT
v.owner().storeUndo(this.current.getUndo());
}
// RESET BRUSH
this.coordsOne[0] = 0;
this.coordsOne[1] = 0;
this.coordsOne[2] = 0;
this.coordsTwo[0] = 0;
this.coordsTwo[1] = 0;
this.coordsTwo[2] = 0;
this.coordsThree[0] = 0;
this.coordsThree[1] = 0;
this.coordsThree[2] = 0;
this.cornernumber = 1;
}
@Override
protected final void arrow(final SnipeData v)
{
this.triangleA(v);
}
@Override
protected final void powder(final SnipeData v)
{ // Add a point
this.triangleP(v);
}
@Override
public final void info(final Message vm)
{ // Make the triangle
vm.brushName(this.getName());
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
if (par[1].equalsIgnoreCase("info"))
{
v.sendMessage(ChatColor.GOLD + "Triangle Brush instructions: Select three corners with the arrow brush, then generate the triangle with the powder brush.");
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.triangle";
}
}

Datei anzeigen

@ -0,0 +1,198 @@
package com.thevoxelbox.voxelsniper.brush;
import com.sk89q.worldedit.blocks.BlockMaterial;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.ChatColor;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#Underlay_Brush
*
* @author jmck95 Credit to GavJenks for framework and 95 of code. Big Thank you to GavJenks
*/
public class UnderlayBrush extends PerformBrush
{
private static final int DEFAULT_DEPTH = 3;
private int depth = DEFAULT_DEPTH;
private boolean allBlocks = false;
/**
*
*/
public UnderlayBrush()
{
this.setName("Underlay (Reverse Overlay)");
}
@SuppressWarnings("deprecation")
private void underlay(final SnipeData v)
{
final int[][] memory = new int[v.getBrushSize() * 2 + 1][v.getBrushSize() * 2 + 1];
final double brushSizeSquared = Math.pow(v.getBrushSize() + 0.5, 2);
for (int z = v.getBrushSize(); z >= -v.getBrushSize(); z--)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = this.getTargetBlock().getY(); y < this.getTargetBlock().getY() + this.depth; y++)
{ // start scanning from the height you clicked at
if (memory[x + v.getBrushSize()][z + v.getBrushSize()] != 1)
{ // if haven't already found the surface in this column
if ((Math.pow(x, 2) + Math.pow(z, 2)) <= brushSizeSquared)
{ // if inside of the column...
if (!this.allBlocks)
{ // if the override parameter has not been activated, go to the switch that filters out manmade stuff.
int id = this.getBlockIdAt(this.getTargetBlock().getX() + x, y, this.getTargetBlock().getZ() + z);
BlockMaterial mat = BlockTypes.get(id).getMaterial();
if (!mat.isReplacedDuringPlacement() && mat.isFullCube()) {
for (int d = 0; (d < this.depth); d++) {
if (this.clampY(this.getTargetBlock().getX() + x, y + d, this.getTargetBlock().getZ() + z).getTypeId() != 0) {
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y + d, this.getTargetBlock().getZ() + z)); // fills down as many layers as you specify in
// parameters
memory[x + v.getBrushSize()][z + v.getBrushSize()] = 1; // stop it from checking any other blocks in this vertical 1x1 column.
}
}
break;
} else {
continue;
}
}
else
{
for (int d = 0; (d < this.depth); d++)
{
if (this.clampY(this.getTargetBlock().getX() + x, y + d, this.getTargetBlock().getZ() + z).getTypeId() != 0)
{
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y + d, this.getTargetBlock().getZ() + z)); // fills down as many layers as you specify in
// parameters
memory[x + v.getBrushSize()][z + v.getBrushSize()] = 1; // stop it from checking any other blocks in this vertical 1x1 column.
}
}
}
}
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
private void underlay2(final SnipeData v)
{
final int[][] memory = new int[v.getBrushSize() * 2 + 1][v.getBrushSize() * 2 + 1];
final double brushSizeSquared = Math.pow(v.getBrushSize() + 0.5, 2);
for (int z = v.getBrushSize(); z >= -v.getBrushSize(); z--)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = this.getTargetBlock().getY(); y < this.getTargetBlock().getY() + this.depth; y++)
{ // start scanning from the height you clicked at
if (memory[x + v.getBrushSize()][z + v.getBrushSize()] != 1)
{ // if haven't already found the surface in this column
if ((Math.pow(x, 2) + Math.pow(z, 2)) <= brushSizeSquared)
{ // if inside of the column...
if (!this.allBlocks)
{ // if the override parameter has not been activated, go to the switch that filters out manmade stuff.
int id = this.getBlockIdAt(this.getTargetBlock().getX() + x, y, this.getTargetBlock().getZ() + z);
BlockMaterial mat = BlockTypes.get(id).getMaterial();
if (!mat.isReplacedDuringPlacement() && mat.isFullCube()) {
for (int d = -1; (d < this.depth - 1); d++) {
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y - d, this.getTargetBlock().getZ() + z)); // fills down as many layers as you specify in
// parameters
memory[x + v.getBrushSize()][z + v.getBrushSize()] = 1; // stop it from checking any other blocks in this vertical 1x1 column.
}
break;
} else {
continue;
}
}
else
{
for (int d = -1; (d < this.depth - 1); d++)
{
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, y - d, this.getTargetBlock().getZ() + z)); // fills down as many layers as you specify in
// parameters
memory[x + v.getBrushSize()][z + v.getBrushSize()] = 1; // stop it from checking any other blocks in this vertical 1x1 column.
}
}
}
}
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
public final void arrow(final SnipeData v)
{
this.underlay(v);
}
@Override
public final void powder(final SnipeData v)
{
this.underlay2(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public final void parameters(final String[] par, final SnipeData v)
{
for (int i = 1; i < par.length; i++)
{
if (par[i].equalsIgnoreCase("info"))
{
v.owner().getPlayer().sendMessage(ChatColor.GOLD + "Reverse Overlay brush parameters:");
v.owner().getPlayer().sendMessage(ChatColor.AQUA + "d[number] (ex: d3) The number of blocks thick to change.");
v.owner().getPlayer().sendMessage(ChatColor.BLUE + "all (ex: /b reover all) Sets the brush to affect ALL materials");
if (this.depth < 1)
{
this.depth = 1;
}
return;
}
if (par[i].startsWith("d"))
{
this.depth = Integer.parseInt(par[i].replace("d", ""));
v.owner().getPlayer().sendMessage(ChatColor.AQUA + "Depth set to " + this.depth);
}
else if (par[i].startsWith("all"))
{
this.allBlocks = true;
v.owner().getPlayer().sendMessage(ChatColor.BLUE + "Will underlay over any block." + this.depth);
}
else if (par[i].startsWith("some"))
{
this.allBlocks = false;
v.owner().getPlayer().sendMessage(ChatColor.BLUE + "Will underlay only natural block types." + this.depth);
}
else
{
v.owner().getPlayer().sendMessage(ChatColor.RED + "Invalid brush parameters! use the info parameter to display parameter info.");
}
}
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.underlay";
}
}

Datei anzeigen

@ -0,0 +1,71 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Volt-Meter_Brush
*
* @author Gavjenks
*/
public class VoltMeterBrush extends Brush
{
/**
*
*/
public VoltMeterBrush()
{
this.setName("VoltMeter");
}
@SuppressWarnings("deprecation")
private void data(final SnipeData v)
{
final AsyncBlock block = this.clampY(this.getTargetBlock().getX(), this.getTargetBlock().getY(), this.getTargetBlock().getZ());
final int data = block.getPropertyId();
v.sendMessage(ChatColor.AQUA + "Blocks until repeater needed: " + data);
}
private void volt(final SnipeData v)
{
final Block block = this.clampY(this.getTargetBlock().getX(), this.getTargetBlock().getY(), this.getTargetBlock().getZ());
final boolean indirect = block.isBlockIndirectlyPowered();
final boolean direct = block.isBlockPowered();
v.sendMessage(ChatColor.AQUA + "Direct Power? " + direct + " Indirect Power? " + indirect);
v.sendMessage(ChatColor.BLUE + "Top Direct? " + block.isBlockFacePowered(BlockFace.UP) + " Top Indirect? " + block.isBlockFaceIndirectlyPowered(BlockFace.UP));
v.sendMessage(ChatColor.BLUE + "Bottom Direct? " + block.isBlockFacePowered(BlockFace.DOWN) + " Bottom Indirect? " + block.isBlockFaceIndirectlyPowered(BlockFace.DOWN));
v.sendMessage(ChatColor.BLUE + "East Direct? " + block.isBlockFacePowered(BlockFace.EAST) + " East Indirect? " + block.isBlockFaceIndirectlyPowered(BlockFace.EAST));
v.sendMessage(ChatColor.BLUE + "West Direct? " + block.isBlockFacePowered(BlockFace.WEST) + " West Indirect? " + block.isBlockFaceIndirectlyPowered(BlockFace.WEST));
v.sendMessage(ChatColor.BLUE + "North Direct? " + block.isBlockFacePowered(BlockFace.NORTH) + " North Indirect? " + block.isBlockFaceIndirectlyPowered(BlockFace.NORTH));
v.sendMessage(ChatColor.BLUE + "South Direct? " + block.isBlockFacePowered(BlockFace.SOUTH) + " South Indirect? " + block.isBlockFaceIndirectlyPowered(BlockFace.SOUTH));
}
@Override
protected final void arrow(final SnipeData v)
{
this.volt(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.data(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.brushMessage("Right click with arrow to see if blocks/faces are powered. Powder measures wire current.");
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.voltmeter";
}
}

Datei anzeigen

@ -0,0 +1,61 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Voxel_Brush
*
* @author Piotr
*/
public class VoxelBrush extends PerformBrush
{
/**
*
*/
public VoxelBrush()
{
this.setName("Voxel");
}
private void voxel(final SnipeData v)
{
for (int z = v.getBrushSize(); z >= -v.getBrushSize(); z--)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = v.getBrushSize(); y >= -v.getBrushSize(); y--)
{
this.current.perform(this.clampY(this.getTargetBlock().getX() + x, this.getTargetBlock().getY() + z, this.getTargetBlock().getZ() + y));
}
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.voxel(v);
}
@Override
protected final void powder(final SnipeData v)
{
this.voxel(v);
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.voxel";
}
}

Datei anzeigen

@ -0,0 +1,60 @@
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.block.Block;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Voxel_Disc_Brush
*
* @author Voxel
*/
public class VoxelDiscBrush extends PerformBrush
{
/**
*
*/
public VoxelDiscBrush()
{
this.setName("Voxel Disc");
}
private void disc(final SnipeData v, AsyncBlock targetBlock)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int z = v.getBrushSize(); z >= -v.getBrushSize(); z--)
{
current.perform(targetBlock.getRelative(x, 0, z));
}
}
v.owner().storeUndo(this.current.getUndo());
}
@Override
protected final void arrow(final SnipeData v)
{
this.disc(v, this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.disc(v, this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.voxeldisc";
}
}

Datei anzeigen

@ -0,0 +1,115 @@
package com.thevoxelbox.voxelsniper.brush;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
/**
* http://www.voxelwiki.com/minecraft/Voxelsniper#The_Voxel_Disc_Face_Brush
*
* @author Voxel
*/
public class VoxelDiscFaceBrush extends PerformBrush
{
/**
*
*/
public VoxelDiscFaceBrush()
{
this.setName("Voxel Disc Face");
}
private void disc(final SnipeData v, Block targetBlock)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = v.getBrushSize(); y >= -v.getBrushSize(); y--)
{
this.current.perform(this.clampY(targetBlock.getX() + x, targetBlock.getY(), targetBlock.getZ() + y));
}
}
v.owner().storeUndo(this.current.getUndo());
}
private void discNS(final SnipeData v, Block targetBlock)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = v.getBrushSize(); y >= -v.getBrushSize(); y--)
{
this.current.perform(this.clampY(targetBlock.getX() + x, targetBlock.getY() + y, targetBlock.getZ()));
}
}
v.owner().storeUndo(this.current.getUndo());
}
private void discEW(final SnipeData v, Block targetBlock)
{
for (int x = v.getBrushSize(); x >= -v.getBrushSize(); x--)
{
for (int y = v.getBrushSize(); y >= -v.getBrushSize(); y--)
{
this.current.perform(this.clampY(targetBlock.getX(), targetBlock.getY() + x, targetBlock.getZ() + y));
}
}
v.owner().storeUndo(this.current.getUndo());
}
private void pre(final SnipeData v, final BlockFace bf, Block targetBlock)
{
if (bf == null)
{
return;
}
switch (bf)
{
case NORTH:
case SOUTH:
this.discNS(v, targetBlock);
break;
case EAST:
case WEST:
this.discEW(v, targetBlock);
break;
case UP:
case DOWN:
this.disc(v, targetBlock);
break;
default:
break;
}
}
@Override
protected final void arrow(final SnipeData v)
{
this.pre(v, this.getTargetBlock().getFace(this.getLastBlock()), this.getTargetBlock());
}
@Override
protected final void powder(final SnipeData v)
{
this.pre(v, this.getTargetBlock().getFace(this.getLastBlock()), this.getLastBlock());
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
vm.size();
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.voxeldiscface";
}
}

Datei anzeigen

@ -0,0 +1,97 @@
/**
This file is part of VoxelSniper, licensed under the MIT License (MIT).
Copyright (c) The VoxelBox <http://thevoxelbox.com>
Copyright (c) contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package com.thevoxelbox.voxelsniper.brush;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.TaskManager;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
/**
* @author MikeMatrix
*/
public class WarpBrush extends Brush
{
/**
*
*/
public WarpBrush()
{
this.setName("Warp");
}
@Override
public final void info(final Message vm)
{
vm.brushName(this.getName());
}
@Override
protected final void arrow(final SnipeData v)
{
Player player = v.owner().getPlayer();
Location location = this.getLastBlock().getLocation();
Location playerLocation = player.getLocation();
location.setPitch(playerLocation.getPitch());
location.setYaw(playerLocation.getYaw());
location.setWorld(Bukkit.getWorld(location.getWorld().getName()));
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
player.teleport(location);
}
});
}
@Override
protected final void powder(final SnipeData v)
{
Player player = v.owner().getPlayer();
Location location = this.getLastBlock().getLocation();
Location playerLocation = player.getLocation();
location.setPitch(playerLocation.getPitch());
location.setYaw(playerLocation.getYaw());
location.setWorld(Bukkit.getWorld(location.getWorld().getName()));
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
player.teleport(location);
}
});
}
@Override
public String getPermissionNode()
{
return "voxelsniper.brush.warp";
}
public static Class<?> inject() {
return WarpBrush.class;
}
}

Datei anzeigen

@ -0,0 +1,43 @@
package com.thevoxelbox.voxelsniper.brush.perform;
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
import com.boydti.fawe.object.pattern.PatternTraverser;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import org.bukkit.block.Block;
public class PatternPerformer extends vPerformer {
private String info;
private Pattern pattern;
private Extent extent;
private MutableBlockVector mutable = new MutableBlockVector();
@Override
public void info(Message vm) {
vm.performerName(this.name + ": " + info);
vm.voxel();
}
@Override
public void init(SnipeData snipeData) {
this.w = snipeData.getWorld();
this.extent = snipeData.getExtent();
this.info = snipeData.getPatternInfo();
this.pattern = snipeData.getPattern();
new PatternTraverser(pattern).reset(extent);
}
@Override
public void perform(AsyncBlock block) {
mutable.setComponents(block.getX(), block.getY(), block.getZ());
try {
pattern.apply(extent, mutable, mutable);
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
}

Datei anzeigen

@ -0,0 +1,100 @@
/**
This file is part of VoxelSniper, licensed under the MIT License (MIT).
Copyright (c) The VoxelBox <http://thevoxelbox.com>
Copyright (c) contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package com.thevoxelbox.voxelsniper.brush.perform;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.thevoxelbox.voxelsniper.Message;
import com.thevoxelbox.voxelsniper.SnipeData;
import com.thevoxelbox.voxelsniper.brush.Brush;
import com.thevoxelbox.voxelsniper.event.SniperBrushChangedEvent;
import java.util.Arrays;
import org.bukkit.Bukkit;
public abstract class PerformBrush extends Brush implements Performer {
protected vPerformer current = new pMaterial();
public PerformBrush() {
}
public vPerformer getCurrentPerformer() {
return this.current;
}
public void parse(String[] args, SnipeData v) {
String handle = args[0];
if(PerformerE.has(handle)) {
vPerformer p = PerformerE.getPerformer(handle);
if(p != null) {
this.current = p;
SniperBrushChangedEvent event = new SniperBrushChangedEvent(v.owner(), v.owner().getCurrentToolId(), this, this);
Bukkit.getPluginManager().callEvent(event);
this.info(v.getVoxelMessage());
this.current.info(v.getVoxelMessage());
if(args.length > 1) {
String[] additionalArguments = (String[])Arrays.copyOfRange(args, 1, args.length);
this.parameters(this.hackTheArray(additionalArguments), v);
}
} else {
this.parameters(this.hackTheArray(args), v);
}
} else {
this.parameters(this.hackTheArray(args), v);
}
}
private String[] hackTheArray(String[] args) {
String[] returnValue = new String[args.length + 1];
int i = 0;
for(int argsLength = args.length; i < argsLength; ++i) {
String arg = args[i];
returnValue[i + 1] = arg;
}
return returnValue;
}
public void initP(SnipeData v) {
Pattern pattern = v.getPattern();
if (pattern != null) {
if (!(current instanceof PatternPerformer)) {
current = new PatternPerformer();
}
} else if (current instanceof PatternPerformer) {
current = new pMaterial();
}
this.current.init(v);
this.current.setUndo();
}
public void showInfo(Message vm) {
this.current.info(vm);
}
public static Class<?> inject() {
return PerformBrush.class;
}
}

Datei anzeigen

@ -0,0 +1,18 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.thevoxelbox.voxelsniper.brush.perform;
import com.thevoxelbox.voxelsniper.Message;
/**
* @author Voxel
*/
public interface Performer
{
public void parse(String[] args, com.thevoxelbox.voxelsniper.SnipeData v);
public void showInfo(Message vm);
}

Datei anzeigen

@ -0,0 +1,179 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.thevoxelbox.voxelsniper.brush.perform;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.ChatColor;
/**
* @author Voxel
*/
/* The m/i/c system of naming performers: <placement-option>[replacement-option][extras]
*
* placement-option is mandatory and can be material(m) [for /v], ink(i) [for /vi] or combo(c) [for both]
* replacement-option is optional and can be m [for /vr], i [for /vir] or c [for both]
* extras is optional and can be update(u) [for graphical glitch], physics(p) [for no-phys] or up [for both]
*
* new extra: n = no undo
*
* The main benefit of this system is that it provides the least possible number of characters in the paramaters
* while guaranteeing that all sensible combinations will be made. Additionally, the names will be VERY consistent
*
* EX Old System: /b b isrcup (use /v, /vi, /vr and /vir, update graphics and no physics)
* EX New System: /b b ccup (two characters shorter, good because snipers have been complaing about keystrokes)
*
*/
/* This enum is getting REALLY Long, would it be possible to algorithmically generate the full performer
* from the pieces? So if the performer name is of the for m*, you'll setTypeId whereas if it is of the
* form c* you'd setTypeIdAndPropertyId? Similarly, if the performer is of the form *p, any setTypeId's or setTypeIdAndPropertyId's
* will be set to false instead of true? The middle bits might be tougher, being of the form _m* perhaps?
* Regex to the rescue, am I right? - Giltwist
*/
public enum PerformerE
{
MATERIAL(pMaterial.class, "m", "material"),
MATERIAL_NOPHYS(pMaterialNoPhys.class, "mp", "mat-nophys"),
MAT_MAT(pMatMat.class, "mm", "mat-mat"),
MAT_MAT_NOPHYS(pMatMatNoPhys.class, "mmp", "mat-mat-nophys"),
MAT_INK(pMatInk.class, "mi", "mat-ink"),
MAT_INK_NOPHYS(pMatInkNoPhys.class, "mip", "mat-ink-nophys"),
MAT_COMBO(pMatCombo.class, "mc", "mat-combo"),
MAT_COMBO_NOPHYS(pMatComboNophys.class, "mcp", "mat-combo-nophys"),
INK(pInk.class, "i", "ink"),
INK_MAT(pInkMat.class, "im", "ink-mat"),
INK_INK(pInkInk.class, "ii", "ink-ink"),
INK_COMBO(pInkCombo.class, "ic", "ink-combo"),
INK_INK_NOPHYS(pInkInkNoPhys.class, "iip", "ink-ink-nophys"),
INK_NOPHYS(pInkNoPhys.class, "ip", "ink-nophys"),
INK_MAT_NOPHYS(pInkMatNoPhys.class, "imp", "ink-mat-nophys"),
INK_COMBO_NOPHYS(pInkComboNoPhys.class, "icp", "ink-combo-nophys"),
COMBO(pCombo.class, "c", "combo"),
COMBO_NOPHYS(pComboNoPhys.class, "cp", "combo-nophys"),
COMBO_MAT(pComboMat.class, "cm", "combo-mat"),
COMBO_MAT_NOPHYS(pComboMatNoPhys.class, "cmp", "combo-mat-nophys"),
COMBO_INK(pComboInk.class, "ci", "combo-ink"),
COMBO_INK_NOPHYS(pComboInkNoPhys.class, "cip", "combo-ink-nophys"),
COMBO_COMBO(pComboCombo.class, "cc", "combo-combo"),
COMBO_COMBO_NOPHYS(pComboComboNoPhys.class, "ccp", "combo-combo-nophys"),
EXCLUDE_MATERIAL(pExcludeMat.class, "xm", "exclude-mat"),
EXCLUDE_INK(pExcludeInk.class, "xi", "exclude-ink"),
EXCLUDE_COMBO(pExcludeCombo.class, "xc", "exclude-combo"),
INCLUDE_MATERIAL(pIncludeMat.class, "nm", "include-mat"),
INCLUDE_INK(pIncludeInk.class, "ni", "include-ink"),
INCLUDE_COMBO(pIncludeCombo.class, "nc", "include-combo"),
MAT_NO_UNDO(pNoUndo.class, "noundo", "noundo");
//Other Performers which don't exist yet but are required for a full set of possibilities that actually could potentially do something:
//List does not include any no-physics, unless materials are being placed (or combo), or any update unless ink is being placed (or combo) -Gavjenks
//MAT_MAT_UPDATE( pMatMatUpdate.class, "mmu", "mat-mat-update" ), // place mat, replace mat, graphical update
//MAT_COMBO_UPDATE( pMatComboUpdate.class, "mcu", "mat-combo-update" ), // place mat, replace combo, graphical update
//MAT_COMBO_NOPHYS_UPDATE( pMatComboNoPhysUpdate.class, "mcup", "mat-combo-update-nophys"), // place mat, replace combo, update, no physics
//MAT_INK_UPDATE( pMatInkUpdate.class, "miu", "mat-ink-update"), // place mat, replace ink, graphical update
//MAT_INK_NOPHYS_UPDATE( pMatInkNoPhysUpdate.class, "miup", "mat-ink-update-nophys"), // place mat, replace ink, graphical update no physics
//INK_MAT_UPDATE( pInkMatUpdate.class, "imu", "ink-mat-update"), // place ink, replace mat, graphical update
//INK_INK_UPDATE( pInkInkUpdate.class, "iiu", "ink-ink-update"), // place ink, replace ink, graphical update
//INK_COMBO_UPDATE( pInkComboUpdate.class, "icu", "ink-combo-update"), // place ink, replace combo, graphical update
//COMBO_MAT_UPDATE( pComboMatUpdate.class, "cmu", "combo-mat-update"), // place combo, replace mat, graphical update
//COMBO_MAT_NOPHYS_UPDATE( pComboMatNoPhysUpdate.class, "cmup", "combo-mat-update-nophys"), // place combo, replace mat, graphical update, no physics
//COMBO_INK_UPDATE( pComboInkUpdate.class, "ciu", "combo-ink-update"), // place combo, replace ink, graphical update
//COMBO_INK_NOPHYS_UPDATE( pComboInkNoPhysUpdate.class, "ciup", "combo-ink-update-nophys"), // place combo, replace ink, graphical update, no physics
//COMBO_COMBO_UPDATE( pComboComboUpdate.class, "ccu", "combo-combo-update"), // place combo, replace combo, graphical update
//COMBO_COMBO_NOPHYS_UPDATE(pComboComboNoPhysUpdate.class, "ccup", "combo-combo-update-nophys"),// place combo, replace combo, graphical update, no physics
private static Map<String, vPerformer> performers;
private static Map<String, String> long_names;
private Class<? extends vPerformer> pclass;
private String short_name;
private String long_name;
public static String performer_list_short = "";
public static String performer_list_long = "";
private PerformerE(Class<? extends vPerformer> c, String s, String l)
{
pclass = c;
short_name = s;
long_name = l;
}
private vPerformer getPerformer()
{
vPerformer p;
try
{
try
{
p = pclass.getConstructor().newInstance();
return p;
}
catch (InstantiationException ex)
{
Logger.getLogger(PerformerE.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(PerformerE.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalArgumentException ex)
{
Logger.getLogger(PerformerE.class.getName()).log(Level.SEVERE, null, ex);
}
catch (InvocationTargetException ex)
{
Logger.getLogger(PerformerE.class.getName()).log(Level.SEVERE, null, ex);
}
}
catch (NoSuchMethodException ex)
{
Logger.getLogger(PerformerE.class.getName()).log(Level.SEVERE, null, ex);
}
catch (SecurityException ex)
{
Logger.getLogger(PerformerE.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static vPerformer getPerformer(String s)
{
if (performers.containsKey(s))
{
return performers.get(s);
}
else
{
return performers.get(long_names.get(s));
}
}
public static boolean has(String s)
{
return performers.containsKey(s);
}
static
{
performers = new TreeMap<String, vPerformer>();
long_names = new TreeMap<String, String>();
for (PerformerE pe : values())
{
performers.put(pe.short_name, pe.getPerformer());
long_names.put(pe.long_name, pe.short_name);
performer_list_short = performer_list_short + ChatColor.GREEN + pe.short_name + ChatColor.RED + ", ";
performer_list_long = performer_list_long + ChatColor.GREEN + pe.long_name + ChatColor.RED + ", ";
}
performer_list_short = performer_list_short.substring(0, performer_list_short.length() - 2);
performer_list_long = performer_list_long.substring(0, performer_list_long.length() - 2);
}
}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen