Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-12-26 02:50:06 +01:00
Merge branch 'main' of https://github.com/IntellectualSites/FastAsyncWorldEdit into main
Dieser Commit ist enthalten in:
Commit
030c253732
@ -301,6 +301,9 @@ public class BukkitWorld extends AbstractWorld {
|
|||||||
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 pt) {
|
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 pt) {
|
||||||
World world = getWorld();
|
World world = getWorld();
|
||||||
TreeType bukkitType = toBukkitTreeType(type);
|
TreeType bukkitType = toBukkitTreeType(type);
|
||||||
|
if (bukkitType == TreeType.CHORUS_PLANT) {
|
||||||
|
pt = pt.add(0, 1, 0); // bukkit skips the feature gen which does this offset normally, so we have to add it back
|
||||||
|
}
|
||||||
return type != null && world.generateTree(BukkitAdapter.adapt(world, pt), bukkitType,
|
return type != null && world.generateTree(BukkitAdapter.adapt(world, pt), bukkitType,
|
||||||
new EditSessionBlockChangeDelegate(editSession));
|
new EditSessionBlockChangeDelegate(editSession));
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,9 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
public char get(int x, @Range(from = 0, to = 255) int y, int z) {
|
public char get(int x, @Range(from = 0, to = 255) int y, int z) {
|
||||||
final int layer = y >> 4;
|
final int layer = y >> 4;
|
||||||
final int index = (y & 15) << 8 | z << 4 | x;
|
final int index = (y & 15) << 8 | z << 4 | x;
|
||||||
|
if (layer >= sections.length || layer < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return sections[layer].get(this, layer, index);
|
return sections[layer].get(this, layer, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
if (biomes == null) {
|
if (biomes == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return biomes[(y >> 2) << 4 | (z & 3) << 2 | x & 3];
|
return biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -90,7 +90,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
if (biomes == null) {
|
if (biomes == null) {
|
||||||
biomes = new BiomeType[1024];
|
biomes = new BiomeType[1024];
|
||||||
}
|
}
|
||||||
biomes[(y >> 2) << 4 | (z & 3) << 2 | x & 3] = biome;
|
biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2] = biome;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,7 +481,7 @@ public class MCAChunk implements IChunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BiomeType getBiomeType(int x, int y, int z) {
|
public BiomeType getBiomeType(int x, int y, int z) {
|
||||||
return this.biomes[(y >> 2) << 4 | (z & 3) << 2 | x & 3];
|
return this.biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -505,7 +505,7 @@ public class MCAChunk implements IChunk {
|
|||||||
@Override
|
@Override
|
||||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
setModified();
|
setModified();
|
||||||
biomes[(y >> 2) << 4 | (z & 3) << 2 | x & 3] = biome;
|
biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2] = biome;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,10 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
}
|
}
|
||||||
if (!tilesTo.isEmpty()) {
|
if (!tilesTo.isEmpty()) {
|
||||||
for (Map.Entry<BlockVector3, CompoundTag> entry : tilesTo.entrySet()) {
|
for (Map.Entry<BlockVector3, CompoundTag> entry : tilesTo.entrySet()) {
|
||||||
addTileCreate(entry.getValue());
|
CompoundTag nbt = entry.getValue();
|
||||||
|
BlockVector3 pos = entry.getKey();
|
||||||
|
MainUtil.setPosition(nbt, pos.getX() + bx, pos.getY(), pos.getZ() + bz);
|
||||||
|
addTileCreate(nbt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Set<UUID> entRemoves = set.getEntityRemoves();
|
Set<UUID> entRemoves = set.getEntityRemoves();
|
||||||
|
@ -143,10 +143,11 @@ public class AsyncPlayer extends PlayerProxy {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void floatAt(int x, int y, int z, boolean alwaysGlass) {
|
public void floatAt(int x, int y, int z, boolean alwaysGlass) {
|
||||||
|
if (alwaysGlass || !isAllowedToFly()) {
|
||||||
RuntimeException caught = null;
|
RuntimeException caught = null;
|
||||||
try {
|
try {
|
||||||
EditSession edit = new EditSessionBuilder(WorldWrapper.unwrap(getWorld()))
|
EditSession edit =
|
||||||
.player(unwrap(getBasePlayer())).build();
|
new EditSessionBuilder(WorldWrapper.unwrap(getWorld())).player(unwrap(getBasePlayer())).build();
|
||||||
edit.setBlock(BlockVector3.at(x, y - 1, z), BlockTypes.GLASS);
|
edit.setBlock(BlockVector3.at(x, y - 1, z), BlockTypes.GLASS);
|
||||||
edit.flushQueue();
|
edit.flushQueue();
|
||||||
LocalSession session = Fawe.get().getWorldEdit().getSessionManager().get(this);
|
LocalSession session = Fawe.get().getWorldEdit().getSessionManager().get(this);
|
||||||
@ -156,10 +157,13 @@ public class AsyncPlayer extends PlayerProxy {
|
|||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
caught = e;
|
caught = e;
|
||||||
}
|
}
|
||||||
setPosition(Vector3.at(x + 0.5, y, z + 0.5));
|
|
||||||
if (caught != null) {
|
if (caught != null) {
|
||||||
throw caught;
|
throw caught;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
setFlying(true);
|
||||||
|
}
|
||||||
|
trySetPosition(Vector3.at(x + 0.5, y, z + 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -57,6 +57,7 @@ import com.sk89q.worldedit.function.GroundFunction;
|
|||||||
import com.sk89q.worldedit.function.RegionFunction;
|
import com.sk89q.worldedit.function.RegionFunction;
|
||||||
import com.sk89q.worldedit.function.block.BlockReplace;
|
import com.sk89q.worldedit.function.block.BlockReplace;
|
||||||
import com.sk89q.worldedit.function.block.Naturalizer;
|
import com.sk89q.worldedit.function.block.Naturalizer;
|
||||||
|
import com.sk89q.worldedit.function.block.SnowSimulator;
|
||||||
import com.sk89q.worldedit.function.generator.ForestGenerator;
|
import com.sk89q.worldedit.function.generator.ForestGenerator;
|
||||||
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
|
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
|
||||||
import com.sk89q.worldedit.function.mask.BlockStateMask;
|
import com.sk89q.worldedit.function.mask.BlockStateMask;
|
||||||
@ -97,6 +98,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.math.MathUtils;
|
import com.sk89q.worldedit.math.MathUtils;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector2;
|
import com.sk89q.worldedit.math.MutableBlockVector2;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||||
|
import com.sk89q.worldedit.math.Vector2;
|
||||||
import com.sk89q.worldedit.math.Vector3;
|
import com.sk89q.worldedit.math.Vector3;
|
||||||
import com.sk89q.worldedit.math.interpolation.Interpolation;
|
import com.sk89q.worldedit.math.interpolation.Interpolation;
|
||||||
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
|
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
|
||||||
@ -104,6 +106,7 @@ import com.sk89q.worldedit.math.interpolation.Node;
|
|||||||
import com.sk89q.worldedit.math.noise.RandomNoise;
|
import com.sk89q.worldedit.math.noise.RandomNoise;
|
||||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.regions.CylinderRegion;
|
||||||
import com.sk89q.worldedit.regions.EllipsoidRegion;
|
import com.sk89q.worldedit.regions.EllipsoidRegion;
|
||||||
import com.sk89q.worldedit.regions.FlatRegion;
|
import com.sk89q.worldedit.regions.FlatRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
@ -148,6 +151,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.sk89q.worldedit.function.block.SnowSimulator.snowy;
|
||||||
import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
|
import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
|
||||||
import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
|
import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
|
||||||
import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
|
import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
|
||||||
@ -2150,9 +2154,25 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
* @param radius the radius
|
* @param radius the radius
|
||||||
* @return number of blocks affected
|
* @return number of blocks affected
|
||||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||||
|
* @deprecated Use {@link #thaw(BlockVector3, double, int)}.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int thaw(BlockVector3 position, double radius)
|
public int thaw(BlockVector3 position, double radius)
|
||||||
|
throws MaxChangedBlocksException {
|
||||||
|
return thaw(position, radius,
|
||||||
|
WorldEdit.getInstance().getConfiguration().defaultVerticalHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thaw blocks in a cylinder.
|
||||||
|
*
|
||||||
|
* @param position the position
|
||||||
|
* @param radius the radius
|
||||||
|
* @param height the height (upwards and downwards)
|
||||||
|
* @return number of blocks affected
|
||||||
|
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||||
|
*/
|
||||||
|
public int thaw(BlockVector3 position, double radius, int height)
|
||||||
throws MaxChangedBlocksException {
|
throws MaxChangedBlocksException {
|
||||||
int affected = 0;
|
int affected = 0;
|
||||||
double radiusSq = radius * radius;
|
double radiusSq = radius * radius;
|
||||||
@ -2164,6 +2184,10 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
BlockState air = BlockTypes.AIR.getDefaultState();
|
BlockState air = BlockTypes.AIR.getDefaultState();
|
||||||
BlockState water = BlockTypes.WATER.getDefaultState();
|
BlockState water = BlockTypes.WATER.getDefaultState();
|
||||||
|
|
||||||
|
int centerY = Math.max(getWorld().getMinY(), Math.min(getWorld().getMaxY(), oy));
|
||||||
|
int minY = Math.max(getWorld().getMinY(), centerY - height);
|
||||||
|
int maxY = Math.min(getWorld().getMaxY(), centerY + height);
|
||||||
|
|
||||||
int ceilRadius = (int) Math.ceil(radius);
|
int ceilRadius = (int) Math.ceil(radius);
|
||||||
for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) {
|
for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) {
|
||||||
for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) {
|
for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) {
|
||||||
@ -2171,15 +2195,25 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int y = maxY; y >= 1; --y) {
|
for (int y = maxY; y > minY; --y) {
|
||||||
BlockType id = getBlock(x, y, z).getBlockType();
|
BlockVector3 pt = BlockVector3.at(x, y, z);
|
||||||
|
BlockVector3 below = BlockVector3.at(x, y - 1, z);
|
||||||
|
BlockType id = getBlock(pt).getBlockType();
|
||||||
|
|
||||||
if (id == BlockTypes.ICE) {
|
if (id == BlockTypes.ICE) {
|
||||||
if (setBlock(x, y, z, water)) {
|
if (setBlock(pt, water)) {
|
||||||
++affected;
|
++affected;
|
||||||
}
|
}
|
||||||
} else if (id == BlockTypes.SNOW) {
|
} else if (id == BlockTypes.SNOW) {
|
||||||
if (setBlock(x, y, z, air)) {
|
if (setBlock(pt, air)) {
|
||||||
|
if (y > 0 ) {
|
||||||
|
BlockState block = getBlock(below);
|
||||||
|
if (block.getStates().containsKey(snowy)) {
|
||||||
|
if (setBlock(below, block.with(snowy, false))) {
|
||||||
|
affected++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
++affected;
|
++affected;
|
||||||
}
|
}
|
||||||
} else if (id.getMaterial().isAir()) {
|
} else if (id.getMaterial().isAir()) {
|
||||||
@ -2191,7 +2225,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return changes = affected;
|
return affected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2201,67 +2235,46 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
* @param radius a radius
|
* @param radius a radius
|
||||||
* @return number of blocks affected
|
* @return number of blocks affected
|
||||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||||
|
* @deprecated Use {@link #simulateSnow(BlockVector3, double, int)}.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int simulateSnow(BlockVector3 position, double radius) throws MaxChangedBlocksException {
|
public int simulateSnow(BlockVector3 position, double radius) throws MaxChangedBlocksException {
|
||||||
int affected = 0;
|
return simulateSnow(position, radius,
|
||||||
double radiusSq = radius * radius;
|
WorldEdit.getInstance().getConfiguration().defaultVerticalHeight);
|
||||||
|
|
||||||
int ox = position.getBlockX();
|
|
||||||
int oy = position.getBlockY();
|
|
||||||
int oz = position.getBlockZ();
|
|
||||||
|
|
||||||
BlockState ice = BlockTypes.ICE.getDefaultState();
|
|
||||||
BlockState snow = BlockTypes.SNOW.getDefaultState();
|
|
||||||
|
|
||||||
int ceilRadius = (int) Math.ceil(radius);
|
|
||||||
for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) {
|
|
||||||
for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) {
|
|
||||||
if ((BlockVector3.at(x, oy, z)).distanceSq(position) > radiusSq) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int y = maxY; y >= 1; --y) {
|
/**
|
||||||
BlockVector3 pt = BlockVector3.at(x, y, z);
|
* Make snow in a cylinder.
|
||||||
BlockType id = getBlock(pt).getBlockType();
|
*
|
||||||
|
* @param position a position
|
||||||
|
* @param radius a radius
|
||||||
|
* @param height the height (upwards and downwards)
|
||||||
|
* @return number of blocks affected
|
||||||
|
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||||
|
*/
|
||||||
|
public int simulateSnow(BlockVector3 position, double radius, int height)
|
||||||
|
throws MaxChangedBlocksException {
|
||||||
|
|
||||||
if (id.getMaterial().isAir()) {
|
return simulateSnow(new CylinderRegion(position, Vector2.at(radius, radius), position.getBlockY(), height), false);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ice!
|
/**
|
||||||
if (id == BlockTypes.WATER) {
|
* Make snow in a region.
|
||||||
if (setBlock(pt, ice)) {
|
*
|
||||||
++affected;
|
* @param region the region to simulate snow in
|
||||||
}
|
* @param stack whether it should stack existing snow
|
||||||
break;
|
* @return number of blocks affected
|
||||||
}
|
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||||
|
*/
|
||||||
|
public int simulateSnow(FlatRegion region, boolean stack)
|
||||||
|
throws MaxChangedBlocksException {
|
||||||
|
checkNotNull(region);
|
||||||
|
|
||||||
// Snow should not cover these blocks
|
SnowSimulator snowSimulator = new SnowSimulator(this, stack);
|
||||||
if (id.getMaterial().isTranslucent()) {
|
LayerVisitor layerVisitor = new LayerVisitor(region, region.getMinimumY(), region.getMaximumY(), snowSimulator);
|
||||||
// Add snow on leaves
|
Operations.completeLegacy(layerVisitor);
|
||||||
if (!BlockCategories.LEAVES.contains(id)) {
|
return snowSimulator.getAffected();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Too high?
|
|
||||||
if (y == maxY) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add snow cover
|
|
||||||
if (setBlock(pt.add(0, 1, 0), snow)) {
|
|
||||||
++affected;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changes = affected;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make dirt green.
|
* Make dirt green.
|
||||||
*
|
*
|
||||||
@ -2270,52 +2283,67 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
* @param onlyNormalDirt only affect normal dirt (all default properties)
|
* @param onlyNormalDirt only affect normal dirt (all default properties)
|
||||||
* @return number of blocks affected
|
* @return number of blocks affected
|
||||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||||
|
* @deprecated Use {@link #green(BlockVector3, double, int, boolean)}.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int green(BlockVector3 position, double radius, boolean onlyNormalDirt)
|
public int green(BlockVector3 position, double radius, boolean onlyNormalDirt)
|
||||||
throws MaxChangedBlocksException {
|
throws MaxChangedBlocksException {
|
||||||
|
return green(position, radius,
|
||||||
|
WorldEdit.getInstance().getConfiguration().defaultVerticalHeight, onlyNormalDirt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make dirt green in a cylinder.
|
||||||
|
*
|
||||||
|
* @param position the position
|
||||||
|
* @param radius the radius
|
||||||
|
* @param height the height
|
||||||
|
* @param onlyNormalDirt only affect normal dirt (all default properties)
|
||||||
|
* @return number of blocks affected
|
||||||
|
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||||
|
*/
|
||||||
|
public int green(BlockVector3 position, double radius, int height, boolean onlyNormalDirt)
|
||||||
|
throws MaxChangedBlocksException {
|
||||||
|
int affected = 0;
|
||||||
final double radiusSq = radius * radius;
|
final double radiusSq = radius * radius;
|
||||||
|
|
||||||
final int ox = position.getBlockX();
|
final int ox = position.getBlockX();
|
||||||
|
final int oy = position.getBlockY();
|
||||||
final int oz = position.getBlockZ();
|
final int oz = position.getBlockZ();
|
||||||
|
|
||||||
final BlockState grass = BlockTypes.GRASS_BLOCK.getDefaultState();
|
final BlockState grass = BlockTypes.GRASS_BLOCK.getDefaultState();
|
||||||
|
|
||||||
|
final int centerY = Math.max(getWorld().getMinY(), Math.min(getWorld().getMaxY(), oy));
|
||||||
|
final int minY = Math.max(getWorld().getMinY(), centerY - height);
|
||||||
|
final int maxY = Math.min(getWorld().getMaxY(), centerY + height);
|
||||||
|
|
||||||
final int ceilRadius = (int) Math.ceil(radius);
|
final int ceilRadius = (int) Math.ceil(radius);
|
||||||
for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) {
|
for (int x = ox - ceilRadius; x <= ox + ceilRadius; ++x) {
|
||||||
int dx = x - ox;
|
|
||||||
int dx2 = dx * dx;
|
|
||||||
for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) {
|
for (int z = oz - ceilRadius; z <= oz + ceilRadius; ++z) {
|
||||||
int dz = z - oz;
|
if ((BlockVector3.at(x, oy, z)).distanceSq(position) > radiusSq) {
|
||||||
int dz2 = dz * dz;
|
|
||||||
if (dx2 + dz2 > radiusSq) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
loop:
|
|
||||||
for (int y = maxY; y >= 1; --y) {
|
for (int y = maxY; y > minY; --y) {
|
||||||
final BlockType block = getBlockType(x, y, z);
|
final BlockVector3 pt = BlockVector3.at(x, y, z);
|
||||||
switch (block.getInternalId()) {
|
final BlockState block = getBlock(pt);
|
||||||
case BlockID.COARSE_DIRT:
|
|
||||||
if (onlyNormalDirt) {
|
if (block.getBlockType() == BlockTypes.DIRT
|
||||||
break loop;
|
|| (!onlyNormalDirt && block.getBlockType() == BlockTypes.COARSE_DIRT)) {
|
||||||
}
|
if (setBlock(pt, grass)) {
|
||||||
this.setBlock(x, y, z, grass);
|
++affected;
|
||||||
break loop;
|
|
||||||
case BlockID.DIRT:
|
|
||||||
this.setBlock(x, y, z, grass);
|
|
||||||
break loop;
|
|
||||||
case BlockID.WATER:
|
|
||||||
case BlockID.LAVA:
|
|
||||||
default:
|
|
||||||
if (block.getMaterial().isMovementBlocker()) {
|
|
||||||
break loop;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
} else if (block.getBlockType() == BlockTypes.WATER || block.getBlockType() == BlockTypes.LAVA) {
|
||||||
|
break;
|
||||||
|
} else if (block.getBlockType().getMaterial().isMovementBlocker()) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return changes;
|
return affected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,6 +34,7 @@ import com.sk89q.worldedit.LocalSession;
|
|||||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.command.argument.HeightConverter;
|
||||||
import com.sk89q.worldedit.command.util.CommandPermissions;
|
import com.sk89q.worldedit.command.util.CommandPermissions;
|
||||||
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
|
||||||
import com.sk89q.worldedit.command.util.CreatureButcher;
|
import com.sk89q.worldedit.command.util.CreatureButcher;
|
||||||
@ -54,10 +55,12 @@ import com.sk89q.worldedit.function.operation.Operations;
|
|||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.function.visitor.EntityVisitor;
|
import com.sk89q.worldedit.function.visitor.EntityVisitor;
|
||||||
import com.sk89q.worldedit.internal.annotation.Direction;
|
import com.sk89q.worldedit.internal.annotation.Direction;
|
||||||
|
import com.sk89q.worldedit.internal.annotation.VertHeight;
|
||||||
import com.sk89q.worldedit.internal.expression.EvaluationException;
|
import com.sk89q.worldedit.internal.expression.EvaluationException;
|
||||||
import com.sk89q.worldedit.internal.expression.Expression;
|
import com.sk89q.worldedit.internal.expression.Expression;
|
||||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.math.Vector2;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.regions.CylinderRegion;
|
import com.sk89q.worldedit.regions.CylinderRegion;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
@ -464,6 +467,7 @@ public class UtilityCommands {
|
|||||||
return affected;
|
return affected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
name = "snow",
|
name = "snow",
|
||||||
aliases = { "/snow" },
|
aliases = { "/snow" },
|
||||||
@ -472,13 +476,27 @@ public class UtilityCommands {
|
|||||||
@CommandPermissions("worldedit.snow")
|
@CommandPermissions("worldedit.snow")
|
||||||
@Logging(PLACEMENT)
|
@Logging(PLACEMENT)
|
||||||
public int snow(Actor actor, LocalSession session, EditSession editSession,
|
public int snow(Actor actor, LocalSession session, EditSession editSession,
|
||||||
@Arg(desc = "The radius of the circle to snow in", def = "10")
|
@Arg(desc = "The radius of the cylinder to snow in", def = "10")
|
||||||
double size) throws WorldEditException {
|
double size,
|
||||||
|
@Arg(
|
||||||
|
desc = "The height of the cylinder to snow in",
|
||||||
|
def = HeightConverter.DEFAULT_VALUE
|
||||||
|
)
|
||||||
|
@VertHeight
|
||||||
|
int height,
|
||||||
|
@Switch(name = 's', desc = "Stack snow layers")
|
||||||
|
boolean stack) throws WorldEditException {
|
||||||
size = Math.max(1, size);
|
size = Math.max(1, size);
|
||||||
|
height = Math.max(1, height);
|
||||||
we.checkMaxRadius(size);
|
we.checkMaxRadius(size);
|
||||||
|
|
||||||
int affected = editSession.simulateSnow(session.getPlacementPosition(actor), size);
|
BlockVector3 position = session.getPlacementPosition(actor);
|
||||||
actor.printInfo(TranslatableComponent.of("worldedit.snow.created", TextComponent.of(affected)));
|
|
||||||
|
CylinderRegion region = new CylinderRegion(position, Vector2.at(size, size), position.getBlockY() - height, position.getBlockY() + height);
|
||||||
|
int affected = editSession.simulateSnow(region, stack);
|
||||||
|
actor.printInfo(TranslatableComponent.of(
|
||||||
|
"worldedit.snow.created", TextComponent.of(affected)
|
||||||
|
));
|
||||||
return affected;
|
return affected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,13 +508,22 @@ public class UtilityCommands {
|
|||||||
@CommandPermissions("worldedit.thaw")
|
@CommandPermissions("worldedit.thaw")
|
||||||
@Logging(PLACEMENT)
|
@Logging(PLACEMENT)
|
||||||
public int thaw(Actor actor, LocalSession session, EditSession editSession,
|
public int thaw(Actor actor, LocalSession session, EditSession editSession,
|
||||||
@Arg(desc = "The radius of the circle to thaw in", def = "10")
|
@Arg(desc = "The radius of the cylinder to thaw in", def = "10")
|
||||||
double size) throws WorldEditException {
|
double size,
|
||||||
|
@Arg(
|
||||||
|
desc = "The height of the cylinder to thaw in",
|
||||||
|
def = HeightConverter.DEFAULT_VALUE
|
||||||
|
)
|
||||||
|
@VertHeight
|
||||||
|
int height) throws WorldEditException {
|
||||||
size = Math.max(1, size);
|
size = Math.max(1, size);
|
||||||
|
height = Math.max(1, height);
|
||||||
we.checkMaxRadius(size);
|
we.checkMaxRadius(size);
|
||||||
|
|
||||||
int affected = editSession.thaw(session.getPlacementPosition(actor), size);
|
int affected = editSession.thaw(session.getPlacementPosition(actor), size, height);
|
||||||
actor.printInfo(TranslatableComponent.of("worldedit.thaw.removed", TextComponent.of(affected)));
|
actor.printInfo(TranslatableComponent.of(
|
||||||
|
"worldedit.thaw.removed", TextComponent.of(affected)
|
||||||
|
));
|
||||||
return affected;
|
return affected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,16 +535,27 @@ public class UtilityCommands {
|
|||||||
@CommandPermissions("worldedit.green")
|
@CommandPermissions("worldedit.green")
|
||||||
@Logging(PLACEMENT)
|
@Logging(PLACEMENT)
|
||||||
public int green(Actor actor, LocalSession session, EditSession editSession,
|
public int green(Actor actor, LocalSession session, EditSession editSession,
|
||||||
@Arg(desc = "The radius of the circle to convert in", def = "10")
|
@Arg(desc = "The radius of the cylinder to convert in", def = "10")
|
||||||
double size,
|
double size,
|
||||||
|
@Arg(
|
||||||
|
desc = "The height of the cylinder to convert in",
|
||||||
|
def = HeightConverter.DEFAULT_VALUE
|
||||||
|
)
|
||||||
|
@VertHeight
|
||||||
|
int height,
|
||||||
@Switch(name = 'f', desc = "Also convert coarse dirt")
|
@Switch(name = 'f', desc = "Also convert coarse dirt")
|
||||||
boolean convertCoarse) throws WorldEditException {
|
boolean convertCoarse) throws WorldEditException {
|
||||||
size = Math.max(1, size);
|
size = Math.max(1, size);
|
||||||
|
height = Math.max(1, height);
|
||||||
we.checkMaxRadius(size);
|
we.checkMaxRadius(size);
|
||||||
final boolean onlyNormalDirt = !convertCoarse;
|
final boolean onlyNormalDirt = !convertCoarse;
|
||||||
|
|
||||||
final int affected = editSession.green(session.getPlacementPosition(actor), size, onlyNormalDirt);
|
final int affected = editSession.green(
|
||||||
actor.printInfo(TranslatableComponent.of("worldedit.green.changed", TextComponent.of(affected)));
|
session.getPlacementPosition(actor), size, height, onlyNormalDirt
|
||||||
|
);
|
||||||
|
actor.printInfo(TranslatableComponent.of(
|
||||||
|
"worldedit.green.changed", TextComponent.of(affected)
|
||||||
|
));
|
||||||
return affected;
|
return affected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,12 +23,15 @@ import com.sk89q.worldedit.WorldEditException;
|
|||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.LayerFunction;
|
import com.sk89q.worldedit.function.LayerFunction;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.registry.state.BooleanProperty;
|
||||||
import com.sk89q.worldedit.registry.state.Property;
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
public class SnowSimulator implements LayerFunction {
|
public class SnowSimulator implements LayerFunction {
|
||||||
|
|
||||||
|
public static final BooleanProperty snowy = (BooleanProperty) (Property<?>) BlockTypes.GRASS_BLOCK.getProperty("snowy");
|
||||||
|
|
||||||
private final BlockState ice = BlockTypes.ICE.getDefaultState();
|
private final BlockState ice = BlockTypes.ICE.getDefaultState();
|
||||||
private final BlockState snow = BlockTypes.SNOW.getDefaultState();
|
private final BlockState snow = BlockTypes.SNOW.getDefaultState();
|
||||||
private final BlockState snowBlock = BlockTypes.SNOW_BLOCK.getDefaultState();
|
private final BlockState snowBlock = BlockTypes.SNOW_BLOCK.getDefaultState();
|
||||||
@ -42,6 +45,7 @@ public class SnowSimulator implements LayerFunction {
|
|||||||
private int affected;
|
private int affected;
|
||||||
|
|
||||||
public SnowSimulator(Extent extent, boolean stack) {
|
public SnowSimulator(Extent extent, boolean stack) {
|
||||||
|
|
||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
this.stack = stack;
|
this.stack = stack;
|
||||||
|
|
||||||
@ -66,9 +70,8 @@ public class SnowSimulator implements LayerFunction {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can only place on full solid blocks
|
// Stop searching when we hit a movement blocker
|
||||||
return block.getBlockType().getMaterial().isFullCube()
|
return block.getBlockType().getMaterial().isMovementBlocker();
|
||||||
&& block.getBlockType().getMaterial().isSolid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -107,16 +110,25 @@ public class SnowSimulator implements LayerFunction {
|
|||||||
// We've hit the highest layer (If it doesn't contain current + 2 it means it's 1 away from full)
|
// We've hit the highest layer (If it doesn't contain current + 2 it means it's 1 away from full)
|
||||||
if (!snowLayersProperty.getValues().contains(currentHeight + 2)) {
|
if (!snowLayersProperty.getValues().contains(currentHeight + 2)) {
|
||||||
if (this.extent.setBlock(abovePosition, snowBlock)) {
|
if (this.extent.setBlock(abovePosition, snowBlock)) {
|
||||||
|
if (block.getStates().containsKey(snowy)) {
|
||||||
|
this.extent.setBlock(position, block.with(snowy, true));
|
||||||
|
}
|
||||||
this.affected++;
|
this.affected++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.extent.setBlock(abovePosition, above.with(snowLayersProperty, currentHeight + 1))) {
|
if (this.extent.setBlock(abovePosition, above.with(snowLayersProperty, currentHeight + 1))) {
|
||||||
|
if (block.getStates().containsKey(snowy)) {
|
||||||
|
this.extent.setBlock(position, block.with(snowy, true));
|
||||||
|
}
|
||||||
this.affected++;
|
this.affected++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.extent.setBlock(abovePosition, snow)) {
|
if (this.extent.setBlock(abovePosition, snow)) {
|
||||||
|
if (block.getStates().containsKey(snowy)) {
|
||||||
|
this.extent.setBlock(position, block.with(snowy, true));
|
||||||
|
}
|
||||||
this.affected++;
|
this.affected++;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren