Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-09-06 08:02:50 +02:00
merge
Dieser Commit ist enthalten in:
Commit
4c2b753687
@ -1,27 +0,0 @@
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'maven'
|
||||
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include(dependency('com.martiansoftware:jsap:2.1'))
|
||||
}
|
||||
archiveName = "FastAsyncVoxelSniper-${project.name}-${parent.version}.jar"
|
||||
destinationDir = file '../target'
|
||||
}
|
||||
|
||||
build.dependsOn(shadowJar)
|
@ -1,29 +0,0 @@
|
||||
package com.boydti.fawe.bukkit.favs;
|
||||
|
||||
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(e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
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<>(brushes.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Immutable Multimap copy of all the registered brushes
|
||||
*/
|
||||
public Multimap<Class<? extends IBrush>, String> getRegisteredBrushesMultimap() {
|
||||
return ImmutableMultimap.copyOf(brushes);
|
||||
}
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
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: " + BlockTypes.get(snipeData.getReplaceId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 + BlockTypes.get(snipeData.getVoxelId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display voxel list.
|
||||
*/
|
||||
public void voxelList() {
|
||||
if (snipeData.getVoxelList().isEmpty()) {
|
||||
snipeData.sendMessage(ChatColor.DARK_GREEN + "No blocks selected!");
|
||||
} else {
|
||||
String returnValueBuilder = ChatColor.DARK_GREEN + "Block Types Selected: " + ChatColor.AQUA
|
||||
+ snipeData.getVoxelList();
|
||||
snipeData.sendMessage(returnValueBuilder);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper;
|
||||
|
||||
import org.bukkit.Art;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Painting;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* 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(null, 4).getLocation();
|
||||
Chunk paintingChunk = p.getTargetBlock(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 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,261 +0,0 @@
|
||||
/*
|
||||
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.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();
|
||||
}
|
||||
|
||||
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 = (this.playerLoc.getYaw() + 90.0F) % 360.0F;
|
||||
this.rotY = 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;
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper;
|
||||
|
||||
public enum SnipeAction {
|
||||
ARROW, GUNPOWDER
|
||||
}
|
@ -1,319 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
|
||||
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 Cylinder 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;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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().checkDisallowedBlocks(BlockTypes.getFromStateId(voxelId).getDefaultState())) {
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,653 +0,0 @@
|
||||
/*
|
||||
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.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.BlockTypes;
|
||||
import com.thevoxelbox.voxelsniper.brush.IBrush;
|
||||
import com.thevoxelbox.voxelsniper.brush.JockeyBrush;
|
||||
import com.thevoxelbox.voxelsniper.brush.SnipeBrush;
|
||||
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
|
||||
import com.thevoxelbox.voxelsniper.brush.perform.Performer;
|
||||
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.plugin.PluginManager;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Sniper {
|
||||
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.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().getInventory().getItemInMainHand().getType());
|
||||
}
|
||||
|
||||
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(() -> {
|
||||
if (!fp.runAction(
|
||||
() -> 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(0);
|
||||
// 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);
|
||||
if (brush instanceof JockeyBrush) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
brush.perform(snipeAction, snipeData, targetBlock, lastBlock);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (sniperTool.getCurrentBrush() instanceof PerformBrush) {
|
||||
PerformBrush performerBrush = (PerformBrush) sniperTool.getCurrentBrush();
|
||||
performerBrush.initP(snipeData);
|
||||
}
|
||||
brush.perform(snipeAction, snipeData, targetBlock, lastBlock);
|
||||
}
|
||||
} finally {
|
||||
snipeData.setExtent(null);
|
||||
Request.reset();
|
||||
}
|
||||
if (Fawe.isMainThread()) {
|
||||
SetQueue.IMP.flush(changeQueue);
|
||||
} else {
|
||||
changeQueue.flush();
|
||||
}
|
||||
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());
|
||||
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, count == 1 ? "" : " x" + count);
|
||||
} else {
|
||||
BBC.COMMAND_UNDO_ERROR.send(fp);
|
||||
}
|
||||
}
|
||||
|
||||
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 | IllegalAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return Sniper.class;
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
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());
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
/**
|
||||
* Holds {@link 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() {
|
||||
|
||||
}
|
||||
}
|
@ -1,245 +0,0 @@
|
||||
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.thevoxelbox.voxelsniper.brush.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Bukkit extension point.
|
||||
*/
|
||||
public class VoxelSniper extends JavaPlugin {
|
||||
private static VoxelSniper instance;
|
||||
private final VoxelSniperListener voxelSniperListener = new VoxelSniperListener(this);
|
||||
private SniperManager sniperManager = new SniperManager(this);
|
||||
private VoxelSniperConfiguration voxelSniperConfiguration;
|
||||
private Brushes brushManager = new Brushes();
|
||||
|
||||
/**
|
||||
* @return {@link VoxelSniper}
|
||||
*/
|
||||
public static VoxelSniper getInstance() {
|
||||
return VoxelSniper.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link com.thevoxelbox.voxelsniper.Brushes} for current instance.
|
||||
*
|
||||
* @return Brush Manager for current instance.
|
||||
*/
|
||||
public Brushes getBrushManager() {
|
||||
return brushManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
private static Map<String, Plugin> lookupNames;
|
||||
static {
|
||||
{ // Disable BetterBrushes - FAVS includes the features and BetterBrushes is outdated
|
||||
PluginManager manager = Bukkit.getPluginManager();
|
||||
try {
|
||||
Field pluginsField = manager.getClass().getDeclaredField("plugins");
|
||||
Field lookupNamesField = manager.getClass().getDeclaredField("lookupNames");
|
||||
pluginsField.setAccessible(true);
|
||||
lookupNamesField.setAccessible(true);
|
||||
List<Plugin> plugins = (List<Plugin>) pluginsField.get(manager);
|
||||
lookupNames = (Map<String, Plugin>) lookupNamesField.get(manager);
|
||||
pluginsField.set(manager, new ArrayList<Plugin>(plugins) {
|
||||
@Override
|
||||
public boolean add(Plugin plugin) {
|
||||
if (plugin.getName().startsWith("BetterBrushes")) {
|
||||
Fawe.debug("Disabling `" + plugin.getName() + "`. FastAsyncVoxelSniper includes all the features.");
|
||||
} else {
|
||||
return super.add(plugin);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
lookupNamesField.set(manager, lookupNames = new ConcurrentHashMap<String, Plugin>(lookupNames) {
|
||||
@Override
|
||||
public Plugin put(@NotNull String key, @NotNull Plugin plugin) {
|
||||
if (plugin.getName().startsWith("BetterBrushes")) {
|
||||
return null;
|
||||
}
|
||||
return super.put(key, plugin);
|
||||
}
|
||||
});
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, String commandLabel, @NotNull String[] args) {
|
||||
if (sender instanceof Player) {
|
||||
|
||||
return voxelSniperListener.onCommand((Player) sender, args, command.getName());
|
||||
}
|
||||
|
||||
getLogger().info("Only players can execute VoxelSniper 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 onCommand(player, new Command("p") {
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender sender, String commandLabel, @NotNull 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 onCommand(player, new Command("d") {
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender sender, String commandLabel, @NotNull 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(ErodeBlendBrush.class, "eb", "erodeblend", "erodeblendball");
|
||||
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");
|
||||
brushManager.registerSniperBrush(WallSider.class, "wallsider", "sider");
|
||||
}
|
||||
|
||||
public void setupCommand(final String label, final FaweCommand cmd) {
|
||||
this.getCommand(label).setExecutor(new BukkitCommand(cmd));
|
||||
}
|
||||
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
/**
|
||||
* 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_MESSAGE_ON_LOGIN_ENABLED = "message-on-login-enabled";
|
||||
public static final int DEFAULT_LITESNIPER_MAX_BRUSH_SIZE = 30;
|
||||
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 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldedit.extension.platform.PlatformCommandManager;
|
||||
import com.sk89q.worldedit.internal.command.exception.ExceptionConverter;
|
||||
import com.thevoxelbox.voxelsniper.api.command.VoxelCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelBrushCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelBrushToolCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelCenterCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelChunkCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelDefaultCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelGoToCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelHeightCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelInkCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelInkReplaceCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelListCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelPaintCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelPerformerCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelReplaceCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelSniperCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelUndoCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelUndoUserCommand;
|
||||
import com.thevoxelbox.voxelsniper.command.VoxelVoxelCommand;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
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;
|
||||
|
||||
|
||||
public class VoxelSniperListener implements Listener {
|
||||
|
||||
private static final String SNIPER_PERMISSION = "voxelsniper.sniper";
|
||||
private final VoxelSniper plugin;
|
||||
private Map<String, VoxelCommand> commands = new HashMap<>();
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
FawePlayer fp = FawePlayer.wrap(player);
|
||||
if (!fp.runAction(() -> {
|
||||
ExceptionConverter exceptionConverter = PlatformCommandManager.getInstance().getExceptionConverter();
|
||||
try {
|
||||
try {
|
||||
found.onCommand(player, split);
|
||||
return;
|
||||
} catch (Throwable t) {
|
||||
Throwable next = t;
|
||||
exceptionConverter.convert(next);
|
||||
while (next.getCause() != null) {
|
||||
next = next.getCause();
|
||||
exceptionConverter.convert(next);
|
||||
}
|
||||
throw next;
|
||||
}
|
||||
} catch (CommandException e) {
|
||||
String message = e.getMessage();
|
||||
if (message != null) {
|
||||
fp.sendMessage(e.getMessage());
|
||||
return;
|
||||
}
|
||||
e.printStackTrace();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
fp.sendMessage("An unknown FAWE error has occurred! Please see console.");
|
||||
}, false, true)) {
|
||||
BBC.WORLDEDIT_COMMAND_LIMIT.send(fp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@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 throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* A brush that creates a solid ball.
|
||||
*
|
||||
* @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";
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
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:");
|
||||
StringBuilder availableBiomes = new StringBuilder();
|
||||
|
||||
for (final Biome biome : Biome.values()) {
|
||||
if (availableBiomes.length() == 0) {
|
||||
availableBiomes = new StringBuilder(ChatColor.DARK_GREEN + biome.name());
|
||||
continue;
|
||||
}
|
||||
|
||||
availableBiomes.append(ChatColor.RED + ", " + ChatColor.DARK_GREEN)
|
||||
.append(biome.name());
|
||||
|
||||
}
|
||||
v.sendMessage(ChatColor.DARK_BLUE + "Available biomes: " + availableBiomes);
|
||||
} else {
|
||||
// allows biome names with spaces in their name
|
||||
StringBuilder biomeName = new StringBuilder(args[1]);
|
||||
for (int i = 2; i < args.length; i++) {
|
||||
biomeName.append(" ").append(args[i]);
|
||||
}
|
||||
|
||||
for (final Biome biome : Biome.values()) {
|
||||
if (biome.name().equalsIgnoreCase(biomeName.toString())) {
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.Undo;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
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++) {
|
||||
System.arraycopy(oldMaterials[x + 1][y + 1], 1, newMaterials[x][y], 0,
|
||||
brushSizeDoubled + 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 (BlockType 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++) {
|
||||
BlockType 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";
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public abstract class BlendBrushBase extends Brush {
|
||||
protected boolean excludeAir = true;
|
||||
protected boolean excludeWater = true;
|
||||
|
||||
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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected final boolean isExcludeAir() {
|
||||
return excludeAir;
|
||||
}
|
||||
|
||||
protected final void setExcludeAir(boolean excludeAir) {
|
||||
this.excludeAir = excludeAir;
|
||||
}
|
||||
|
||||
protected final boolean isExcludeWater() {
|
||||
return excludeWater;
|
||||
}
|
||||
|
||||
protected final void setExcludeWater(boolean excludeWater) {
|
||||
this.excludeWater = excludeWater;
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.Undo;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
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++) {
|
||||
System.arraycopy(oldMaterials[x + 1], 1, newMaterials[x], 0, brushSizeDoubled + 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 (BlockType 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++) {
|
||||
BlockType 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";
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.Undo;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
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++) {
|
||||
System.arraycopy(oldMaterials[x + 1][y + 1], 1, newMaterials[x][y], 0,
|
||||
brushSizeDoubled + 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 (BlockType 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++) {
|
||||
BlockType 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";
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.Undo;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
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++) {
|
||||
System.arraycopy(oldMaterials[x + 1], 1, newMaterials[x], 0, brushSizeDoubled + 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 (BlockType 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++) {
|
||||
BlockType 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";
|
||||
}
|
||||
}
|
@ -1,237 +0,0 @@
|
||||
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 java.util.Random;
|
||||
|
||||
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--) {
|
||||
System.arraycopy(tempSplat[x][y], 0, splat[x][y], 0, brushSizeDoubled + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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--) {
|
||||
System.arraycopy(tempSplat[x][y], 0, splat[x][y], 0, brushSizeDoubled + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockID;
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class BlockResetBrush extends Brush {
|
||||
private static final ArrayList<Material> DENIED_UPDATES = new ArrayList<>();
|
||||
|
||||
static {
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.ACACIA_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.SPRUCE_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.ACACIA_WALL_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.BIRCH_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.SPRUCE_WALL_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.BIRCH_WALL_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.DARK_OAK_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.DARK_OAK_WALL_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.JUNGLE_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.JUNGLE_WALL_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.OAK_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.OAK_WALL_SIGN);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.CHEST);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.FURNACE);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.REDSTONE_TORCH);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.REDSTONE_WALL_TORCH);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.REDSTONE_WIRE);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.OAK_DOOR);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.DARK_OAK_DOOR);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.BIRCH_DOOR);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.ACACIA_DOOR);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.SPRUCE_DOOR);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.JUNGLE_DOOR);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.IRON_DOOR);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.DARK_OAK_FENCE_GATE);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.ACACIA_FENCE_GATE);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.BIRCH_FENCE_GATE);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.SPRUCE_FENCE_GATE);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.JUNGLE_FENCE_GATE);
|
||||
BlockResetBrush.DENIED_UPDATES.add(Material.OAK_FENCE_GATE);
|
||||
}
|
||||
|
||||
public BlockResetBrush() {
|
||||
this.setName("Block Reset Brush");
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
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.BlockMaterial;
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import org.bukkit.Material;
|
||||
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,282 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncWorld;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
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.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 X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
* @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 Sniper caller
|
||||
* @param clickedBlock Block that the player targeted/interacted with
|
||||
* @param clickedFace Face of that targeted Block
|
||||
* @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(), 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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 setBlockLegacy(int x, int y, int z, int id, int data) {
|
||||
this.getWorld().getBlockAt(x, y, z).setCombinedId(LegacyMapper.getInstance().getBlockFromLegacy(id, data).getInternalId());
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@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";
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
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;
|
||||
|
||||
public class CheckerVoxelDiscBrush extends PerformBrush {
|
||||
private boolean useWorldCoordinates = true;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public CheckerVoxelDiscBrush() {
|
||||
this.setName("Checker Voxel Disc");
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
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;
|
||||
|
||||
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, BlockTypes.AIR.getInternalId());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
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.
|
||||
*
|
||||
* @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 height 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 Sniper 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 successfully.");
|
||||
}
|
||||
|
||||
@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 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";
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LargeFireball;
|
||||
import org.bukkit.entity.SmallFireball;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,177 +0,0 @@
|
||||
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;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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 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 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 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";
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
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;
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
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;
|
||||
|
||||
public class DiscBrush extends PerformBrush {
|
||||
private double trueCircle = 0;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*/
|
||||
public DiscBrush() {
|
||||
this.setName("Disc");
|
||||
}
|
||||
|
||||
/**
|
||||
* Disc executor.
|
||||
*
|
||||
* @param v Snipe Data
|
||||
*/
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
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.BlockFace;
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
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 org.bukkit.util.NumberConversions;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
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 Snipe Data
|
||||
* @param targetBlock the targetBlock to set
|
||||
*/
|
||||
@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<>();
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
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;
|
||||
|
||||
public class DrainBrush extends Brush {
|
||||
private double trueCircle = 0;
|
||||
private boolean disc = false;
|
||||
|
||||
public DrainBrush() {
|
||||
this.setName("Drain");
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,235 +0,0 @@
|
||||
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;
|
||||
|
||||
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 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";
|
||||
}
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
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;
|
||||
|
||||
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 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";
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
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<>(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<>();
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.Undo;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
|
||||
public class ErodeBlendBrush extends Brush {
|
||||
|
||||
private BlendBallBrush blendBall;
|
||||
private ErodeBrush erode;
|
||||
|
||||
public ErodeBlendBrush() {
|
||||
this.blendBall = new BlendBallBrush();
|
||||
this.erode = new ErodeBrush();
|
||||
this.setName("Erode BlendBall");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void arrow(final SnipeData v) {
|
||||
this.blendBall.excludeAir = false;
|
||||
this.blendBall.setTargetBlock(this.getTargetBlock());
|
||||
this.blendBall.arrow(v);
|
||||
this.erode.setTargetBlock(this.getTargetBlock());
|
||||
this.erode.arrow(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void powder(final SnipeData v) {
|
||||
this.blendBall.excludeAir = false;
|
||||
this.blendBall.setTargetBlock(this.getTargetBlock());
|
||||
this.blendBall.arrow(v);
|
||||
this.erode.setTargetBlock(this.getTargetBlock());
|
||||
this.erode.powder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void parameters(final String[] par, final SnipeData v) {
|
||||
this.blendBall.parameters(par, v);
|
||||
this.erode.parameters(par, v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.erodeblend";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Message vm) {
|
||||
this.erode.info(vm);
|
||||
this.blendBall.info(vm);
|
||||
}
|
||||
|
||||
}
|
@ -1,451 +0,0 @@
|
||||
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.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
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.*;
|
||||
|
||||
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) {
|
||||
}
|
||||
}
|
||||
|
||||
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(BukkitAdapter.adapt(blockWrapper.getMaterial()).getInternalId(), 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<>();
|
||||
|
||||
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 minimum 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.erode";
|
||||
}
|
||||
|
||||
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 separator Separator for delimiting entries.
|
||||
*/
|
||||
public static String getValuesString(String separator) {
|
||||
StringBuilder valuesString = new StringBuilder();
|
||||
|
||||
boolean delimiterHelper = true;
|
||||
for (final Preset preset : Preset.values()) {
|
||||
if (delimiterHelper) {
|
||||
delimiterHelper = false;
|
||||
} else {
|
||||
valuesString.append(separator);
|
||||
}
|
||||
valuesString.append(preset.name());
|
||||
}
|
||||
return valuesString.toString();
|
||||
}
|
||||
|
||||
public ErosionPreset getPreset() {
|
||||
return this.preset;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
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<>();
|
||||
this.flatChanges = new HashMap<>();
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public BlockWrapper get(final Vector position, final int iteration) {
|
||||
BlockWrapper changedBlock;
|
||||
|
||||
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<>());
|
||||
}
|
||||
|
||||
this.blockChanges.get(iteration).put(position, changedBlock);
|
||||
this.flatChanges.put(position, changedBlock);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class BlockWrapper {
|
||||
|
||||
private final AsyncBlock block;
|
||||
private final Material material;
|
||||
private final int data;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,177 +0,0 @@
|
||||
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;
|
||||
|
||||
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 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";
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
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.brush.perform.PerformBrush;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
|
||||
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(BlockTypes.AIR.getInternalId());
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
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.Material;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,630 +0,0 @@
|
||||
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 java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
// Proposal: Use /v and /vr for leave and wood material // or two more parameters -- Monofraps
|
||||
|
||||
public class GenerateTreeBrush extends Brush {
|
||||
// Tree Variables.
|
||||
private Random randGenerator = new Random();
|
||||
private ArrayList<Block> branchBlocks = new ArrayList<>();
|
||||
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 heightMinimum = 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.
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
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 directional 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.heightMinimum + 1) + this.heightMinimum;
|
||||
|
||||
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 branches 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 directional 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.heightMinimum + 1) + this.heightMinimum;
|
||||
|
||||
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 branches 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.heightMinimum = Integer.parseInt(parameter.replace("minh", ""));
|
||||
if (this.heightMinimum > this.heightMaximum) {
|
||||
this.heightMinimum = this.heightMaximum;
|
||||
v.sendMessage(ChatColor.RED + "Minimum Height exceed than Maximum Height, has been set to " + this.heightMinimum + " Instead!");
|
||||
} else {
|
||||
v.sendMessage(ChatColor.BLUE + "Minimum Height set to " + this.heightMinimum);
|
||||
}
|
||||
} else if (parameter.startsWith("maxh")) { // Height Maximum
|
||||
this.heightMaximum = Integer.parseInt(parameter.replace("maxh", ""));
|
||||
if (this.heightMinimum > this.heightMaximum) {
|
||||
this.heightMaximum = this.heightMinimum;
|
||||
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.heightMinimum = 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";
|
||||
}
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
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.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.bukkit.util.noise.PerlinNoiseGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
public class HeatRayBrush extends Brush {
|
||||
|
||||
/* 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<>();
|
||||
|
||||
static {
|
||||
for (Material m : Material.values()) {
|
||||
if (!m.isLegacy() && m.isBlock() && m.isFlammable()) {
|
||||
FLAMABLE_BLOCKS.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int octaves = 5;
|
||||
private double frequency = 1;
|
||||
private double amplitude = 0.3;
|
||||
|
||||
|
||||
/**
|
||||
* 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.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.parseInt(parameter.replace("oct", ""));
|
||||
v.getVoxelMessage().custom(ChatColor.GREEN + "Octaves: " + this.octaves);
|
||||
} else if (parameter.startsWith("amp")) {
|
||||
this.amplitude = Double.parseDouble(parameter.replace("amp", ""));
|
||||
v.getVoxelMessage().custom(ChatColor.GREEN + "Amplitude: " + this.amplitude);
|
||||
} else if (parameter.startsWith("freq")) {
|
||||
this.frequency = Double.parseDouble(parameter.replace("freq", ""));
|
||||
v.getVoxelMessage().custom(ChatColor.GREEN + "Frequency: " + this.frequency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.heatray";
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
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.util.BlockIterator;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class JaggedLineBrush extends PerformBrush {
|
||||
private static final Vector HALF_BLOCK_OFFSET = new Vector(0.5, 0.5, 0.5);
|
||||
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 static int timesUsed = 0;
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
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;
|
||||
|
||||
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.addPassenger(closest);
|
||||
} else {
|
||||
closest.addPassenger(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.addPassenger(entity);
|
||||
lastEntity = entity;
|
||||
stackHeight++;
|
||||
} else if (jockeyType == JockeyType.STACK_PLAYER_ONLY) {
|
||||
if (entity instanceof Player) {
|
||||
lastEntity.addPassenger(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());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void parameters(final String[] par, final SnipeData v) {
|
||||
|
||||
try {
|
||||
boolean inverse = false;
|
||||
boolean playerOnly = false;
|
||||
boolean stack = false;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.jockey";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
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.util.BlockIterator;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,251 +0,0 @@
|
||||
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.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Moves a selection blockPositionY a certain amount.
|
||||
*
|
||||
* @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<>();
|
||||
|
||||
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.parseInt(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.parseInt(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.parseInt(par[i].substring(1));
|
||||
v.getVoxelMessage().custom(ChatColor.AQUA + "Z direction set to: " + this.moveDirections[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.move";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<>();
|
||||
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 = Math.min(this.location1.getBlockX(), this.location2.getBlockX());
|
||||
final int lowY = Math.min(this.location1.getBlockY(), this.location2.getBlockY());
|
||||
final int lowZ = Math.min(this.location1.getBlockZ(), this.location2.getBlockZ());
|
||||
final int highX = Math.max(this.location1.getBlockX(), this.location2.getBlockX());
|
||||
final int highY = Math.max(this.location1.getBlockY(), this.location2.getBlockY());
|
||||
final int highZ = Math.max(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 of 5000000, 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 = Math.max((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";
|
||||
}
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.world.block.BlockID;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
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) {
|
||||
BlockType type = BlockTypes.get(materialId);
|
||||
switch (type.getInternalId()) {
|
||||
case BlockID.WATER:
|
||||
case BlockID.LAVA:
|
||||
case BlockID.CACTUS:
|
||||
return true;
|
||||
default:
|
||||
BlockMaterial mat = type.getMaterial();
|
||||
return mat.isTranslucent();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean isOverrideableMaterial(int materialId) {
|
||||
BlockMaterial mat = BlockTypes.get(materialId).getMaterial();
|
||||
if (allBlocks && !(mat.isAir())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !mat.isFragileWhenPushed() && mat.isFullCube();
|
||||
}
|
||||
|
||||
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.getBlockAt(this.getTargetBlock().getX() + x, y - 1,
|
||||
this.getTargetBlock().getZ() + z)
|
||||
.isEmpty()) { // if not a floating block (like one of Notch'world pools)
|
||||
if (this.getBlockAt(this.getTargetBlock().getX() + x, y + 1,
|
||||
this.getTargetBlock().getZ() + z)
|
||||
.isEmpty()) { // 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.
|
||||
|
||||
BlockType type = BukkitAdapter.asBlockType((this
|
||||
.getBlockType(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;
|
||||
|
||||
}
|
||||
} 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";
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.PaintingWrapper;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
|
||||
/**
|
||||
* Painting scrolling 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";
|
||||
}
|
||||
}
|
@ -1,311 +0,0 @@
|
||||
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 org.bukkit.ChatColor;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
|
||||
public class PullBrush extends Brush {
|
||||
private final HashSet<BlockWrapper> surface = new HashSet<>();
|
||||
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.getBlockAt(x, y, z).isEmpty() && ((this.getBlockAt(x, y - 1, z).isEmpty()) || (this.getBlockAt(x, y + 1, z).isEmpty()) || (this.getBlockAt(x + 1, y, z).isEmpty()) || (this.getBlockAt(x - 1, y, z).isEmpty()) || (this.getBlockAt(x, y, z + 1).isEmpty()) || (this.getBlockAt(x, y, z - 1).isEmpty()));
|
||||
|
||||
}
|
||||
|
||||
@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.getBlockAt(block.getX(), block.getY() - 1, block.getZ()).isEmpty()) {
|
||||
currentBlock.setTypeId(block.getId());
|
||||
currentBlock.setPropertyId(block.getD());
|
||||
for (int y = block.getY(); y < currentBlock.getY(); y++) {
|
||||
this.setBlockIdAt(block.getZ(), block.getX(), y, BlockTypes.AIR.getInternalId());
|
||||
}
|
||||
} 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, BlockTypes.AIR.getInternalId());
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.pull";
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,320 +0,0 @@
|
||||
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.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;
|
||||
|
||||
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.getFromInternalId(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 occurred.");
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.punish";
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
@ -1,357 +0,0 @@
|
||||
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 java.util.Random;
|
||||
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
int brushSize = ((this.bsize + 1) * 2) + 1;
|
||||
|
||||
if (this.snap.length == 0) {
|
||||
this.snap = new BlockWrapper[brushSize][brushSize][brushSize];
|
||||
|
||||
int sx = this.getTargetBlock().getX() - (this.bsize + 1);
|
||||
|
||||
for (int x = 0; x < this.snap.length; x++) {
|
||||
int sz = this.getTargetBlock().getZ() - (this.bsize + 1);
|
||||
for (int z = 0; z < this.snap.length; z++) {
|
||||
int 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[brushSize][brushSize][brushSize];
|
||||
|
||||
int sx = this.getTargetBlock().getX() - (this.bsize + 1);
|
||||
|
||||
for (int x = 0; x < this.snap.length; x++) {
|
||||
int sz = this.getTargetBlock().getZ() - (this.bsize + 1);
|
||||
for (int z = 0; z < this.snap.length; z++) {
|
||||
int 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(BlockTypes.AIR.getInternalId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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(BlockTypes.AIR.getInternalId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.randomerode";
|
||||
}
|
||||
|
||||
private class BlockWrapper {
|
||||
private boolean solid;
|
||||
private AsyncBlock nativeBlock;
|
||||
private int id;
|
||||
private int i;
|
||||
|
||||
public BlockWrapper(final AsyncBlock bl) {
|
||||
this.setNativeBlock(bl);
|
||||
this.setI(bl.getTypeId());
|
||||
switch (bl.getType()) {
|
||||
case AIR:
|
||||
case WATER:
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
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.util.BlockWrapper;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
|
||||
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(BlockTypes.AIR.getInternalId());
|
||||
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 (BlockTypes.get(block.getId()).getMaterial().isAir()) {
|
||||
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();
|
||||
|
||||
if (this.mode == 0) {
|
||||
this.getMatrix();
|
||||
this.rotate(v);
|
||||
} else {
|
||||
v.sendMessage(ChatColor.RED + "Something went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void powder(final SnipeData v) {
|
||||
this.bSize = v.getBrushSize();
|
||||
|
||||
if (this.mode == 0) {
|
||||
this.getMatrix();
|
||||
this.rotate(v);
|
||||
} else {
|
||||
v.sendMessage(ChatColor.RED + "Something went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
@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";
|
||||
}
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
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.util.BlockWrapper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
// 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 BlockWrapper[][][] snap;
|
||||
private double se;
|
||||
|
||||
public Rot2DvertBrush() {
|
||||
this.setName("2D Rotation");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void getMatrix() {
|
||||
int brushSize = (this.bSize * 2) + 1;
|
||||
|
||||
this.snap = new BlockWrapper[brushSize][brushSize][brushSize];
|
||||
|
||||
int sx = this.getTargetBlock().getX() - this.bSize;
|
||||
|
||||
for (int x = 0; x < this.snap.length; x++) {
|
||||
int sz = this.getTargetBlock().getZ() - this.bSize;
|
||||
|
||||
for (int z = 0; z < this.snap.length; z++) {
|
||||
int 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(BlockTypes.AIR.getInternalId());
|
||||
sy++;
|
||||
}
|
||||
|
||||
sz++;
|
||||
}
|
||||
sx++;
|
||||
}
|
||||
}
|
||||
|
||||
private void rotate() {
|
||||
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 (BlockTypes.get(block.getId()).getMaterial().isAir()) {
|
||||
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();
|
||||
|
||||
if (this.mode == 0) {
|
||||
this.getMatrix();
|
||||
this.rotate();
|
||||
} else {
|
||||
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void powder(final SnipeData v) {
|
||||
this.bSize = v.getBrushSize();
|
||||
|
||||
if (this.mode == 0) {
|
||||
this.getMatrix();
|
||||
this.rotate();
|
||||
} else {
|
||||
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
@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";
|
||||
}
|
||||
}
|
@ -1,231 +0,0 @@
|
||||
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 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(BlockTypes.AIR.getInternalId());
|
||||
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 undefined or whatever, then skip those.
|
||||
// --> Why not utilize Sniper'world new opportunities 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 differentiate 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 (BlockTypes.get(block.getId()).getMaterial().isAir()) {
|
||||
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();
|
||||
|
||||
if (this.mode == 0) {
|
||||
this.getMatrix();
|
||||
this.rotate(v);
|
||||
} else {
|
||||
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void powder(final SnipeData v) {
|
||||
this.bSize = v.getBrushSize();
|
||||
|
||||
if (this.mode == 0) {
|
||||
this.getMatrix();
|
||||
this.rotate(v);
|
||||
} else {
|
||||
v.owner().getPlayer().sendMessage(ChatColor.RED + "Something went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.rot3d";
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
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;
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
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;
|
||||
|
||||
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 {
|
||||
return Math.min(value, max);
|
||||
}
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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 = Math.min(this.block.getX(), bl.getX());
|
||||
final int lowY = Math.min(this.block.getY(), bl.getY());
|
||||
final int lowZ = Math.min(this.block.getZ(), bl.getZ());
|
||||
final int highX = Math.max(this.block.getX(), bl.getX());
|
||||
final int highY = Math.max(this.block.getY(), bl.getY());
|
||||
final int highZ = Math.max(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 of 5000000, 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";
|
||||
}
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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 = Math.min(this.block.getX(), bl.getX());
|
||||
final int lowY = Math.min(this.block.getY(), bl.getY());
|
||||
final int lowZ = Math.min(this.block.getZ(), bl.getZ());
|
||||
final int highX = Math.max(this.block.getX(), bl.getX());
|
||||
final int highY = Math.max(this.block.getY(), bl.getY());
|
||||
final int highZ = Math.max(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";
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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 = Math.min(this.block.getX(), bl.getX());
|
||||
final int lowY = Math.min(this.block.getY(), bl.getY());
|
||||
final int lowZ = Math.min(this.block.getZ(), bl.getZ());
|
||||
final int highX = Math.max(this.block.getX(), bl.getX());
|
||||
final int highY = Math.max(this.block.getY(), bl.getY());
|
||||
final int highZ = Math.max(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";
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
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.
|
||||
*
|
||||
* @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++) {
|
||||
System.arraycopy(oldMaterials[x + 1][y + 1], 1, newMaterials[x][y], 0,
|
||||
brushSizeDoubled + 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 sible 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";
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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 = Math.min(this.block.getX(), bl.getX());
|
||||
final int lowY = Math.min(this.block.getY(), bl.getY());
|
||||
final int lowZ = Math.min(this.block.getZ(), bl.getZ());
|
||||
final int highX = Math.max(this.block.getX(), bl.getX());
|
||||
final int highY = Math.max(this.block.getY(), bl.getY());
|
||||
final int highZ = Math.max(this.block.getZ(), bl.getZ());
|
||||
|
||||
int selectionSize = Math.abs(highX - lowX) * Math.abs(highZ - lowZ) * Math.abs(highY - lowY);
|
||||
if (selectionSize > MAX_SIZE) {
|
||||
v.sendMessage(ChatColor.RED + "Selection size above hardcoded limit of 5000000, please use a smaller selection.");
|
||||
} else {
|
||||
final ArrayList<AsyncBlock> blocks = new ArrayList<>(selectionSize / 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";
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
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.
|
||||
*
|
||||
* @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++) {
|
||||
System.arraycopy(oldMaterials[x + 1][y + 1], 1, newMaterials[x][y], 0,
|
||||
brushSizeSquared + 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";
|
||||
}
|
||||
}
|
@ -1,374 +0,0 @@
|
||||
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.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Overwrites signs.
|
||||
*
|
||||
* @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 target 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;
|
||||
}
|
||||
|
||||
StringBuilder newText = new StringBuilder();
|
||||
|
||||
// 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.append(currentParameter).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
newText = new StringBuilder(ChatColor.translateAlternateColorCodes('&', newText.toString()));
|
||||
|
||||
// remove last space or return if the string is empty and the user just wanted to set the status
|
||||
if ((newText.length() > 0) && newText.toString().endsWith(" ")) {
|
||||
newText = new StringBuilder(newText.substring(0, newText.length() - 1));
|
||||
} else if (newText.length() == 0) {
|
||||
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 = new StringBuilder(newText.substring(0, MAX_SIGN_LINE_LENGTH));
|
||||
}
|
||||
|
||||
this.signTextLines[lineIndex] = newText.toString();
|
||||
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();
|
||||
try (FileWriter outFile = new FileWriter(store); BufferedWriter outStream = new BufferedWriter(outFile)) {
|
||||
for (int i = 0; i < this.signTextLines.length; i++) {
|
||||
outStream.write(this.signLinesEnabled[i] + "\n");
|
||||
outStream.write(this.signTextLines[i] + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
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.parseBoolean(inStream.readLine());
|
||||
this.signTextLines[i] = inStream.readLine();
|
||||
}
|
||||
|
||||
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() {
|
||||
Arrays.fill(this.signTextLines, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets line enabled states to enabled.
|
||||
*/
|
||||
private void resetStates() {
|
||||
Arrays.fill(this.signLinesEnabled, 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";
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
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 com.thevoxelbox.voxelsniper.Undo;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
||||
|
||||
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.getBlockAt(blockPositionX - brushSize + x, blockPositionY - i, blockPositionZ - brushSize + z).isEmpty() || 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) != BlockTypes.SNOW.getInternalId()) {
|
||||
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 snow block
|
||||
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]) {
|
||||
BlockType blockType =
|
||||
BlockTypes.get(snowCone[x][z]);
|
||||
if (blockType.getMaterial().isAir()) {
|
||||
snowConeData[x][z] = snowData;
|
||||
snowCone[x][z] = BlockTypes.SNOW.getInternalId();
|
||||
|
||||
snowConeData[x][z] = snowData;
|
||||
} else if (blockType == BlockTypes.SNOW_BLOCK) {
|
||||
snowConeData[x][z] = snowData;
|
||||
}
|
||||
} 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) {
|
||||
if (getTargetBlock().getType() == Material.SNOW) {
|
||||
this.addSnow(v, this.getTargetBlock());
|
||||
} else {
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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";
|
||||
}
|
||||
}
|
@ -1,535 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
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 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");
|
||||
}
|
||||
|
||||
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;
|
||||
int startZ;
|
||||
int y = 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();
|
||||
}
|
||||
}
|
||||
|
||||
int xOffset = 0;
|
||||
int zOffset = 0;
|
||||
int toggle = 0;
|
||||
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)) {
|
||||
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, BlockTypes.AIR.getInternalId());
|
||||
}
|
||||
|
||||
} else {
|
||||
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, BlockTypes.AIR.getInternalId());
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
if (this.stairtype.equalsIgnoreCase("block")) {
|
||||
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i, v.getVoxelId());
|
||||
} else if (this.stairtype.equalsIgnoreCase("step")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z, 44, v.getPropertyId());
|
||||
} else if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair")) {
|
||||
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY + i - 1, v.getVoxelId());
|
||||
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (this.stairtype.equalsIgnoreCase("step")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z, 43, v.getPropertyId());
|
||||
} else if (this.stairtype.equalsIgnoreCase("woodstair")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z, 53, 0);
|
||||
} else if (this.stairtype.equalsIgnoreCase("cobblestair")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z, 67, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (this.stairtype.equalsIgnoreCase("woodstair")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z, 53, (spiral[x][i][z] - 2));
|
||||
} else if (this.stairtype.equalsIgnoreCase("cobblestair")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY + i, blockPositionZ - v.getBrushSize() + z, 67, (spiral[x][i][z] - 2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
v.owner().storeUndo(undo);
|
||||
}
|
||||
|
||||
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;
|
||||
int startZ;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
int xOffset = 0;
|
||||
int zOffset = 0;
|
||||
int toggle = 0;
|
||||
int y = 0;
|
||||
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:
|
||||
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, BlockTypes.AIR.getInternalId());
|
||||
break;
|
||||
case 1:
|
||||
if (this.stairtype.equalsIgnoreCase("block")) {
|
||||
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, v.getVoxelId());
|
||||
} else if (this.stairtype.equalsIgnoreCase("step")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z, 44, v.getPropertyId());
|
||||
} else if (this.stairtype.equalsIgnoreCase("woodstair") || this.stairtype.equalsIgnoreCase("cobblestair")) {
|
||||
this.setBlockIdAt(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, v.getVoxelId());
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (this.stairtype.equalsIgnoreCase("step")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z, 43, v.getPropertyId());
|
||||
} else if (this.stairtype.equalsIgnoreCase("woodstair")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z, 53, 0);
|
||||
} else if (this.stairtype.equalsIgnoreCase("cobblestair")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z, 67, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (this.stairtype.equalsIgnoreCase("woodstair")) {
|
||||
this.setBlockLegacy(blockPositionX - v.getBrushSize() + x, blockPositionY - i, blockPositionZ - v.getBrushSize() + z, 53, (spiral[x][i][z] - 2));
|
||||
} else if (this.stairtype.equalsIgnoreCase("cobblestair")) {
|
||||
this.setBlockLegacy(blockPositionZ - v.getBrushSize() + z, blockPositionX - v.getBrushSize() + x, blockPositionY - i, 67, (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++) {
|
||||
// stairs
|
||||
// step/slab
|
||||
|
||||
try {
|
||||
this.stairtype = par[i].toLowerCase().intern();
|
||||
v.sendMessage(ChatColor.BLUE + "Staircase type: " + this.stairtype);
|
||||
return;
|
||||
} catch (InputParseException ignore) {
|
||||
}
|
||||
if (par[i].equalsIgnoreCase("block") || par[i].equalsIgnoreCase("step") || par[i].equalsIgnoreCase("woodstair") || par[i].equalsIgnoreCase("cobblestair")) {
|
||||
this.stairtype = par[i].toLowerCase().intern();
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
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 java.util.Random;
|
||||
|
||||
|
||||
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--) {
|
||||
if (2 * v.getBrushSize() + 1 >= 0) {
|
||||
System.arraycopy(tempSplat[x][y], 0, splat[x][y], 0,
|
||||
2 * v.getBrushSize() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
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 java.util.Random;
|
||||
|
||||
|
||||
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--) {
|
||||
if (2 * v.getBrushSize() + 1 >= 0) {
|
||||
System.arraycopy(tempSplat[x], 0, splat[x], 0, 2 * v.getBrushSize() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,341 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
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;
|
||||
|
||||
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--) {
|
||||
if (2 * v.getBrushSize() + 1 >= 0) {
|
||||
System.arraycopy(tempSplat[x], 0, splat[x], 0, 2 * v.getBrushSize() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
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.
|
||||
BlockType 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).isEmpty()) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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).isEmpty()) {
|
||||
// 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--) {
|
||||
if (2 * v.getBrushSize() + 1 >= 0) {
|
||||
System.arraycopy(tempsplat[x], 0, splat[x], 0, 2 * v.getBrushSize() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
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.getBlockAt(this.getTargetBlock().getX() + x, y - 1, this.getTargetBlock().getZ() + z).isEmpty()) { // if not a floating block (like one of Notch'world pools)
|
||||
if (this.getBlockAt(this.getTargetBlock().getX() + x, y + 1, this.getTargetBlock().getZ() + z).isEmpty()) { // 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.
|
||||
|
||||
BlockType 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.
|
||||
}
|
||||
}
|
||||
} 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 occurred while processing parameter %s.", parameter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.splatteroverlay";
|
||||
}
|
||||
}
|
@ -1,207 +0,0 @@
|
||||
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 java.util.Random;
|
||||
|
||||
|
||||
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--) {
|
||||
if (2 * v.getBrushSize() + 1 >= 0) {
|
||||
System.arraycopy(tempSplat[x][y], 0, splat[x][y], 0,
|
||||
2 * v.getBrushSize() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,190 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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--) {
|
||||
if (2 * v.getBrushSize() + 1 >= 0) {
|
||||
System.arraycopy(tempSplat[x], 0, splat[x], 0, 2 * v.getBrushSize() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,248 +0,0 @@
|
||||
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<>();
|
||||
private final ArrayList<Block> ctrlPts = new ArrayList<>();
|
||||
protected ArrayList<Point> spline = new ArrayList<>();
|
||||
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 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.spline";
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,235 +0,0 @@
|
||||
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 java.util.HashSet;
|
||||
|
||||
public class StampBrush extends Brush {
|
||||
protected HashSet<BlockWrapper> clone = new HashSet<>();
|
||||
protected HashSet<BlockWrapper> fall = new HashSet<>();
|
||||
protected HashSet<BlockWrapper> drop = new HashSet<>();
|
||||
protected HashSet<BlockWrapper> solid = new HashSet<>();
|
||||
protected Undo undo;
|
||||
protected boolean sorted = false;
|
||||
protected StampType stamp = StampType.DEFAULT;
|
||||
|
||||
public StampBrush() {
|
||||
this.setName("Stamp");
|
||||
}
|
||||
|
||||
|
||||
public final void reSort() {
|
||||
this.sorted = false;
|
||||
}
|
||||
|
||||
protected final boolean falling(final int id) {
|
||||
return (id > 7 && id < 14);
|
||||
}
|
||||
|
||||
protected final boolean fallsOff(final int id) {
|
||||
return (BlockTypes.get(id).getMaterial().isFragileWhenPushed());
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void setStamp(final StampType type) {
|
||||
this.stamp = type;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
protected enum StampType {
|
||||
NO_AIR, FILL, DEFAULT
|
||||
}
|
||||
|
||||
|
||||
protected class BlockWrapper {
|
||||
public int id;
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
public int d;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,362 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
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 java.io.*;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* 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. )
|
||||
* <p>
|
||||
* 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("UnstableApiUsage")
|
||||
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();
|
||||
try (FaweOutputStream out = new FaweOutputStream(new DataOutputStream(new PGZIPOutputStream(new BufferedOutputStream(new FileOutputStream(file)))))) {
|
||||
int blockPositionX = Math.min(this.firstPoint[0], this.secondPoint[0]);
|
||||
int blockPositionZ = Math.min(this.firstPoint[1], this.secondPoint[1]);
|
||||
int blockPositionY = Math.min(this.firstPoint[2], this.secondPoint[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 + "'.");
|
||||
}
|
||||
|
||||
} 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";
|
||||
}
|
||||
}
|
@ -1,763 +0,0 @@
|
||||
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;
|
||||
|
||||
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<>();
|
||||
|
||||
public StencilListBrush() {
|
||||
this.setName("StencilList");
|
||||
}
|
||||
|
||||
private String readRandomStencil() {
|
||||
double rand = Math.random() * (this.stencilList.size());
|
||||
final int choice = (int) rand;
|
||||
return this.stencilList.get(choice);
|
||||
}
|
||||
|
||||
private void readStencilList() {
|
||||
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.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();
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
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();
|
||||
} 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";
|
||||
}
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
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;
|
||||
|
||||
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.");
|
||||
StringBuilder toleranceOptions = new StringBuilder();
|
||||
for (final Tolerance tolerance : Tolerance.values()) {
|
||||
if (toleranceOptions.length() > 0) {
|
||||
toleranceOptions.append("|");
|
||||
}
|
||||
toleranceOptions.append(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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.threepointcircle";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
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.BlockFace;
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,293 +0,0 @@
|
||||
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;
|
||||
|
||||
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;
|
||||
double lengthTwo;
|
||||
double lengthThree;
|
||||
double heronBig;
|
||||
|
||||
// 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(Math.max(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";
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
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).isEmpty()) {
|
||||
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 {
|
||||
for (int d = 0; (d < this.depth); d++) {
|
||||
if (!this.clampY(this.getTargetBlock().getX() + x, y + d, this.getTargetBlock().getZ() + z).isEmpty()) {
|
||||
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 {
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
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;
|
||||
|
||||
public class VoltMeterBrush extends Brush {
|
||||
|
||||
public VoltMeterBrush() {
|
||||
this.setName("VoltMeter");
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush;
|
||||
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush;
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
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;
|
||||
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
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.util.Vector;
|
||||
|
||||
public class WallSider extends Brush {
|
||||
|
||||
private static String[] facings = new String[]{"north", "east", "south", "west", "relative to player"};
|
||||
private short c;
|
||||
private short d;
|
||||
private double e;
|
||||
private boolean f;
|
||||
private boolean g;
|
||||
private boolean h;
|
||||
|
||||
public WallSider() {
|
||||
this.c = 4;
|
||||
this.d = 1;
|
||||
this.e = 0.0;
|
||||
this.setName("WallSider");
|
||||
}
|
||||
|
||||
private void a(final SnipeData snipeData, final Block block, final boolean b) {
|
||||
final double n = (snipeData.getBrushSize() + this.e) * (snipeData.getBrushSize() + this.e);
|
||||
final Vector vector;
|
||||
final Vector clone = (vector = block.getLocation().toVector()).clone();
|
||||
int c;
|
||||
if (this.c == 4) {
|
||||
double n2;
|
||||
if ((n2 = (snipeData.owner().getPlayer().getLocation().getYaw() - 90.0f) % 360.0f) < 0.0) {
|
||||
n2 += 360.0;
|
||||
}
|
||||
c = ((0.0 >= n2 && n2 < 45.0) ? 2 : ((45.0 >= n2 && n2 < 135.0) ? 3 : ((135.0 >= n2 && n2 < 225.0) ? 0 : ((225.0 >= n2 && n2 < 315.0) ? 1 : ((315.0 >= n2 && n2 < 360.0) ? 2 : -1)))));
|
||||
} else {
|
||||
c = this.c;
|
||||
}
|
||||
int n3 = c;
|
||||
if (b) {
|
||||
n3 = (short) ((n3 + 2) % 4);
|
||||
}
|
||||
int n4 = 98;
|
||||
if (n3 == 0 || n3 == 2) {
|
||||
n4 = 97;
|
||||
}
|
||||
for (int i = -snipeData.getBrushSize(); i <= snipeData.getBrushSize(); ++i) {
|
||||
if (n4 == 97) {
|
||||
clone.setX(vector.getX() + i);
|
||||
} else {
|
||||
clone.setZ(vector.getZ() + i);
|
||||
}
|
||||
for (int j = -snipeData.getBrushSize(); j <= snipeData.getBrushSize(); ++j) {
|
||||
clone.setY(vector.getY() + j);
|
||||
if (vector.distanceSquared(clone) <= n) {
|
||||
for (short n5 = 0; n5 < this.d; ++n5) {
|
||||
if (n4 == 97) {
|
||||
clone.setZ(vector.getZ() + ((n3 == 2) ? n5 : (-n5)));
|
||||
} else {
|
||||
clone.setX(vector.getX() + ((n3 == 1) ? n5 : (-n5)));
|
||||
}
|
||||
final AsyncBlock block2 = this.getWorld().getBlockAt(clone.getBlockX(), clone.getBlockY(), clone.getBlockZ());
|
||||
if ((this.f && block2.getTypeId() == snipeData.getReplaceId()) || (!this.f && (block2.getTypeId() != 0 || this.g))) {
|
||||
block2.setTypeId(snipeData.getVoxelId());
|
||||
}
|
||||
}
|
||||
if (n4 == 97) {
|
||||
clone.setZ(vector.getZ());
|
||||
} else {
|
||||
clone.setX(vector.getX());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void arrow(final SnipeData snipeData) {
|
||||
this.a(snipeData, this.getTargetBlock(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void powder(final SnipeData snipeData) {
|
||||
this.a(snipeData, this.getTargetBlock(), true);
|
||||
}
|
||||
|
||||
public final void parameters(final String[] array, final SnipeData snipeData) {
|
||||
for (int i = 1; i < array.length; ++i) {
|
||||
final String lowerCase;
|
||||
if ((lowerCase = array[i].toLowerCase()).startsWith("d")) {
|
||||
this.d = (short) Integer.parseInt(lowerCase.replace("d", ""));
|
||||
snipeData.sendMessage(ChatColor.AQUA + "Depth set to " + this.d + " blocks");
|
||||
} else if (lowerCase.startsWith("s")) {
|
||||
this.c = (short) Integer.parseInt(lowerCase.replace("s", ""));
|
||||
if (this.c > 4 || this.c < 0) {
|
||||
this.c = 4;
|
||||
}
|
||||
snipeData.sendMessage(ChatColor.AQUA + "Orientation set to " + facings[this.c]);
|
||||
} else if (lowerCase.startsWith("true")) {
|
||||
this.e = 0.5;
|
||||
snipeData.sendMessage(ChatColor.AQUA + "True circle mode ON.");
|
||||
} else if (lowerCase.startsWith("false")) {
|
||||
this.e = 0.0;
|
||||
snipeData.sendMessage(ChatColor.AQUA + "True circle mode OFF.");
|
||||
} else if (lowerCase.startsWith("air")) {
|
||||
this.g = true;
|
||||
snipeData.sendMessage(ChatColor.AQUA + "Including air.");
|
||||
} else if (lowerCase.startsWith("mm")) {
|
||||
this.f = true;
|
||||
snipeData.sendMessage(ChatColor.AQUA + "Replacing block.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermissionNode() {
|
||||
return "voxelsniper.brush.wallsider";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Message vm) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.thevoxelbox.voxelsniper.brush.perform;
|
||||
|
||||
import com.boydti.fawe.bukkit.wrapper.AsyncBlock;
|
||||
import com.boydti.fawe.object.pattern.PatternTraverser;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||
import com.thevoxelbox.voxelsniper.Message;
|
||||
import com.thevoxelbox.voxelsniper.SnipeData;
|
||||
|
||||
public class PatternPerformer extends vPerformer {
|
||||
private String info;
|
||||
private Pattern pattern;
|
||||
private Extent extent;
|
||||
private final MutableBlockVector3 mutable = new MutableBlockVector3();
|
||||
|
||||
@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) {
|
||||
BlockVector3 bv = mutable.setComponents(block.getX(), block.getY(), block.getZ());
|
||||
try {
|
||||
pattern.apply(extent, bv, bv);
|
||||
} catch (WorldEditException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
This file is part of VoxelSniper, licensed under the MIT License (MIT).
|
||||
<p>
|
||||
Copyright (c) The VoxelBox <http://thevoxelbox.com>
|
||||
Copyright (c) contributors
|
||||
<p>
|
||||
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:
|
||||
<p>
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
<p>
|
||||
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 org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class PerformBrush extends Brush implements Performer {
|
||||
protected vPerformer current = new pMaterial();
|
||||
|
||||
public PerformBrush() {
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return PerformBrush.class;
|
||||
}
|
||||
|
||||
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 = 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);
|
||||
}
|
||||
}
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren