mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-13 14:58:35 +00:00
Remove hardcoding of world limits (#1199)
* Remove hardcoding of world limits - seems to be working fine without the datapack for world height changing - particular attention should be given to LocalBlockVectorSet and MathMan changes * update adapters * Override getMinY in various classes and ensure selections have a world attached to them * no message * Address comments - Fix for lighting mode 1 * A few more changes * Fix LocalBlockVectorSet * Fix range statement * Various fixes/comment-addressing - There's not much point in having a different file name now for history. We've broken it before... - Fix history read/write - Fix range on for loops in CharBlocks * undo bad CharBlocks change * Fix history y level * Fix biome history * Fix lighting * Fix /up * Make regen fail not because of these changes * Fixes for y < 0 * Fix isEmpty where only the uppermost chunksection is edited * Fix javadocs/FAWE annotations * Better explain why BiomeMath is removed * If history task throws an error, it should only be caught and printed if not completing now. * Min|max world heights for new patterns * Load biomes from NMS instead of bukkit (#1200) * Update adapters * Update adapters * Don't initialise BlockTypes when biomes aren't set up yet so all BiomeTypes.BIOME are no longer null thanks. * Address some comments. * rename layer -> sectionIndex to imply inclusivity * Javadoctored. Co-authored-by: NotMyFault <mc.cache@web.de> Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com>
This commit is contained in:
@ -1184,6 +1184,16 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
return getBlockChangeCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getMinimumPoint() {
|
||||
return getWorld().getMinimumPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getMaximumPoint() {
|
||||
return getWorld().getMaximumPoint();
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
public void setSize(int size) {
|
||||
this.changes = size;
|
||||
@ -1276,7 +1286,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
public <B extends BlockStateHolder<B>> int fall(final Region region, boolean fullHeight, final B replace) {
|
||||
FlatRegion flat = asFlatRegion(region);
|
||||
final int startPerformY = region.getMinimumPoint().getBlockY();
|
||||
final int startCheckY = fullHeight ? 0 : startPerformY;
|
||||
final int startCheckY = fullHeight ? getMinY() : startPerformY;
|
||||
final int endY = region.getMaximumPoint().getBlockY();
|
||||
RegionVisitor visitor = new RegionVisitor(flat, pos -> {
|
||||
int x = pos.getX();
|
||||
@ -1353,7 +1363,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
|
||||
|
||||
// Pick how we're going to visit blocks
|
||||
RecursiveVisitor visitor = new DirectionalVisitor(mask, replace, origin, direction, (int) (radius * 2 + 1));
|
||||
RecursiveVisitor visitor = new DirectionalVisitor(mask, replace, origin, direction, (int) (radius * 2 + 1), minY, maxY);
|
||||
|
||||
// Start at the origin
|
||||
visitor.visit(origin);
|
||||
@ -1406,8 +1416,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
Mask mask = new MaskIntersection(
|
||||
new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
|
||||
new BoundedHeightMask(
|
||||
Math.max(origin.getBlockY() - depth + 1, getMinimumPoint().getBlockY()),
|
||||
Math.min(getMaxY(), origin.getBlockY())
|
||||
Math.max(origin.getBlockY() - depth + 1, minY),
|
||||
Math.min(maxY, origin.getBlockY())
|
||||
),
|
||||
Masks.negate(new ExistingBlockMask(this))
|
||||
);
|
||||
@ -1417,11 +1427,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
|
||||
// Pick how we're going to visit blocks
|
||||
RecursiveVisitor visitor;
|
||||
//FAWE start - provide extent for preloading
|
||||
//FAWE start - provide extent for preloading, min/max y
|
||||
if (recursive) {
|
||||
visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1), this);
|
||||
visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1), minY, maxY, this);
|
||||
} else {
|
||||
visitor = new DownwardVisitor(mask, replace, origin.getBlockY(), (int) (radius * 2 + 1), this);
|
||||
visitor = new DownwardVisitor(mask, replace, origin.getBlockY(), (int) (radius * 2 + 1), minY, maxY, this);
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
@ -1938,7 +1948,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
//FAWE end
|
||||
}
|
||||
Mask mask = new MaskIntersection(
|
||||
new BoundedHeightMask(getWorld().getMinY(), getWorld().getMaxY()),
|
||||
new BoundedHeightMask(minY, maxY),
|
||||
new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
|
||||
//FAWE start
|
||||
liquidMask
|
||||
@ -1950,8 +1960,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
} else {
|
||||
replace = new BlockReplace(this, BlockTypes.AIR.getDefaultState());
|
||||
}
|
||||
//FAWE start - provide extent for preloading
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1), this);
|
||||
//FAWE start - provide extent for preloading, min/max y
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1), minY, maxY, this);
|
||||
//FAWE end
|
||||
|
||||
// Around the origin in a 3x3 block
|
||||
@ -1989,14 +1999,14 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
|
||||
// There are boundaries that the routine needs to stay in
|
||||
Mask mask = new MaskIntersection(
|
||||
new BoundedHeightMask(getWorld().getMinY(), Math.min(origin.getBlockY(), getWorld().getMaxY())),
|
||||
new BoundedHeightMask(minY, Math.min(origin.getBlockY(), maxY)),
|
||||
new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))),
|
||||
blockMask
|
||||
);
|
||||
|
||||
BlockReplace replace = new BlockReplace(this, fluid.getDefaultState());
|
||||
//FAWE start - provide extent for preloading
|
||||
NonRisingVisitor visitor = new NonRisingVisitor(mask, replace, Integer.MAX_VALUE, this);
|
||||
//FAWE start - provide extent for preloading, world min/maxY
|
||||
NonRisingVisitor visitor = new NonRisingVisitor(mask, replace, Integer.MAX_VALUE, minY, maxY, this);
|
||||
//FAWE end
|
||||
|
||||
// Around the origin in a 3x3 block
|
||||
@ -2411,7 +2421,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (y != 0 && (yy = py - y) >= 0) {
|
||||
if (y != 0 && (yy = py - y) >= minY) {
|
||||
this.setBlock(px + x, yy, pz + z, block);
|
||||
if (x != 0) {
|
||||
this.setBlock(px - x, yy, pz + z, block);
|
||||
@ -2506,9 +2516,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
BlockState air = BlockTypes.AIR.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 centerY = Math.max(minY, Math.min(maxY, oy));
|
||||
int minY = Math.max(this.minY, centerY - height);
|
||||
int maxY = Math.min(this.maxY, centerY + height);
|
||||
|
||||
//FAWE start - mutable
|
||||
MutableBlockVector3 mutable = new MutableBlockVector3();
|
||||
@ -2535,8 +2545,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
++affected;
|
||||
}
|
||||
} else if (id == BlockTypes.SNOW) {
|
||||
//FAWE start
|
||||
if (setBlock(mutable, air)) {
|
||||
if (y > 0) {
|
||||
if (y > getMinY()) {
|
||||
BlockState block = getBlock(mutable2);
|
||||
if (block.getStates().containsKey(snowy)) {
|
||||
if (setBlock(mutable2, block.with(snowy, false))) {
|
||||
@ -2649,9 +2660,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
|
||||
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 centerY = Math.max(minY, Math.min(maxY, oy));
|
||||
final int minY = Math.max(this.minY, centerY - height);
|
||||
final int maxY = Math.min(this.maxY, centerY + height);
|
||||
|
||||
//FAWE start - mutable
|
||||
MutableBlockVector3 mutable = new MutableBlockVector3();
|
||||
@ -2952,7 +2963,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
int zv = (int) (z.getValue() * unit.getZ() + zero2.getZ());
|
||||
|
||||
BlockState get;
|
||||
if (yv >= 0 && yv < 256) {
|
||||
if (yv >= minY && yv <= maxY) {
|
||||
get = getBlock(xv, yv, zv);
|
||||
} else {
|
||||
get = BlockTypes.AIR.getDefaultState();
|
||||
@ -3538,7 +3549,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
int xx = x + bx;
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int zz = z + bz;
|
||||
for (int y = 0; y < maxY + 1; y++) {
|
||||
for (int y = minY; y < maxY + 1; y++) {
|
||||
BaseBlock block = getFullBlock(mutable.setComponents(xx, y, zz));
|
||||
fcs.add(mutable, block, BlockTypes.AIR.getDefaultState().toBaseBlock());
|
||||
}
|
||||
@ -3561,7 +3572,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int zz = z + bz;
|
||||
mutable.mutZ(zz);
|
||||
for (int y = 0; y < maxY + 1; y++) {
|
||||
for (int y = minY; y < maxY + 1; y++) {
|
||||
mutable.mutY(y);
|
||||
boolean contains = (fe == null || fe.contains(xx, y, zz)) && region.contains(mutable);
|
||||
if (contains) {
|
||||
|
@ -211,6 +211,13 @@ public class LocalSession implements TextureHolder {
|
||||
if (defaultSelector != null) {
|
||||
this.selector = defaultSelector.createSelector();
|
||||
}
|
||||
//FAWE start
|
||||
if (worldOverride != null) {
|
||||
this.selector.setWorld(worldOverride);
|
||||
} else {
|
||||
this.selector.setWorld(currentWorld);
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
|
@ -457,6 +457,7 @@ public class BrushCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.stencil")
|
||||
public void stencilBrush(
|
||||
Player player,
|
||||
LocalSession session, InjectedValueAccess context,
|
||||
@Arg(desc = "Pattern")
|
||||
Pattern fill,
|
||||
@ -478,13 +479,15 @@ public class BrushCommands {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
InputStream stream = getHeightmapStream(image);
|
||||
HeightBrush brush;
|
||||
int minY = player.getWorld().getMinY();
|
||||
int maxY = player.getWorld().getMaxY();
|
||||
try {
|
||||
brush = new StencilBrush(stream, rotation, yscale, onlyWhite,
|
||||
"#clipboard".equalsIgnoreCase(image)
|
||||
? session.getClipboard().getClipboard() : null
|
||||
? session.getClipboard().getClipboard() : null, minY, maxY
|
||||
);
|
||||
} catch (EmptyClipboardException ignored) {
|
||||
brush = new StencilBrush(stream, rotation, yscale, onlyWhite, null);
|
||||
brush = new StencilBrush(stream, rotation, yscale, onlyWhite, null, minY, maxY);
|
||||
}
|
||||
if (randomRotate) {
|
||||
brush.setRandomRotate(true);
|
||||
@ -710,6 +713,7 @@ public class BrushCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.height")
|
||||
public void heightBrush(
|
||||
Player player,
|
||||
LocalSession session,
|
||||
@Arg(desc = "Expression", def = "5")
|
||||
Expression radius,
|
||||
@ -728,7 +732,7 @@ public class BrushCommands {
|
||||
boolean dontSmooth, InjectedValueAccess context
|
||||
)
|
||||
throws WorldEditException, FileNotFoundException {
|
||||
terrainBrush(session, radius, image, rotation, yscale, false, randomRotate, layers,
|
||||
terrainBrush(player, session, radius, image, rotation, yscale, false, randomRotate, layers,
|
||||
!dontSmooth, ScalableHeightMap.Shape.CONE, context
|
||||
);
|
||||
}
|
||||
@ -741,6 +745,7 @@ public class BrushCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.height")
|
||||
public void cliffBrush(
|
||||
Player player,
|
||||
LocalSession session,
|
||||
@Arg(desc = "Expression", def = "5")
|
||||
Expression radius,
|
||||
@ -760,7 +765,7 @@ public class BrushCommands {
|
||||
boolean dontSmooth, InjectedValueAccess context
|
||||
)
|
||||
throws WorldEditException, FileNotFoundException {
|
||||
terrainBrush(session, radius, image, rotation, yscale, true, randomRotate, layers,
|
||||
terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers,
|
||||
!dontSmooth, ScalableHeightMap.Shape.CYLINDER, context
|
||||
);
|
||||
}
|
||||
@ -775,6 +780,7 @@ public class BrushCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.height")
|
||||
public void flattenBrush(
|
||||
Player player,
|
||||
LocalSession session,
|
||||
@Arg(desc = "Expression", def = "5")
|
||||
Expression radius,
|
||||
@ -794,12 +800,13 @@ public class BrushCommands {
|
||||
boolean dontSmooth, InjectedValueAccess context
|
||||
)
|
||||
throws WorldEditException, FileNotFoundException {
|
||||
terrainBrush(session, radius, image, rotation, yscale, true, randomRotate, layers,
|
||||
terrainBrush(player, session, radius, image, rotation, yscale, true, randomRotate, layers,
|
||||
!dontSmooth, ScalableHeightMap.Shape.CONE, context
|
||||
);
|
||||
}
|
||||
|
||||
private void terrainBrush(
|
||||
Player player,
|
||||
LocalSession session,
|
||||
Expression radius,
|
||||
String image,
|
||||
@ -816,23 +823,25 @@ public class BrushCommands {
|
||||
worldEdit.checkMaxBrushRadius(radius);
|
||||
InputStream stream = getHeightmapStream(image);
|
||||
HeightBrush brush;
|
||||
int minY = player.getWorld().getMinY();
|
||||
int maxY = player.getWorld().getMaxY();
|
||||
if (flat) {
|
||||
try {
|
||||
brush = new FlattenBrush(stream, rotation, yscale, layers, smooth,
|
||||
"#clipboard".equalsIgnoreCase(image)
|
||||
? session.getClipboard().getClipboard() : null, shape
|
||||
? session.getClipboard().getClipboard() : null, shape, minY, maxY
|
||||
);
|
||||
} catch (EmptyClipboardException ignored) {
|
||||
brush = new FlattenBrush(stream, rotation, yscale, layers, smooth, null, shape);
|
||||
brush = new FlattenBrush(stream, rotation, yscale, layers, smooth, null, shape, minY, maxY);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
brush = new HeightBrush(stream, rotation, yscale, layers, smooth,
|
||||
"#clipboard".equalsIgnoreCase(image)
|
||||
? session.getClipboard().getClipboard() : null
|
||||
? session.getClipboard().getClipboard() : null, minY, maxY
|
||||
);
|
||||
} catch (EmptyClipboardException ignored) {
|
||||
brush = new HeightBrush(stream, rotation, yscale, layers, smooth, null);
|
||||
brush = new HeightBrush(stream, rotation, yscale, layers, smooth, null, minY, maxY);
|
||||
}
|
||||
}
|
||||
if (randomRotate) {
|
||||
|
@ -635,12 +635,18 @@ public class GenerationCommands {
|
||||
@Arg(desc = "Ore vein size") @Range(from = 0, to = Integer.MAX_VALUE) int size,
|
||||
@Arg(desc = "Ore vein frequency (number of times to attempt to place ore)", def = "10") @Range(from = 0, to = Integer.MAX_VALUE) int freq,
|
||||
@Arg(desc = "Ore vein rarity (% chance each attempt is placed)", def = "100") @Range(from = 0, to = 100) int rarity,
|
||||
@Arg(desc = "Ore vein min y", def = "0") @Range(from = 0, to = 255) int minY,
|
||||
@Arg(desc = "Ore vein max y", def = "63") @Range(from = 0, to = 255) int maxY
|
||||
@Arg(desc = "Ore vein min y", def = "0") int minY,
|
||||
@Arg(desc = "Ore vein max y", def = "63") int maxY
|
||||
) throws WorldEditException {
|
||||
if (mask instanceof AbstractExtentMask) {
|
||||
((AbstractExtentMask) mask).setExtent(editSession);
|
||||
}
|
||||
checkCommandArgument(minY >= editSession.getMinY(), Caption.of("fawe.error.outside-range-lower", "miny",
|
||||
editSession.getMinY()));
|
||||
checkCommandArgument(maxY <= editSession.getMaxY(), Caption.of("fawe.error.outside-range-upper", "maxy",
|
||||
editSession.getMaxY()));
|
||||
checkCommandArgument(minY < maxY, Caption.of("fawe.error.argument-size-mismatch", "miny",
|
||||
"maxy"));
|
||||
editSession.addOre(region, mask, material, size, freq, rarity, minY, maxY);
|
||||
actor.print(Caption.of("fawe.worldedit.visitor.visitor.block", editSession.getBlockChangeCount()));
|
||||
}
|
||||
|
@ -133,8 +133,8 @@ public class HistorySubCommands {
|
||||
Location origin = player.getLocation();
|
||||
BlockVector3 bot = origin.toBlockPoint().subtract(radius, radius, radius);
|
||||
BlockVector3 top = origin.toBlockPoint().add(radius, radius, radius);
|
||||
bot = bot.clampY(0, world.getMaxY());
|
||||
top = top.clampY(0, world.getMaxY());
|
||||
bot = bot.clampY(world.getMinY(), world.getMaxY());
|
||||
top = top.clampY(world.getMinY(), world.getMaxY());
|
||||
// TODO mask the regions bot / top to the bottom and top coord in the allowedRegions
|
||||
// TODO: then mask the edit to the bot / top
|
||||
// if (allowedRegions.length != 1 || !allowedRegions[0].isGlobal()) {
|
||||
@ -196,9 +196,9 @@ public class HistorySubCommands {
|
||||
.summarize(RegionWrapper.GLOBAL(), false);
|
||||
if (summary != null) {
|
||||
rollback.setDimensions(
|
||||
BlockVector3.at(summary.minX, 0, summary.minZ),
|
||||
BlockVector3.at(summary.minX, world.getMinY(), summary.minZ),
|
||||
BlockVector3
|
||||
.at(summary.maxX, 255, summary.maxZ)
|
||||
.at(summary.maxX, world.getMaxY(), summary.maxZ)
|
||||
);
|
||||
rollback.setTime(historyFile.lastModified());
|
||||
RollbackDatabase db = DBHandler.IMP
|
||||
@ -410,8 +410,8 @@ public class HistorySubCommands {
|
||||
|
||||
BlockVector3 bot = origin.toBlockPoint().subtract(radius, radius, radius);
|
||||
BlockVector3 top = origin.toBlockPoint().add(radius, radius, radius);
|
||||
bot = bot.clampY(0, world.getMaxY());
|
||||
top = top.clampY(0, world.getMaxY());
|
||||
bot = bot.clampY(world.getMinY(), world.getMaxY());
|
||||
top = top.clampY(world.getMinY(), world.getMaxY());
|
||||
|
||||
long minTime = System.currentTimeMillis() - timeDiff;
|
||||
Iterable<Supplier<RollbackOptimizedHistory>> edits = database.getEdits(other, minTime, bot, top, false, false);
|
||||
|
@ -363,17 +363,23 @@ public class RegionCommands {
|
||||
@Selection Region region,
|
||||
@Arg(name = "pattern", desc = "The pattern of blocks to lay") Pattern patternArg
|
||||
) throws WorldEditException {
|
||||
BlockVector3 max = region.getMaximumPoint();
|
||||
int maxY = max.getBlockY();
|
||||
//FAWE start - world min/maxY
|
||||
int maxY = region.getMaximumY();
|
||||
int minY = region.getMinimumY();
|
||||
//FAWE end
|
||||
Iterable<BlockVector2> flat = Regions.asFlatRegion(region).asFlatRegion();
|
||||
Iterator<BlockVector2> iter = flat.iterator();
|
||||
int y = 0;
|
||||
//FAWE start - world min/maxY
|
||||
int y = minY;
|
||||
//FAWE end
|
||||
int affected = 0;
|
||||
while (iter.hasNext()) {
|
||||
BlockVector2 pos = iter.next();
|
||||
int x = pos.getBlockX();
|
||||
int z = pos.getBlockZ();
|
||||
y = editSession.getNearestSurfaceTerrainBlock(x, z, y, 0, maxY);
|
||||
//FAWE start - world min/maxY
|
||||
y = editSession.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY);
|
||||
//FAWE end
|
||||
editSession.setBlock(x, y, z, patternArg);
|
||||
affected++;
|
||||
}
|
||||
@ -856,6 +862,7 @@ public class RegionCommands {
|
||||
)
|
||||
@CommandPermissions("worldedit.region.flora")
|
||||
@Logging(REGION)
|
||||
@Preload(Preload.PreloadCheck.PRELOAD)
|
||||
@Confirm(Confirm.Processor.REGION)
|
||||
public int flora(
|
||||
Actor actor, EditSession editSession, @Selection Region region,
|
||||
@ -867,7 +874,7 @@ public class RegionCommands {
|
||||
FloraGenerator generator = new FloraGenerator(editSession);
|
||||
GroundFunction ground = new GroundFunction(new ExistingBlockMask(editSession), generator);
|
||||
//FAWE start - provide extent for preloading
|
||||
LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground, editSession);
|
||||
LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
|
||||
//FAWE end
|
||||
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
|
||||
Operations.completeLegacy(visitor);
|
||||
|
@ -124,9 +124,9 @@ public class SelectionCommands {
|
||||
Location pos;
|
||||
//FAWE start - clamp
|
||||
if (coordinates != null) {
|
||||
pos = new Location(world, coordinates.toVector3().clampY(0, world.getMaxY()));
|
||||
pos = new Location(world, coordinates.toVector3().clampY(world.getMinY(), world.getMaxY()));
|
||||
} else if (actor instanceof Locatable) {
|
||||
pos = ((Locatable) actor).getBlockLocation().clampY(0, world.getMaxY());
|
||||
pos = ((Locatable) actor).getBlockLocation().clampY(world.getMinY(), world.getMaxY());
|
||||
//FAWE end
|
||||
} else {
|
||||
actor.print(Caption.of("worldedit.pos.console-require-coords"));
|
||||
@ -157,9 +157,9 @@ public class SelectionCommands {
|
||||
Location pos;
|
||||
if (coordinates != null) {
|
||||
//FAWE start - clamp
|
||||
pos = new Location(world, coordinates.toVector3().clampY(0, world.getMaxY()));
|
||||
pos = new Location(world, coordinates.toVector3().clampY(world.getMinY(), world.getMaxY()));
|
||||
} else if (actor instanceof Locatable) {
|
||||
pos = ((Locatable) actor).getBlockLocation().clampY(0, world.getMaxY());
|
||||
pos = ((Locatable) actor).getBlockLocation().clampY(world.getMinY(), world.getMaxY());
|
||||
//Fawe end
|
||||
} else {
|
||||
actor.print(Caption.of("worldedit.pos.console-require-coords"));
|
||||
@ -258,7 +258,7 @@ public class SelectionCommands {
|
||||
.clampY(minChunkY, maxChunkY);
|
||||
|
||||
min = minChunk.shl(CHUNK_SHIFTS, CHUNK_SHIFTS_Y, CHUNK_SHIFTS);
|
||||
max = maxChunk.shl(CHUNK_SHIFTS, CHUNK_SHIFTS_Y, CHUNK_SHIFTS).add(15, world.getMaxY(), 15);
|
||||
max = maxChunk.shl(CHUNK_SHIFTS, CHUNK_SHIFTS_Y, CHUNK_SHIFTS).add(15, 255, 15);
|
||||
|
||||
actor.print(Caption.of(
|
||||
"worldedit.chunk.selected-multiple",
|
||||
@ -286,7 +286,7 @@ public class SelectionCommands {
|
||||
}
|
||||
|
||||
min = minChunk.shl(CHUNK_SHIFTS, CHUNK_SHIFTS_Y, CHUNK_SHIFTS);
|
||||
max = min.add(15, world.getMaxY(), 15);
|
||||
max = min.add(15, 255, 15);
|
||||
|
||||
actor.print(Caption.of(
|
||||
"worldedit.chunk.selected",
|
||||
|
@ -413,8 +413,8 @@ public class UtilityCommands {
|
||||
) throws WorldEditException {
|
||||
size = Math.max(1, size);
|
||||
we.checkMaxRadius(size);
|
||||
height = height != null ? Math.min((world.getMaxY() + 1), height + 1) : (world.getMaxY() + 1);
|
||||
|
||||
height = height != null ? Math.min((world.getMaxY() - world.getMinY() + 1), height + 1) : (world.getMaxY() - world.getMinY() + 1);
|
||||
int affected = editSession.removeAbove(session.getPlacementPosition(actor), size, height);
|
||||
actor.print(Caption.of("worldedit.removeabove.removed", TextComponent.of(affected)));
|
||||
return affected;
|
||||
@ -436,8 +436,8 @@ public class UtilityCommands {
|
||||
) throws WorldEditException {
|
||||
size = Math.max(1, size);
|
||||
we.checkMaxRadius(size);
|
||||
height = height != null ? Math.min((world.getMaxY() + 1), height + 1) : (world.getMaxY() + 1);
|
||||
|
||||
height = height != null ? Math.min((world.getMaxY() - world.getMinY() + 1), height + 1) : (world.getMaxY() - world.getMinY() + 1);
|
||||
int affected = editSession.removeBelow(session.getPlacementPosition(actor), size, height);
|
||||
actor.print(Caption.of("worldedit.removebelow.removed", TextComponent.of(affected)));
|
||||
return affected;
|
||||
|
@ -388,7 +388,7 @@ public class BrushTool
|
||||
final int x = loc.getBlockX();
|
||||
final int z = loc.getBlockZ();
|
||||
int y;
|
||||
for (y = height; y > 0; y--) {
|
||||
for (y = height; y > editSession.getMinY(); y--) {
|
||||
BlockType block = editSession.getBlockType(x, y, z);
|
||||
if (block.getMaterial().isMovementBlocker()) {
|
||||
break;
|
||||
|
@ -87,7 +87,8 @@ public class FloodFillTool implements BlockTool {
|
||||
//FAWE start - Respect masks
|
||||
Mask mask = initialType.toMask(editSession);
|
||||
BlockReplace function = new BlockReplace(editSession, pattern);
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(mask, function, range, editSession);
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(mask, function, range, editSession.getMinY(),
|
||||
editSession.getMaxY(), editSession);
|
||||
visitor.visit(origin);
|
||||
Operations.completeLegacy(visitor);
|
||||
//FAWE end
|
||||
|
@ -86,7 +86,14 @@ public class RecursivePickaxe implements BlockTool {
|
||||
final int radius = (int) range;
|
||||
final BlockReplace replace = new BlockReplace(editSession, (BlockTypes.AIR.getDefaultState()));
|
||||
editSession.setMask(null);
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(new IdMask(editSession), replace, radius, editSession);
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(
|
||||
new IdMask(editSession),
|
||||
replace,
|
||||
radius,
|
||||
editSession.getMinY(),
|
||||
editSession.getMaxY(),
|
||||
editSession
|
||||
);
|
||||
//TODO: Fix below
|
||||
//visitor.visit(pos);
|
||||
//Operations.completeBlindly(visitor);
|
||||
|
@ -39,8 +39,8 @@ public class GravityBrush implements Brush {
|
||||
MaxChangedBlocksException {
|
||||
//FAWE start - Ours operates differently to upstream, but does the same
|
||||
double endY = position.getY() + size;
|
||||
double startPerformY = Math.max(0, position.getY() - size);
|
||||
double startCheckY = fullHeight ? 0 : startPerformY;
|
||||
double startPerformY = Math.max(editSession.getMinY(), position.getY() - size);
|
||||
double startCheckY = fullHeight ? editSession.getMinY() : startPerformY;
|
||||
for (double x = position.getX() + size; x > position.getX() - size; --x) {
|
||||
for (double z = position.getZ() + size; z > position.getZ() - size; --z) {
|
||||
double freeSpot = startCheckY;
|
||||
|
@ -69,7 +69,7 @@ public class OffsetMaskParser extends InputParser<Mask> implements AliasedParser
|
||||
submask = new ExistingBlockMask(context.requireExtent());
|
||||
}
|
||||
//FAWE start - OffsetMask > OffsetsMask
|
||||
return new OffsetMask(submask, BlockVector3.at(0, firstChar == '>' ? -1 : 1, 0));
|
||||
return new OffsetMask(submask, BlockVector3.at(0, firstChar == '>' ? -1 : 1, 0), context.getMinY(), context.getMaxY());
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.extension.factory.MaskFactory;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Locatable;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
@ -50,6 +51,8 @@ public class ParserContext {
|
||||
private boolean preferringWildcard;
|
||||
//Fawe start
|
||||
private InjectedValueAccess injected;
|
||||
private int minY = Integer.MIN_VALUE;
|
||||
private int maxY = Integer.MAX_VALUE;
|
||||
//FAWE end
|
||||
|
||||
/**
|
||||
@ -270,5 +273,69 @@ public class ParserContext {
|
||||
public InjectedValueAccess getInjected() {
|
||||
return injected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to resolve the minimum Y value associated with this context or returns 0.
|
||||
* Caches both min and max y values.
|
||||
*
|
||||
* @return Minimum y value (inclusive) or 0
|
||||
*/
|
||||
public int getMinY() {
|
||||
if (minY != Integer.MIN_VALUE) {
|
||||
return minY;
|
||||
}
|
||||
|
||||
Extent extent = null;
|
||||
|
||||
if (actor instanceof Locatable) {
|
||||
extent = ((Locatable) actor).getExtent();
|
||||
} else if (world != null) {
|
||||
extent = world;
|
||||
} else if (this.extent != null) {
|
||||
extent = this.extent;
|
||||
}
|
||||
|
||||
if (extent != null) {
|
||||
minY = extent.getMinY();
|
||||
maxY = extent.getMaxY();
|
||||
} else {
|
||||
minY = 0;
|
||||
maxY = 255;
|
||||
}
|
||||
|
||||
return minY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to resolve the maximum Y value associated with this context or returns 255.
|
||||
* Caches both min and max y values.
|
||||
*
|
||||
* @return Maximum y value (inclusive) or 255
|
||||
*/
|
||||
public int getMaxY() {
|
||||
if (maxY != Integer.MAX_VALUE) {
|
||||
return maxY;
|
||||
}
|
||||
|
||||
Extent extent = null;
|
||||
|
||||
if (actor instanceof Locatable) {
|
||||
extent = ((Locatable) actor).getExtent();
|
||||
} else if (world != null) {
|
||||
extent = world;
|
||||
} else if (this.extent != null) {
|
||||
extent = this.extent;
|
||||
}
|
||||
|
||||
if (extent != null) {
|
||||
minY = extent.getMinY();
|
||||
maxY = extent.getMaxY();
|
||||
} else {
|
||||
minY = 0;
|
||||
maxY = 255;
|
||||
}
|
||||
|
||||
return maxY;
|
||||
}
|
||||
//FAWE end
|
||||
}
|
||||
|
@ -202,6 +202,11 @@ public class AbstractDelegateExtent implements Extent {
|
||||
return extent.getMaxY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return extent.getMinY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean relight(int x, int y, int z) {
|
||||
return extent.relight(x, y, z);
|
||||
@ -317,7 +322,7 @@ public class AbstractDelegateExtent implements Extent {
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(
|
||||
int x, @Range(from = 0, to = 255) int y,
|
||||
int x, int y,
|
||||
int z, T block
|
||||
) throws WorldEditException {
|
||||
return extent.setBlock(x, y, z, block);
|
||||
|
@ -200,9 +200,16 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
- TODO: actually optimize these
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the highest solid 'terrain' block.
|
||||
*
|
||||
* @param x the X coordinate
|
||||
* @param z the Z coordinate
|
||||
* @param minY minimal height
|
||||
* @param maxY maximal height
|
||||
* @return height of highest block found or 'minY'
|
||||
*/
|
||||
default int getHighestTerrainBlock(final int x, final int z, int minY, int maxY) {
|
||||
maxY = Math.min(maxY, Math.max(0, maxY));
|
||||
minY = Math.max(0, minY);
|
||||
for (int y = maxY; y >= minY; --y) {
|
||||
BlockState block = getBlock(x, y, z);
|
||||
if (block.getBlockType().getMaterial().isMovementBlocker()) {
|
||||
@ -212,9 +219,19 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
return minY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the highest solid 'terrain' block.
|
||||
*
|
||||
* @param x the X coordinate
|
||||
* @param z the Z coordinate
|
||||
* @param minY minimal height
|
||||
* @param maxY maximal height
|
||||
* @param filter a mask of blocks to consider, or null to consider any solid (movement-blocking) block
|
||||
* @return height of highest block found or 'minY'
|
||||
*/
|
||||
default int getHighestTerrainBlock(final int x, final int z, int minY, int maxY, Mask filter) {
|
||||
maxY = Math.min(maxY, Math.max(0, maxY));
|
||||
minY = Math.max(0, minY);
|
||||
maxY = Math.min(maxY, getMaxY());
|
||||
minY = Math.max(getMinY(), minY);
|
||||
|
||||
MutableBlockVector3 mutable = new MutableBlockVector3();
|
||||
|
||||
@ -226,6 +243,18 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
return minY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nearest surface layer (up/down from start)
|
||||
* <p>
|
||||
* TODO: Someone understand this..?
|
||||
*
|
||||
* @param x x to search from
|
||||
* @param z y to search from
|
||||
* @param y z to search from
|
||||
* @param minY min y to search (inclusive)
|
||||
* @param maxY max y to search (inclusive)
|
||||
* @return nearest surface layer
|
||||
*/
|
||||
default int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) {
|
||||
int clearanceAbove = maxY - y;
|
||||
int clearanceBelow = y - minY;
|
||||
@ -255,7 +284,7 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
for (int layer = y - clearance - 1; layer >= minY; layer--) {
|
||||
block = getBlock(x, layer, z);
|
||||
if (block.getBlockType().getMaterial().isMovementBlocker() == state) {
|
||||
return ((layer + offset) << 4) + 0;
|
||||
return (layer + offset) << 4;
|
||||
}
|
||||
data1 = PropertyGroup.LEVEL.get(block);
|
||||
}
|
||||
@ -272,18 +301,20 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
return (state ? minY : maxY) << 4;
|
||||
}
|
||||
|
||||
default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
|
||||
return getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, minY, maxY, ignoreAir);
|
||||
}
|
||||
|
||||
default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
return getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, minY, maxY);
|
||||
}
|
||||
|
||||
default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
|
||||
return getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets y value for the nearest block that is considered the surface of the terrain (cave roof/floor, mountain surface,
|
||||
* etc) where the block conforms to a given mask. Searches in the x,z column given.
|
||||
*
|
||||
* @param x column x
|
||||
* @param z column z
|
||||
* @param y start y
|
||||
* @param minY minimum y height to consider. Inclusive.
|
||||
* @param maxY maximum y height to consider. Inclusive.
|
||||
* @param failedMin if nothing found, the minimum y value to return if returning min
|
||||
* @param failedMax if nothing found, the maximum y value to return if returning max
|
||||
* @param mask mask to test blocks against
|
||||
* @return The y value of the nearest terrain block
|
||||
*/
|
||||
default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) {
|
||||
y = Math.max(minY, Math.min(maxY, y));
|
||||
int clearanceAbove = maxY - y;
|
||||
@ -320,6 +351,68 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
return state ? failedMin : failedMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets y value for the nearest block that is considered the surface of the terrain (cave roof/floor, mountain surface,
|
||||
* etc). Searches in the x,z column given.
|
||||
*
|
||||
* @param x column x
|
||||
* @param z column z
|
||||
* @param y start y
|
||||
* @param minY minimum y height to consider. Inclusive.
|
||||
* @param maxY maximum y height to consider. Inclusive.
|
||||
* @param ignoreAir if air at the final value if no block found should be considered for return, else return -1
|
||||
* @return The y value of the nearest terrain block
|
||||
*/
|
||||
default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) {
|
||||
return getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, minY, maxY, ignoreAir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets y value for the nearest block that is considered the surface of the terrain (cave roof/floor, mountain surface,
|
||||
* etc). Searches in the x,z column given.
|
||||
*
|
||||
* @param x column x
|
||||
* @param z column z
|
||||
* @param y start y
|
||||
* @param minY minimum y height to consider. Inclusive.
|
||||
* @param maxY maximum y height to consider. Inclusive.
|
||||
* @return The y value of the nearest terrain block
|
||||
*/
|
||||
default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) {
|
||||
return getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, minY, maxY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets y value for the nearest block that is considered the surface of the terrain (cave roof/floor, mountain surface,
|
||||
* etc). Searches in the x,z column given.
|
||||
*
|
||||
* @param x column x
|
||||
* @param z column z
|
||||
* @param y start y
|
||||
* @param minY minimum y height to consider. Inclusive.
|
||||
* @param maxY maximum y height to consider. Inclusive.
|
||||
* @param failedMin if nothing found, the minimum y value to return if returning min
|
||||
* @param failedMax if nothing found, the maximum y value to return if returning max
|
||||
* @return The y value of the nearest terrain block
|
||||
*/
|
||||
default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) {
|
||||
return getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets y value for the nearest block that is considered the surface of the terrain (cave roof/floor, mountain surface,
|
||||
* etc). Searches in the x,z column given.
|
||||
*
|
||||
* @param x column x
|
||||
* @param z column z
|
||||
* @param y start y
|
||||
* @param minY minimum y height to consider. Inclusive.
|
||||
* @param maxY maximum y height to consider. Inclusive.
|
||||
* @param failedMin if nothing found, the minimum y value to return if returning min
|
||||
* @param failedMax if nothing found, the maximum y value to return if returning max
|
||||
* @param ignoreAir if air at the final value if no block found should be considered for return, else return -1
|
||||
* @return The y value of the nearest terrain block
|
||||
*/
|
||||
default int getNearestSurfaceTerrainBlock(
|
||||
int x,
|
||||
int z,
|
||||
@ -367,7 +460,7 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
}
|
||||
}
|
||||
int result = state ? failedMin : failedMax;
|
||||
if (result > 0 && !ignoreAir) {
|
||||
if (result > minY && !ignoreAir) {
|
||||
block = getBlock(x, result, z);
|
||||
return block.getBlockType().getMaterial().isAir() ? -1 : result;
|
||||
}
|
||||
@ -444,12 +537,13 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
spawnResource(region, new OreGen(this, mask, material, size, minY, maxY), rarity, frequency);
|
||||
}
|
||||
|
||||
//TODO: probably update these for 1.18 etc.
|
||||
default void addOres(Region region, Mask mask) throws WorldEditException {
|
||||
addOre(region, mask, BlockTypes.DIRT.getDefaultState(), 33, 10, 100, 0, 255);
|
||||
addOre(region, mask, BlockTypes.GRAVEL.getDefaultState(), 33, 8, 100, 0, 255);
|
||||
addOre(region, mask, BlockTypes.ANDESITE.getDefaultState(), 33, 10, 100, 0, 79);
|
||||
addOre(region, mask, BlockTypes.DIORITE.getDefaultState(), 33, 10, 100, 0, 79);
|
||||
addOre(region, mask, BlockTypes.GRANITE.getDefaultState(), 33, 10, 100, 0, 79);
|
||||
addOre(region, mask, BlockTypes.DIRT.getDefaultState(), 33, 10, 100, getMinY(), getMaxY());
|
||||
addOre(region, mask, BlockTypes.GRAVEL.getDefaultState(), 33, 8, 100, getMinY(), getMaxY());
|
||||
addOre(region, mask, BlockTypes.ANDESITE.getDefaultState(), 33, 10, 100, getMinY(), 79);
|
||||
addOre(region, mask, BlockTypes.DIORITE.getDefaultState(), 33, 10, 100, getMinY(), 79);
|
||||
addOre(region, mask, BlockTypes.GRANITE.getDefaultState(), 33, 10, 100, getMinY(), 79);
|
||||
addOre(region, mask, BlockTypes.COAL_ORE.getDefaultState(), 17, 20, 100, 0, 127);
|
||||
addOre(region, mask, BlockTypes.IRON_ORE.getDefaultState(), 9, 20, 100, 0, 63);
|
||||
addOre(region, mask, BlockTypes.GOLD_ORE.getDefaultState(), 9, 2, 100, 0, 31);
|
||||
@ -556,11 +650,11 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
}
|
||||
|
||||
default int getMinY() {
|
||||
return 0;
|
||||
return getMinimumPoint().getY();
|
||||
}
|
||||
|
||||
default int getMaxY() {
|
||||
return 255;
|
||||
return getMaximumPoint().getY();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -347,7 +347,7 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable {
|
||||
if (!pasteAir && block.getBlockType().getMaterial().isAir()) {
|
||||
continue;
|
||||
}
|
||||
if (pos.getY() < 0) {
|
||||
if (pos.getY() < extent.getMinY()) {
|
||||
throw new RuntimeException("Y-Position cannot be less than 0!");
|
||||
}
|
||||
extent.setBlock(xx, yy, zz, block);
|
||||
|
@ -31,6 +31,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
public class OffsetMask extends AbstractMask {
|
||||
|
||||
//FAWE start - ignore resultant position outside world height range
|
||||
private final int minY;
|
||||
private final int maxY;
|
||||
//FAWE end
|
||||
private Mask mask;
|
||||
private BlockVector3 offset;
|
||||
|
||||
@ -39,12 +43,30 @@ public class OffsetMask extends AbstractMask {
|
||||
*
|
||||
* @param mask the mask
|
||||
* @param offset the offset
|
||||
* @deprecated use {@link OffsetMask#OffsetMask(Mask, BlockVector3, int, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public OffsetMask(Mask mask, BlockVector3 offset) {
|
||||
this(mask, offset, 0, 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param mask the mask
|
||||
* @param offset the offset
|
||||
* @param minY minimum allowable y value to be set. Inclusive.
|
||||
* @param maxY maximum allowable y value to be set. Inclusive.
|
||||
*/
|
||||
//FAWE start - ignore resultant position outside world height range
|
||||
public OffsetMask(Mask mask, BlockVector3 offset, int minY, int maxY) {
|
||||
checkNotNull(mask);
|
||||
checkNotNull(offset);
|
||||
this.mask = mask;
|
||||
this.offset = offset;
|
||||
this.minY = minY;
|
||||
this.maxY = maxY;
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,11 +109,13 @@ public class OffsetMask extends AbstractMask {
|
||||
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
//FAWE start - ignore resultant position outside world height range
|
||||
BlockVector3 testPos = vector.add(offset);
|
||||
if (testPos.getBlockY() < 0 || testPos.getBlockY() > 255) {
|
||||
if (testPos.getBlockY() < minY || testPos.getBlockY() > maxY) {
|
||||
return false;
|
||||
}
|
||||
return getMask().test(vector.add(offset));
|
||||
return getMask().test(testPos);
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -108,7 +132,7 @@ public class OffsetMask extends AbstractMask {
|
||||
//FAWE start
|
||||
@Override
|
||||
public Mask copy() {
|
||||
return new OffsetMask(mask.copy(), offset.toImmutable());
|
||||
return new OffsetMask(mask.copy(), offset.toImmutable(), minY, maxY);
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
|
@ -95,6 +95,8 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
private BlockVectorSet visited = new BlockVectorSet();
|
||||
private BlockVector3[] directions;
|
||||
//FAWE end
|
||||
protected final int minY;
|
||||
protected final int maxY;
|
||||
private int affected = 0;
|
||||
//FAWE start
|
||||
private int currentDepth = 0;
|
||||
@ -107,21 +109,21 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
* @param function the function to apply to visited blocks
|
||||
*/
|
||||
public BreadthFirstSearch(RegionFunction function) {
|
||||
//FAWE start
|
||||
this(function, Integer.MAX_VALUE);
|
||||
//FAWE end
|
||||
checkNotNull(function);
|
||||
//FAWE start - int depth, min/max y
|
||||
this(function, Integer.MAX_VALUE, 0, 255, null);
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
//FAWE start - int depth, min/max y, preloading
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param function the function to apply to visited blocks
|
||||
* @param maxDepth the maximum number of iterations
|
||||
* @param depth maximum number of iterations
|
||||
* @param minY minimum allowable y to visit. Inclusive.
|
||||
* @param maxY maximum allowable y to visit. Inclusive.
|
||||
*/
|
||||
public BreadthFirstSearch(RegionFunction function, int maxDepth) {
|
||||
this(function, maxDepth, null);
|
||||
public BreadthFirstSearch(RegionFunction function, int depth, int minY, int maxY) {
|
||||
this(function, depth, minY, maxY, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,13 +131,17 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
*
|
||||
* @param function the function to apply to visited blocks
|
||||
* @param maxDepth the maximum number of iterations
|
||||
* @param minY minimum y value to visit. Inclusive.
|
||||
* @param maxY maximum y value to visit. Inclusive.
|
||||
* @param extent extent to use for preloading
|
||||
*/
|
||||
public BreadthFirstSearch(RegionFunction function, int maxDepth, Extent extent) {
|
||||
public BreadthFirstSearch(RegionFunction function, int maxDepth, int minY, int maxY, Extent extent) {
|
||||
checkNotNull(function);
|
||||
this.function = function;
|
||||
this.directions = DEFAULT_DIRECTIONS;
|
||||
this.maxDepth = maxDepth;
|
||||
this.minY = minY;
|
||||
this.maxY = maxY;
|
||||
if (extent != null) {
|
||||
ExtentTraverser<ParallelQueueExtent> queueTraverser = new ExtentTraverser<>(extent).find(ParallelQueueExtent.class);
|
||||
this.singleQueue = queueTraverser != null ? (SingleThreadQueueExtent) queueTraverser.get().getExtent() : null;
|
||||
@ -314,7 +320,7 @@ public abstract class BreadthFirstSearch implements Operation {
|
||||
for (int i = 0, j = 0; i < dirs.length && j < maxBranch; i++) {
|
||||
BlockVector3 direction = dirs[i];
|
||||
int y = from.getBlockY() + direction.getY();
|
||||
if (y < 0 || y >= 256) {
|
||||
if (y < minY || y > maxY) {
|
||||
continue;
|
||||
}
|
||||
int x = from.getBlockX() + direction.getX();
|
||||
|
@ -37,19 +37,22 @@ public class DownwardVisitor extends RecursiveVisitor {
|
||||
|
||||
private final int baseY;
|
||||
|
||||
//FAWE start
|
||||
|
||||
/**
|
||||
* Create a new visitor.
|
||||
*
|
||||
* @param mask the mask
|
||||
* @param function the function
|
||||
* @param baseY the base Y
|
||||
* @deprecated Use {@link DownwardVisitor#DownwardVisitor(Mask, RegionFunction, int, int, int, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public DownwardVisitor(Mask mask, RegionFunction function, int baseY) {
|
||||
this(mask, function, baseY, Integer.MAX_VALUE);
|
||||
//FAWE start - int depth, min/max y
|
||||
this(mask, function, baseY, Integer.MAX_VALUE, 0, 255, null);
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
//FAWE start - int depth, min/max y, preloading
|
||||
/**
|
||||
* Create a new visitor.
|
||||
*
|
||||
@ -57,9 +60,11 @@ public class DownwardVisitor extends RecursiveVisitor {
|
||||
* @param function the function
|
||||
* @param baseY the base Y
|
||||
* @param depth maximum number of iterations
|
||||
* @param minY minimum allowable y to visit. Inclusive.
|
||||
* @param maxY maximum allowable y to visit. Inclusive.
|
||||
*/
|
||||
public DownwardVisitor(Mask mask, RegionFunction function, int baseY, int depth) {
|
||||
this (mask, function, baseY, depth, null);
|
||||
public DownwardVisitor(Mask mask, RegionFunction function, int baseY, int depth, int minY, int maxY) {
|
||||
this(mask, function, baseY, depth, minY, maxY, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,10 +74,12 @@ public class DownwardVisitor extends RecursiveVisitor {
|
||||
* @param function the function
|
||||
* @param baseY the base Y
|
||||
* @param depth maximum number of iterations
|
||||
* @param minY minimum allowable y to visit. Inclusive.
|
||||
* @param maxY maximum allowable y to visit. Inclusive.
|
||||
* @param extent extent for preloading
|
||||
*/
|
||||
public DownwardVisitor(Mask mask, RegionFunction function, int baseY, int depth, Extent extent) {
|
||||
super(mask, function, depth, extent);
|
||||
public DownwardVisitor(Mask mask, RegionFunction function, int baseY, int depth, int minY, int maxY, Extent extent) {
|
||||
super(mask, function, depth, minY, maxY, extent);
|
||||
checkNotNull(mask);
|
||||
|
||||
this.baseY = baseY;
|
||||
|
@ -29,29 +29,32 @@ import com.sk89q.worldedit.math.BlockVector3;
|
||||
*/
|
||||
public class NonRisingVisitor extends RecursiveVisitor {
|
||||
|
||||
//FAWE start - max int
|
||||
|
||||
/**
|
||||
* Create a new recursive visitor.
|
||||
* Create a new resursive visitor.
|
||||
*
|
||||
* @param mask the mask
|
||||
* @param function the function
|
||||
* @deprecated Use {@link NonRisingVisitor#NonRisingVisitor(Mask, RegionFunction, int, int, int, Extent)}
|
||||
*/
|
||||
@Deprecated
|
||||
public NonRisingVisitor(Mask mask, RegionFunction function) {
|
||||
this(mask, function, Integer.MAX_VALUE);
|
||||
//FAWE start - int depth, y min/max
|
||||
this(mask, function, Integer.MAX_VALUE, 0, 255, null);
|
||||
//FAWE end
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
//FAWE start - int depth, preloading
|
||||
//FAWE start - int depth, preloading, min/max y
|
||||
/**
|
||||
* Create a new recursive visitor.
|
||||
*
|
||||
* @param mask the mask
|
||||
* @param function the function
|
||||
* @param depth the maximum number of iterations
|
||||
* @param minY minimum allowable y to visit. Inclusive.
|
||||
* @param maxY maximum allowable y to visit. Inclusive.
|
||||
*/
|
||||
public NonRisingVisitor(Mask mask, RegionFunction function, int depth) {
|
||||
this(mask, function, depth, null);
|
||||
public NonRisingVisitor(Mask mask, RegionFunction function, int depth, int minY, int maxY) {
|
||||
this(mask, function, Integer.MAX_VALUE, minY, maxY, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,10 +63,12 @@ public class NonRisingVisitor extends RecursiveVisitor {
|
||||
* @param mask the mask
|
||||
* @param function the function
|
||||
* @param depth the maximum number of iterations
|
||||
* @param minY minimum allowable y to visit. Inclusive.
|
||||
* @param maxY maximum allowable y to visit. Inclusive.
|
||||
* @param extent the extent for preloading
|
||||
*/
|
||||
public NonRisingVisitor(Mask mask, RegionFunction function, int depth, Extent extent) {
|
||||
super(mask, function, depth, extent);
|
||||
public NonRisingVisitor(Mask mask, RegionFunction function, int depth, int minY, int maxY, Extent extent) {
|
||||
super(mask, function, depth, minY, maxY, extent);
|
||||
setDirections(
|
||||
BlockVector3.UNIT_X,
|
||||
BlockVector3.UNIT_MINUS_X,
|
||||
|
@ -34,7 +34,6 @@ public class RecursiveVisitor extends BreadthFirstSearch {
|
||||
|
||||
private final Mask mask;
|
||||
|
||||
//FAWE start
|
||||
/**
|
||||
* Create a new recursive visitor.
|
||||
*
|
||||
@ -42,30 +41,37 @@ public class RecursiveVisitor extends BreadthFirstSearch {
|
||||
* @param function the function
|
||||
*/
|
||||
public RecursiveVisitor(Mask mask, RegionFunction function) {
|
||||
this(mask, function, Integer.MAX_VALUE);
|
||||
this(mask, function, Integer.MAX_VALUE, 0, 255, null);
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
//FAWE start - int depth, min/max y
|
||||
/**
|
||||
* Create a new recursive visitor.
|
||||
*
|
||||
* @param mask the mask
|
||||
* @param function the function
|
||||
* @param maxDepth the maximum number of iterations
|
||||
* @param minY minimum allowable y to visit. Inclusive.
|
||||
* @param maxY maximum allowable y to visit. Inclusive.
|
||||
*/
|
||||
public RecursiveVisitor(Mask mask, RegionFunction function, int maxDepth) {
|
||||
this(mask, function, maxDepth, null);
|
||||
public RecursiveVisitor(Mask mask, RegionFunction function, int maxDepth, int minY, int maxY) {
|
||||
this(mask, function, maxDepth, minY, maxY, null);
|
||||
}
|
||||
|
||||
//FAWE start - int depth, min/max y
|
||||
/**
|
||||
* Create a new recursive visitor.
|
||||
*
|
||||
* @param mask the mask
|
||||
* @param function the function
|
||||
* @param maxDepth the maximum number of iterations
|
||||
* @param minY minimum allowable y to visit. Inclusive.
|
||||
* @param maxY maximum allowable y to visit. Inclusive.
|
||||
* @param extent the extent for preloading
|
||||
*/
|
||||
public RecursiveVisitor(Mask mask, RegionFunction function, int maxDepth, Extent extent) {
|
||||
super(function, maxDepth, extent);
|
||||
public RecursiveVisitor(Mask mask, RegionFunction function, int maxDepth, int minY, int maxY, Extent extent) {
|
||||
super(function, maxDepth, minY, maxY, extent);
|
||||
checkNotNull(mask);
|
||||
this.mask = mask;
|
||||
}
|
||||
|
@ -19,53 +19,54 @@
|
||||
|
||||
package com.sk89q.worldedit.internal.util;
|
||||
|
||||
import net.royawesome.jlibnoise.MathHelper;
|
||||
|
||||
public class BiomeMath {
|
||||
|
||||
// From BiomeArray / BiomeContainer
|
||||
public static final int HORIZONTAL_SECTION_COUNT = (int) Math.round(Math.log(16.0D) / Math.log(2.0D)) - 2;
|
||||
public static final int VERTICAL_SECTION_COUNT = (int) Math.round(Math.log(256.0D) / Math.log(2.0D)) - 2;
|
||||
public static final int HORIZONTAL_BIT_MASK = (1 << HORIZONTAL_SECTION_COUNT) - 1;
|
||||
public static final int VERTICAL_BIT_MASK = (1 << VERTICAL_SECTION_COUNT) - 1;
|
||||
//FAWE - Removed because it's unneeded, and it would require effort to have it work with worlds of differing heights across
|
||||
// different game versions
|
||||
|
||||
private BiomeMath() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the index into the MC biome array, for non-extended-height worlds.
|
||||
*
|
||||
* @param x the block x coordinate
|
||||
* @param y the block y coordinate
|
||||
* @param z the block z coordinate
|
||||
* @return the index into the standard MC biome array
|
||||
*/
|
||||
public static int computeBiomeIndex(int x, int y, int z) {
|
||||
int l = (x >> 2) & HORIZONTAL_BIT_MASK;
|
||||
int m = MathHelper.clamp(y >> 2, 0, VERTICAL_BIT_MASK);
|
||||
int n = (z >> 2) & HORIZONTAL_BIT_MASK;
|
||||
return m << HORIZONTAL_SECTION_COUNT + HORIZONTAL_SECTION_COUNT
|
||||
| n << HORIZONTAL_SECTION_COUNT
|
||||
| l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the index into the MC biome array, for extended-height worlds.
|
||||
*
|
||||
* @param x the block x coordinate
|
||||
* @param y the block y coordinate
|
||||
* @param z the block z coordinate
|
||||
* @param minY minimum y of the world
|
||||
* @param maxY maximum y of the world
|
||||
* @return the index into the standard MC biome array
|
||||
*/
|
||||
public static int computeBiomeIndex(int x, int y, int z, int minY, int maxY) {
|
||||
int l = (x >> 2) & HORIZONTAL_BIT_MASK;
|
||||
int m = MathHelper.clamp((y >> 2) - minY, 0, maxY);
|
||||
int n = (z >> 2) & HORIZONTAL_BIT_MASK;
|
||||
return m << HORIZONTAL_SECTION_COUNT + HORIZONTAL_SECTION_COUNT
|
||||
| n << HORIZONTAL_SECTION_COUNT
|
||||
| l;
|
||||
}
|
||||
// // From BiomeArray / BiomeContainer
|
||||
// public static final int HORIZONTAL_SECTION_COUNT = (int) Math.round(Math.log(16.0D) / Math.log(2.0D)) - 2;
|
||||
// public static final int VERTICAL_SECTION_COUNT = (int) Math.round(Math.log(256.0D) / Math.log(2.0D)) - 2;
|
||||
// public static final int HORIZONTAL_BIT_MASK = (1 << HORIZONTAL_SECTION_COUNT) - 1;
|
||||
// public static final int VERTICAL_BIT_MASK = (1 << VERTICAL_SECTION_COUNT) - 1;
|
||||
//
|
||||
// private BiomeMath() {
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Compute the index into the MC biome array, for non-extended-height worlds.
|
||||
// *
|
||||
// * @param x the block x coordinate
|
||||
// * @param y the block y coordinate
|
||||
// * @param z the block z coordinate
|
||||
// * @return the index into the standard MC biome array
|
||||
// */
|
||||
// public static int computeBiomeIndex(int x, int y, int z) {
|
||||
// int l = (x >> 2) & HORIZONTAL_BIT_MASK;
|
||||
// int m = MathHelper.clamp(y >> 2, 0, VERTICAL_BIT_MASK);
|
||||
// int n = (z >> 2) & HORIZONTAL_BIT_MASK;
|
||||
// return m << HORIZONTAL_SECTION_COUNT + HORIZONTAL_SECTION_COUNT
|
||||
// | n << HORIZONTAL_SECTION_COUNT
|
||||
// | l;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Compute the index into the MC biome array, for extended-height worlds.
|
||||
// *
|
||||
// * @param x the block x coordinate
|
||||
// * @param y the block y coordinate
|
||||
// * @param z the block z coordinate
|
||||
// * @param minY minimum y of the world
|
||||
// * @param maxY maximum y of the world
|
||||
// * @return the index into the standard MC biome array
|
||||
// */
|
||||
// public static int computeBiomeIndex(int x, int y, int z, int minY, int maxY) {
|
||||
// int l = (x >> 2) & HORIZONTAL_BIT_MASK;
|
||||
// int m = MathHelper.clamp((y >> 2) - minY, 0, maxY);
|
||||
// int n = (z >> 2) & HORIZONTAL_BIT_MASK;
|
||||
// return m << HORIZONTAL_SECTION_COUNT + HORIZONTAL_SECTION_COUNT
|
||||
// | n << HORIZONTAL_SECTION_COUNT
|
||||
// | l;
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -97,18 +97,18 @@ public class HeightMap {
|
||||
int bx = min.getBlockX();
|
||||
int bz = min.getBlockZ();
|
||||
Iterator<BlockVector2> flat = Regions.asFlatRegion(region).asFlatRegion().iterator();
|
||||
int layer = 0;
|
||||
int layer = session.getMinY();
|
||||
while (flat.hasNext()) {
|
||||
BlockVector2 pos = flat.next();
|
||||
int x = pos.getBlockX();
|
||||
int z = pos.getBlockZ();
|
||||
layer = session.getNearestSurfaceLayer(x, z, (layer + 7) >> 3, 0, maxY);
|
||||
layer = session.getNearestSurfaceLayer(x, z, (layer + 7) >> 3, session.getMinY(), maxY);
|
||||
data[(z - bz) * width + (x - bx)] = layer;
|
||||
}
|
||||
} else {
|
||||
// Store current heightmap data
|
||||
int index = 0;
|
||||
int yTmp = 255;
|
||||
int yTmp = session.getMaxY();
|
||||
for (int z = 0; z < height; ++z) {
|
||||
for (int x = 0; x < width; ++x, index++) {
|
||||
if (mask != null) {
|
||||
@ -324,7 +324,7 @@ public class HeightMap {
|
||||
int y0 = newHeight - 1;
|
||||
for (int setY = y0, getY = curHeight - 1; setY >= curHeight; setY--, getY--) {
|
||||
BlockState get;
|
||||
if (getY >= 0 && getY < 256) {
|
||||
if (getY >= session.getMinY() && getY <= session.getMaxY()) {
|
||||
get = session.getBlock(xr, getY, zr);
|
||||
} else {
|
||||
get = BlockTypes.AIR.getDefaultState();
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.regions;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
||||
import com.fastasyncworldedit.core.math.BlockVectorSet;
|
||||
@ -745,7 +744,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
|
||||
if (bx >= minX && tx <= maxX && bz >= minZ && tz <= maxZ) {
|
||||
// contains all X/Z
|
||||
if (minY <= 0 && maxY >= 255) {
|
||||
if (minY <= set.getMinSectionIndex() << 4 && maxY >= (set.getMaxSectionIndex() << 4) + 15) {
|
||||
return set;
|
||||
}
|
||||
trimY(set, minY, maxY);
|
||||
@ -766,7 +765,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
boolean trimX = lowerX != 0 || upperX != 15;
|
||||
boolean trimZ = lowerZ != 0 || upperZ != 15;
|
||||
|
||||
for (int layer = 0; layer < FaweCache.IMP.CHUNK_LAYERS; layer++) {
|
||||
for (int layer = get.getMinSectionIndex(); layer < get.getMaxSectionIndex(); layer++) {
|
||||
if (set.hasSection(layer)) {
|
||||
char[] arr = set.load(layer);
|
||||
if (trimX || trimZ) {
|
||||
|
@ -244,11 +244,11 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
||||
final IChunkSet set,
|
||||
boolean full
|
||||
) {
|
||||
int minSection = Math.max(0, getMinimumY() >> 4);
|
||||
int maxSection = Math.min(15, getMaximumY() >> 4);
|
||||
int minSection = Math.max(get.getMinSectionIndex(), getMinimumY() >> 4);
|
||||
int maxSection = Math.min(get.getMaxSectionIndex(), getMaximumY() >> 4);
|
||||
block = block.initChunk(chunk.getX(), chunk.getZ());
|
||||
for (int layer = minSection; layer <= maxSection; layer++) {
|
||||
if ((!full && !get.hasSection(layer)) || !filter.appliesLayer(chunk, layer)) {
|
||||
if ((!full && !set.hasSection(layer)) || !filter.appliesLayer(chunk, layer)) {
|
||||
return;
|
||||
}
|
||||
block = block.initLayer(get, set, layer);
|
||||
|
@ -178,7 +178,7 @@ public class TargetBlock {
|
||||
} else {
|
||||
if (searchForLastBlock) {
|
||||
lastBlock = getCurrentBlock();
|
||||
if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= world.getMaxY()) {
|
||||
if (lastBlock.getBlockY() <= world.getMinY() || lastBlock.getBlockY() >= world.getMaxY()) {
|
||||
searchForLastBlock = false;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user