Skip to content

Commit b27f671

Browse files
authored
Only compute solid blocks once (#3068)
* Only compute solid blocks once * Replace more isMovementBlocker calls
1 parent aecc50d commit b27f671

File tree

3 files changed

+50
-15
lines changed

3 files changed

+50
-15
lines changed

worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightMapType.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.fastasyncworldedit.core.extent.processor.heightmap;
22

33
import com.fastasyncworldedit.core.registry.state.PropertyKey;
4+
import com.sk89q.worldedit.function.mask.SolidBlockMask;
45
import com.sk89q.worldedit.registry.state.Property;
56
import com.sk89q.worldedit.world.block.BlockCategories;
67
import com.sk89q.worldedit.world.block.BlockState;
@@ -17,19 +18,19 @@ public enum HeightMapType {
1718
MOTION_BLOCKING {
1819
@Override
1920
public boolean includes(BlockState state) {
20-
return state.getMaterial().isMovementBlocker() || HeightMapType.hasFluid(state);
21+
return isMovementBlocker(state) || HeightMapType.hasFluid(state);
2122
}
2223
},
2324
MOTION_BLOCKING_NO_LEAVES {
2425
@Override
2526
public boolean includes(BlockState state) {
26-
return (state.getMaterial().isMovementBlocker() || HeightMapType.hasFluid(state)) && !HeightMapType.isLeaf(state);
27+
return (isMovementBlocker(state) || HeightMapType.hasFluid(state)) && !HeightMapType.isLeaf(state);
2728
}
2829
},
2930
OCEAN_FLOOR {
3031
@Override
3132
public boolean includes(BlockState state) {
32-
return state.getMaterial().isMovementBlocker();
33+
return HeightMapType.isMovementBlocker(state);
3334
}
3435
},
3536
WORLD_SURFACE {
@@ -39,6 +40,10 @@ public boolean includes(BlockState state) {
3940
}
4041
};
4142

43+
private static boolean isMovementBlocker(BlockState state) {
44+
return SolidBlockMask.isSolid(state);
45+
}
46+
4247
static {
4348
BlockCategories.LEAVES.getAll(); // make sure this category is initialized, otherwise isLeaf might fail
4449
}

worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.sk89q.worldedit.function.mask.BlockMask;
4848
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
4949
import com.sk89q.worldedit.function.mask.Mask;
50+
import com.sk89q.worldedit.function.mask.SolidBlockMask;
5051
import com.sk89q.worldedit.function.operation.Operation;
5152
import com.sk89q.worldedit.function.operation.Operations;
5253
import com.sk89q.worldedit.function.pattern.BlockPattern;
@@ -456,32 +457,32 @@ default int getNearestSurfaceTerrainBlock(
456457
int clearanceBelow = y - minY;
457458
int clearance = Math.min(clearanceAbove, clearanceBelow);
458459
BlockState block = getBlock(x, y, z);
459-
boolean state = !block.getBlockType().getMaterial().isMovementBlocker();
460+
boolean state = !SolidBlockMask.isSolid(block);
460461
int offset = state ? 0 : 1;
461462
for (int d = 0; d <= clearance; d++) {
462463
int y1 = y + d;
463464
block = getBlock(x, y1, z);
464-
if (block.getMaterial().isMovementBlocker() == state && block.getBlockType() != BlockTypes.__RESERVED__) {
465+
if (matchesSolidState(block, state)) {
465466
return y1 - offset;
466467
}
467468
int y2 = y - d;
468469
block = getBlock(x, y2, z);
469-
if (block.getMaterial().isMovementBlocker() == state && block.getBlockType() != BlockTypes.__RESERVED__) {
470+
if (matchesSolidState(block, state)) {
470471
return y2 + offset;
471472
}
472473
}
473474
if (clearanceAbove != clearanceBelow) {
474475
if (clearanceAbove < clearanceBelow) {
475476
for (int layer = y - clearance - 1; layer >= minY; layer--) {
476477
block = getBlock(x, layer, z);
477-
if (block.getMaterial().isMovementBlocker() == state && block.getBlockType() != BlockTypes.__RESERVED__) {
478+
if (matchesSolidState(block, state)) {
478479
return layer + offset;
479480
}
480481
}
481482
} else {
482483
for (int layer = y + clearance + 1; layer <= maxY; layer++) {
483484
block = getBlock(x, layer, z);
484-
if (block.getMaterial().isMovementBlocker() == state && block.getBlockType() != BlockTypes.__RESERVED__) {
485+
if (matchesSolidState(block, state)) {
485486
return layer - offset;
486487
}
487488
}
@@ -495,6 +496,10 @@ default int getNearestSurfaceTerrainBlock(
495496
return result;
496497
}
497498

499+
private static boolean matchesSolidState(BlockState block, boolean state) {
500+
return SolidBlockMask.isSolid(block) == state && block.getBlockType() != BlockTypes.__RESERVED__;
501+
}
502+
498503
default void addCaves(Region region) throws WorldEditException {
499504
generate(region, new CavesGen(8));
500505
}

worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,48 @@
2020
package com.sk89q.worldedit.function.mask;
2121

2222
import com.sk89q.worldedit.extent.Extent;
23+
import com.sk89q.worldedit.math.BlockVector3;
24+
import com.sk89q.worldedit.world.block.BlockState;
25+
import com.sk89q.worldedit.world.block.BlockTypesCache;
2326

24-
import javax.annotation.Nullable;
27+
public class SolidBlockMask extends AbstractExtentMask {
28+
// FAWE start - precompute solid blocks
29+
private static final boolean[] SOLID = initialize();
2530

26-
public class SolidBlockMask extends BlockMask {
31+
private static boolean[] initialize() {
32+
final boolean[] solid = new boolean[BlockTypesCache.states.length];
33+
for (int i = 0; i < solid.length; i++) {
34+
solid[i] = BlockTypesCache.states[i].getBlockType().getMaterial().isMovementBlocker();
35+
}
36+
return solid;
37+
}
38+
// FAWE end
2739

2840
public SolidBlockMask(Extent extent) {
2941
super(extent);
30-
add(state -> state.getMaterial().isMovementBlocker());
3142
}
3243

33-
@Nullable
44+
// FAWE start
45+
@Override
46+
public boolean test(final Extent extent, final BlockVector3 position) {
47+
final int ordinal = position.getOrdinal(extent);
48+
return SOLID[ordinal];
49+
}
50+
3451
@Override
35-
public Mask2D toMask2D() {
36-
return null;
52+
public boolean test(final BlockVector3 vector) {
53+
return test(getExtent(), vector);
3754
}
3855

39-
//FAWE start
56+
/**
57+
* {@return whether the given block state is considered solid by this mask}
58+
* @since TODO
59+
*/
60+
public static boolean isSolid(BlockState blockState) {
61+
return SOLID[blockState.getOrdinal()];
62+
}
63+
64+
4065
@Override
4166
public Mask copy() {
4267
return new SolidBlockMask(getExtent());

0 commit comments

Comments
 (0)