2019-07-21 22:49:08 -04:00

154 lines
7.1 KiB
Java

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";
}
}