mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-04 03:56:41 +00:00
Add /tracemask. (#474)
Allows setting a mask used for block traces. This allows brush tools to pass through various materials, such as water (e.g. `/tracemask #solid` or `/tracemask !air,water`) before starting to build. By default, a null mask is equivalent to #existing (original behavior). https://gfycat.com/ImmaculateFrayedCockatiel
This commit is contained in:
@ -20,10 +20,15 @@
|
||||
package com.sk89q.worldedit.util;
|
||||
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.SolidBlockMask;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This class uses an inefficient method to figure out what block a player
|
||||
* is looking towards.
|
||||
@ -33,7 +38,8 @@ import com.sk89q.worldedit.world.World;
|
||||
*/
|
||||
public class TargetBlock {
|
||||
|
||||
private World world;
|
||||
private final World world;
|
||||
|
||||
private int maxDistance;
|
||||
private double checkDistance, curDistance;
|
||||
private BlockVector3 targetPos = BlockVector3.ZERO;
|
||||
@ -41,6 +47,11 @@ public class TargetBlock {
|
||||
private BlockVector3 prevPos = BlockVector3.ZERO;
|
||||
private Vector3 offset = Vector3.ZERO;
|
||||
|
||||
// the mask which dictates when to stop a trace - defaults to stopping at non-air blocks
|
||||
private Mask stopMask;
|
||||
// the mask which dictates when to stop a solid block trace - default to BlockMaterial#isMovementBlocker
|
||||
private Mask solidMask;
|
||||
|
||||
/**
|
||||
* Constructor requiring a player, uses default values
|
||||
*
|
||||
@ -50,6 +61,8 @@ public class TargetBlock {
|
||||
this.world = player.getWorld();
|
||||
this.setValues(player.getLocation().toVector(), player.getLocation().getYaw(), player.getLocation().getPitch(),
|
||||
300, 1.65, 0.2);
|
||||
this.stopMask = new ExistingBlockMask(world);
|
||||
this.solidMask = new SolidBlockMask(world);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,6 +75,36 @@ public class TargetBlock {
|
||||
public TargetBlock(Player player, int maxDistance, double checkDistance) {
|
||||
this.world = player.getWorld();
|
||||
this.setValues(player.getLocation().toVector(), player.getLocation().getYaw(), player.getLocation().getPitch(), maxDistance, 1.65, checkDistance);
|
||||
this.stopMask = new ExistingBlockMask(world);
|
||||
this.solidMask = new SolidBlockMask(world);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mask used for determine where to stop traces.
|
||||
* Setting to null will restore the default.
|
||||
*
|
||||
* @param stopMask the mask used to stop traces
|
||||
*/
|
||||
public void setStopMask(@Nullable Mask stopMask) {
|
||||
if (stopMask == null) {
|
||||
this.stopMask = new ExistingBlockMask(world);
|
||||
} else {
|
||||
this.stopMask = stopMask;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mask used for determine where to stop solid block traces.
|
||||
* Setting to null will restore the default.
|
||||
*
|
||||
* @param solidMask the mask used to stop solid block traces
|
||||
*/
|
||||
public void setSolidMask(@Nullable Mask solidMask) {
|
||||
if (solidMask == null) {
|
||||
this.solidMask = new SolidBlockMask(world);
|
||||
} else {
|
||||
this.solidMask = solidMask;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,7 +122,7 @@ public class TargetBlock {
|
||||
this.checkDistance = checkDistance;
|
||||
this.curDistance = 0;
|
||||
xRotation = (xRotation + 90) % 360;
|
||||
yRotation = yRotation * -1;
|
||||
yRotation *= -1;
|
||||
|
||||
double h = (checkDistance * Math.cos(Math.toRadians(yRotation)));
|
||||
|
||||
@ -102,15 +145,15 @@ public class TargetBlock {
|
||||
boolean searchForLastBlock = true;
|
||||
Location lastBlock = null;
|
||||
while (getNextBlock() != null) {
|
||||
if (world.getBlock(targetPos).getBlockType().getMaterial().isAir()) {
|
||||
if (stopMask.test(targetPos)) {
|
||||
break;
|
||||
} else {
|
||||
if (searchForLastBlock) {
|
||||
lastBlock = getCurrentBlock();
|
||||
if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= world.getMaxY()) {
|
||||
searchForLastBlock = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Location currentBlock = getCurrentBlock();
|
||||
@ -124,7 +167,8 @@ public class TargetBlock {
|
||||
* @return Block
|
||||
*/
|
||||
public Location getTargetBlock() {
|
||||
while (getNextBlock() != null && world.getBlock(targetPos).getBlockType().getMaterial().isAir()) ;
|
||||
//noinspection StatementWithEmptyBody
|
||||
while (getNextBlock() != null && !stopMask.test(targetPos)) ;
|
||||
return getCurrentBlock();
|
||||
}
|
||||
|
||||
@ -135,7 +179,8 @@ public class TargetBlock {
|
||||
* @return Block
|
||||
*/
|
||||
public Location getSolidTargetBlock() {
|
||||
while (getNextBlock() != null && !world.getBlock(targetPos).getBlockType().getMaterial().isMovementBlocker()) ;
|
||||
//noinspection StatementWithEmptyBody
|
||||
while (getNextBlock() != null && !solidMask.test(targetPos)) ;
|
||||
return getCurrentBlock();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user