geforkt von Mirrors/FastAsyncWorldEdit
Ported block tracing code to WorldEdit.
Dieser Commit ist enthalten in:
Ursprung
3e8b2edff9
Commit
6f6a82d326
@ -21,6 +21,7 @@ package com.sk89q.worldedit;
|
|||||||
|
|
||||||
import com.sk89q.worldedit.bags.BlockBag;
|
import com.sk89q.worldedit.bags.BlockBag;
|
||||||
import com.sk89q.worldedit.blocks.BlockType;
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
|
import com.sk89q.worldedit.util.TargetBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -298,7 +299,10 @@ public abstract class LocalPlayer {
|
|||||||
* @param range
|
* @param range
|
||||||
* @return point
|
* @return point
|
||||||
*/
|
*/
|
||||||
public abstract WorldVector getBlockTrace(int range);
|
public WorldVector getBlockTrace(int range) {
|
||||||
|
TargetBlock tb = new TargetBlock(this, range, 0.2);
|
||||||
|
return tb.getTargetBlock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the point of the block being looked at. May return null.
|
* Get the point of the block being looked at. May return null.
|
||||||
@ -306,7 +310,10 @@ public abstract class LocalPlayer {
|
|||||||
* @param range
|
* @param range
|
||||||
* @return point
|
* @return point
|
||||||
*/
|
*/
|
||||||
public abstract WorldVector getSolidBlockTrace(int range);
|
public WorldVector getSolidBlockTrace(int range) {
|
||||||
|
TargetBlock tb = new TargetBlock(this, range, 0.2);
|
||||||
|
return tb.getSolidTargetBlock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the player's cardinal direction (N, W, NW, etc.). May return null.
|
* Get the player's cardinal direction (N, W, NW, etc.). May return null.
|
||||||
@ -418,7 +425,31 @@ public abstract class LocalPlayer {
|
|||||||
* @param range
|
* @param range
|
||||||
* @return whether the player was pass through
|
* @return whether the player was pass through
|
||||||
*/
|
*/
|
||||||
public abstract boolean passThroughForwardWall(int range);
|
public boolean passThroughForwardWall(int range) {
|
||||||
|
boolean foundNext = false;
|
||||||
|
int searchDist = 0;
|
||||||
|
TargetBlock hitBlox = new TargetBlock(this, range, 0.2);
|
||||||
|
LocalWorld world = getPosition().getWorld();
|
||||||
|
BlockWorldVector block;
|
||||||
|
while ((block = hitBlox.getNextBlock()) != null) {
|
||||||
|
searchDist++;
|
||||||
|
if (searchDist > 20) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (BlockType.canPassThrough(world.getBlockType(block))) {
|
||||||
|
if (foundNext) {
|
||||||
|
Vector v = new Vector(block.getX(), block.getY() - 1, block.getZ());
|
||||||
|
if (BlockType.canPassThrough(world.getBlockType(v))) {
|
||||||
|
setPosition(v.add(0.5, 0, 0.5));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foundNext = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print a message.
|
* Print a message.
|
||||||
|
@ -532,6 +532,20 @@ public class Vector {
|
|||||||
(int)Math.floor(z));
|
(int)Math.floor(z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a block point from a point.
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param z
|
||||||
|
* @return point
|
||||||
|
*/
|
||||||
|
public BlockVector toBlockPoint() {
|
||||||
|
return new BlockVector((int)Math.floor(x),
|
||||||
|
(int)Math.floor(y),
|
||||||
|
(int)Math.floor(z));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if another object is equivalent.
|
* Checks if another object is equivalent.
|
||||||
*
|
*
|
||||||
|
@ -20,12 +20,10 @@
|
|||||||
package com.sk89q.worldedit.bukkit;
|
package com.sk89q.worldedit.bukkit;
|
||||||
|
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import com.sk89q.worldedit.*;
|
import com.sk89q.worldedit.*;
|
||||||
import com.sk89q.worldedit.bags.BlockBag;
|
import com.sk89q.worldedit.bags.BlockBag;
|
||||||
import com.sk89q.worldedit.blocks.BlockType;
|
|
||||||
|
|
||||||
public class BukkitPlayer extends LocalPlayer {
|
public class BukkitPlayer extends LocalPlayer {
|
||||||
private Player player;
|
private Player player;
|
||||||
@ -37,29 +35,6 @@ public class BukkitPlayer extends LocalPlayer {
|
|||||||
this.player = player;
|
this.player = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public WorldVector getBlockTrace(int range) {
|
|
||||||
TargetBlock tb = new TargetBlock(player, range, 0.2);
|
|
||||||
Block block = tb.getTargetBlock();
|
|
||||||
if (block == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new WorldVector(getWorld(), block.getX(), block.getY(), block.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WorldVector getSolidBlockTrace(int range) {
|
|
||||||
TargetBlock tb = new TargetBlock(player, range, 0.2);
|
|
||||||
tb.reset();
|
|
||||||
while (tb.getNextBlock() != null
|
|
||||||
&& BlockType.canPassThrough(tb.getCurrentBlock().getTypeId()));
|
|
||||||
Block block = tb.getCurrentBlock();
|
|
||||||
if (block == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new WorldVector(getWorld(), block.getX(), block.getY(), block.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemInHand() {
|
public int getItemInHand() {
|
||||||
ItemStack itemStack = player.getItemInHand();
|
ItemStack itemStack = player.getItemInHand();
|
||||||
@ -94,33 +69,6 @@ public class BukkitPlayer extends LocalPlayer {
|
|||||||
// TODO: Make this actually give the item
|
// TODO: Make this actually give the item
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean passThroughForwardWall(int range) {
|
|
||||||
boolean foundNext = false;
|
|
||||||
int searchDist = 0;
|
|
||||||
TargetBlock hitBlox = new TargetBlock(player, range, 0.2);
|
|
||||||
LocalWorld world = getPosition().getWorld();
|
|
||||||
Block block;
|
|
||||||
while ((block = hitBlox.getNextBlock()) != null) {
|
|
||||||
searchDist++;
|
|
||||||
if (searchDist > 20) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (BlockType.canPassThrough(block.getTypeId())) {
|
|
||||||
if (foundNext) {
|
|
||||||
Vector v = new Vector(block.getX(), block.getY() - 1, block.getZ());
|
|
||||||
if (BlockType.canPassThrough(world.getBlockType(v))) {
|
|
||||||
setPosition(v.add(0.5, 0, 0.5));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foundNext = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printRaw(String msg) {
|
public void printRaw(String msg) {
|
||||||
player.sendMessage(msg);
|
player.sendMessage(msg);
|
||||||
|
@ -1,625 +0,0 @@
|
|||||||
package com.sk89q.worldedit.bukkit;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author toi Thanks to Raphfrk for optimization of this class.
|
|
||||||
*/
|
|
||||||
public class TargetBlock {
|
|
||||||
|
|
||||||
private Location loc;
|
|
||||||
private double viewHeight;
|
|
||||||
private int maxDistance;
|
|
||||||
private int[] blockToIgnore;
|
|
||||||
private double checkDistance, curDistance;
|
|
||||||
private double xRotation, yRotation;
|
|
||||||
private Vector targetPos = new Vector();
|
|
||||||
private Vector targetPosDouble = new Vector();
|
|
||||||
private Vector prevPos = new Vector();
|
|
||||||
private Vector offset = new Vector();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor requiring a player, uses default values
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* Player to work with
|
|
||||||
*/
|
|
||||||
public TargetBlock(Player player) {
|
|
||||||
this.setValues(player.getLocation(), 300, 1.65, 0.2, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor requiring a location, uses default values
|
|
||||||
*
|
|
||||||
* @param loc
|
|
||||||
* Location to work with
|
|
||||||
*/
|
|
||||||
public TargetBlock(Location loc) {
|
|
||||||
this.setValues(loc, 300, 0, 0.2, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor requiring a player, max distance and a checking distance
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* Player to work with
|
|
||||||
* @param maxDistance
|
|
||||||
* How far it checks for blocks
|
|
||||||
* @param checkDistance
|
|
||||||
* How often to check for blocks, the smaller the more precise
|
|
||||||
*/
|
|
||||||
public TargetBlock(Player player, int maxDistance, double checkDistance) {
|
|
||||||
this.setValues(player.getLocation(), maxDistance, 1.65, checkDistance,
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor requiring a location, max distance and a checking distance
|
|
||||||
*
|
|
||||||
* @param loc
|
|
||||||
* What location to work with
|
|
||||||
* @param maxDistance
|
|
||||||
* How far it checks for blocks
|
|
||||||
* @param checkDistance
|
|
||||||
* How often to check for blocks, the smaller the more precise
|
|
||||||
*/
|
|
||||||
public TargetBlock(Location loc, int maxDistance, double checkDistance) {
|
|
||||||
this.setValues(loc, maxDistance, 0, checkDistance, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor requiring a player, max distance, checking distance and an
|
|
||||||
* array of blocks to ignore
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* What player to work with
|
|
||||||
* @param maxDistance
|
|
||||||
* How far it checks for blocks
|
|
||||||
* @param checkDistance
|
|
||||||
* How often to check for blocks, the smaller the more precise
|
|
||||||
* @param blocksToIgnore
|
|
||||||
* Integer array of what block ids to ignore while checking for
|
|
||||||
* viable targets
|
|
||||||
*/
|
|
||||||
public TargetBlock(Player player, int maxDistance, double checkDistance,
|
|
||||||
int[] blocksToIgnore) {
|
|
||||||
this.setValues(player.getLocation(), maxDistance, 1.65, checkDistance,
|
|
||||||
blocksToIgnore);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor requiring a location, max distance, checking distance and an
|
|
||||||
* array of blocks to ignore
|
|
||||||
*
|
|
||||||
* @param loc
|
|
||||||
* What location to work with
|
|
||||||
* @param maxDistance
|
|
||||||
* How far it checks for blocks
|
|
||||||
* @param checkDistance
|
|
||||||
* How often to check for blocks, the smaller the more precise
|
|
||||||
* @param blocksToIgnore
|
|
||||||
* Array of what block ids to ignore while checking for viable
|
|
||||||
* targets
|
|
||||||
*/
|
|
||||||
public TargetBlock(Location loc, int maxDistance, double checkDistance,
|
|
||||||
int[] blocksToIgnore) {
|
|
||||||
this.setValues(loc, maxDistance, 0, checkDistance, blocksToIgnore);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor requiring a player, max distance, checking distance and an
|
|
||||||
* array of blocks to ignore
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* What player to work with
|
|
||||||
* @param maxDistance
|
|
||||||
* How far it checks for blocks
|
|
||||||
* @param checkDistance
|
|
||||||
* How often to check for blocks, the smaller the more precise
|
|
||||||
* @param blocksToIgnore
|
|
||||||
* String ArrayList of what block ids to ignore while checking
|
|
||||||
* for viable targets
|
|
||||||
*/
|
|
||||||
public TargetBlock(Player player, int maxDistance, double checkDistance,
|
|
||||||
ArrayList<String> blocksToIgnore) {
|
|
||||||
int[] bti = this.convertStringArraytoIntArray(blocksToIgnore);
|
|
||||||
this.setValues(player.getLocation(), maxDistance, 1.65, checkDistance,
|
|
||||||
bti);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor requiring a location, max distance, checking distance and an
|
|
||||||
* array of blocks to ignore
|
|
||||||
*
|
|
||||||
* @param loc
|
|
||||||
* What location to work with
|
|
||||||
* @param maxDistance
|
|
||||||
* How far it checks for blocks
|
|
||||||
* @param checkDistance
|
|
||||||
* How often to check for blocks, the smaller the more precise
|
|
||||||
* @param blocksToIgnore
|
|
||||||
* String ArrayList of what block ids to ignore while checking
|
|
||||||
* for viable targets
|
|
||||||
*/
|
|
||||||
public TargetBlock(Location loc, int maxDistance, double checkDistance,
|
|
||||||
ArrayList<String> blocksToIgnore) {
|
|
||||||
int[] bti = this.convertStringArraytoIntArray(blocksToIgnore);
|
|
||||||
this.setValues(loc, maxDistance, 0, checkDistance, bti);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the values, all constructors uses this function
|
|
||||||
*
|
|
||||||
* @param loc
|
|
||||||
* Location of the view
|
|
||||||
* @param maxDistance
|
|
||||||
* How far it checks for blocks
|
|
||||||
* @param viewPos
|
|
||||||
* Where the view is positioned in y-axis
|
|
||||||
* @param checkDistance
|
|
||||||
* How often to check for blocks, the smaller the more precise
|
|
||||||
* @param blocksToIgnore
|
|
||||||
* Ids of blocks to ignore while checking for viable targets
|
|
||||||
*/
|
|
||||||
private void setValues(Location loc, int maxDistance, double viewHeight,
|
|
||||||
double checkDistance, int[] blocksToIgnore) {
|
|
||||||
this.loc = loc;
|
|
||||||
this.maxDistance = maxDistance;
|
|
||||||
this.viewHeight = viewHeight;
|
|
||||||
this.checkDistance = checkDistance;
|
|
||||||
this.blockToIgnore = blocksToIgnore;
|
|
||||||
this.curDistance = 0;
|
|
||||||
xRotation = (loc.getYaw() + 90) % 360;
|
|
||||||
yRotation = loc.getPitch() * -1;
|
|
||||||
|
|
||||||
double h = (checkDistance * Math.cos(Math.toRadians(yRotation)));
|
|
||||||
offset.setY((checkDistance * Math.sin(Math.toRadians(yRotation))));
|
|
||||||
offset.setX((h * Math.cos(Math.toRadians(xRotation))));
|
|
||||||
offset.setZ((h * Math.sin(Math.toRadians(xRotation))));
|
|
||||||
|
|
||||||
targetPosDouble = new Vector(loc.getX(), loc.getY() + viewHeight,
|
|
||||||
loc.getZ());
|
|
||||||
targetPos = new Vector(targetPosDouble.getBlockX(),
|
|
||||||
targetPosDouble.getBlockY(), targetPosDouble.getBlockZ());
|
|
||||||
prevPos = targetPos.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call this to reset checking position to allow you to check for a new
|
|
||||||
* target with the same TargetBlock instance.
|
|
||||||
*/
|
|
||||||
public void reset() {
|
|
||||||
targetPosDouble = new Vector(loc.getX(), loc.getY() + viewHeight,
|
|
||||||
loc.getZ());
|
|
||||||
targetPos = new Vector(targetPosDouble.getBlockX(),
|
|
||||||
targetPosDouble.getBlockY(), targetPosDouble.getBlockZ());
|
|
||||||
prevPos = targetPos.clone();
|
|
||||||
this.curDistance = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the distance to a block. Measures from the block underneath the
|
|
||||||
* player to the targetblock Should only be used when passing player as an
|
|
||||||
* constructor parameter
|
|
||||||
*
|
|
||||||
* @return double
|
|
||||||
*/
|
|
||||||
public double getDistanceToBlock() {
|
|
||||||
Vector blockUnderPlayer = new Vector(
|
|
||||||
(int) Math.floor(loc.getX() + 0.5),
|
|
||||||
(int) Math.floor(loc.getY() - 0.5),
|
|
||||||
(int) Math.floor(loc.getZ() + 0.5));
|
|
||||||
|
|
||||||
Block blk = getTargetBlock();
|
|
||||||
double x = blk.getX() - blockUnderPlayer.getBlockX();
|
|
||||||
double y = blk.getY() - blockUnderPlayer.getBlockY();
|
|
||||||
double z = blk.getZ() - blockUnderPlayer.getBlockZ();
|
|
||||||
|
|
||||||
return Math.sqrt((Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the rounded distance to a block. Measures from the block underneath
|
|
||||||
* the player to the targetblock Should only be used when passing player as
|
|
||||||
* an constructor parameter
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public int getDistanceToBlockRounded() {
|
|
||||||
Vector blockUnderPlayer = new Vector(
|
|
||||||
(int) Math.floor(loc.getX() + 0.5),
|
|
||||||
(int) Math.floor(loc.getY() - 0.5),
|
|
||||||
(int) Math.floor(loc.getZ() + 0.5));
|
|
||||||
|
|
||||||
Block blk = getTargetBlock();
|
|
||||||
double x = blk.getX() - blockUnderPlayer.getBlockX();
|
|
||||||
double y = blk.getY() - blockUnderPlayer.getBlockY();
|
|
||||||
double z = blk.getZ() - blockUnderPlayer.getBlockZ();
|
|
||||||
|
|
||||||
return (int) Math
|
|
||||||
.round((Math.sqrt((Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(
|
|
||||||
z, 2)))));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the floored x distance to a block.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public int getXDistanceToBlock() {
|
|
||||||
this.reset();
|
|
||||||
return (int) Math
|
|
||||||
.floor(getTargetBlock().getX() - loc.getBlockX() + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the floored y distance to a block
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public int getYDistanceToBlock() {
|
|
||||||
this.reset();
|
|
||||||
return (int) Math.floor(getTargetBlock().getY() - loc.getBlockY()
|
|
||||||
+ viewHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the floored z distance to a block
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public int getZDistanceToBlock() {
|
|
||||||
this.reset();
|
|
||||||
return (int) Math
|
|
||||||
.floor(getTargetBlock().getZ() - loc.getBlockZ() + 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the block at the sight. Returns null if out of range or if no
|
|
||||||
* viable target was found
|
|
||||||
*
|
|
||||||
* @return Block
|
|
||||||
*/
|
|
||||||
public Block getTargetBlock() {
|
|
||||||
this.reset();
|
|
||||||
while ((getNextBlock() != null)
|
|
||||||
&& ((getCurrentBlock().getTypeId() == 0) || this
|
|
||||||
.blockToIgnoreHasValue(getCurrentBlock().getTypeId())))
|
|
||||||
;
|
|
||||||
return getCurrentBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the type of the block at the sight. Returns false if the block
|
|
||||||
* wasn't set.
|
|
||||||
*
|
|
||||||
* @param typeID
|
|
||||||
* ID of type to set the block to
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public boolean setTargetBlock(int typeID) {
|
|
||||||
if (Material.getMaterial(typeID) != null) {
|
|
||||||
this.reset();
|
|
||||||
while (getNextBlock() != null && getCurrentBlock().getTypeId() == 0)
|
|
||||||
;
|
|
||||||
if (getCurrentBlock() != null) {
|
|
||||||
Block blk = loc.getWorld().getBlockAt(targetPos.getBlockX(),
|
|
||||||
targetPos.getBlockY(), targetPos.getBlockZ());
|
|
||||||
blk.setTypeId(typeID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the type of the block at the sight. Returns false if the block
|
|
||||||
* wasn't set.
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* Material to set the block to
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public boolean setTargetBlock(Material type) {
|
|
||||||
this.reset();
|
|
||||||
while ((getNextBlock() != null)
|
|
||||||
&& ((getCurrentBlock().getTypeId() == 0) || this
|
|
||||||
.blockToIgnoreHasValue(getCurrentBlock().getTypeId())))
|
|
||||||
;
|
|
||||||
if (getCurrentBlock() != null) {
|
|
||||||
Block blk = loc.getWorld().getBlockAt(targetPos.getBlockX(),
|
|
||||||
targetPos.getBlockY(), targetPos.getBlockZ());
|
|
||||||
blk.setType(type);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the type of the block at the sight. Returns false if the block
|
|
||||||
* wasn't set. Observe! At the moment this function is using the built-in
|
|
||||||
* enumerator function .valueOf(String) but would preferably be changed to
|
|
||||||
* smarter function, when implemented
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* Name of type to set the block to
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public boolean setTargetBlock(String type) {
|
|
||||||
Material mat = Material.valueOf(type);
|
|
||||||
if (mat != null) {
|
|
||||||
this.reset();
|
|
||||||
while ((getNextBlock() != null)
|
|
||||||
&& ((getCurrentBlock().getTypeId() == 0) || this
|
|
||||||
.blockToIgnoreHasValue(getCurrentBlock()
|
|
||||||
.getTypeId())))
|
|
||||||
;
|
|
||||||
if (getCurrentBlock() != null) {
|
|
||||||
Block blk = loc.getWorld().getBlockAt(targetPos.getBlockX(),
|
|
||||||
targetPos.getBlockY(), targetPos.getBlockZ());
|
|
||||||
blk.setType(mat);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the block attached to the face at the sight. Returns null if out
|
|
||||||
* of range or if no viable target was found
|
|
||||||
*
|
|
||||||
* @return Block
|
|
||||||
*/
|
|
||||||
public Block getFaceBlock() {
|
|
||||||
while ((getNextBlock() != null)
|
|
||||||
&& ((getCurrentBlock().getTypeId() == 0) || this
|
|
||||||
.blockToIgnoreHasValue(getCurrentBlock().getTypeId())))
|
|
||||||
;
|
|
||||||
if (getCurrentBlock() != null) {
|
|
||||||
return getPreviousBlock();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the type of the block attached to the face at the sight. Returns
|
|
||||||
* false if the block wasn't set.
|
|
||||||
*
|
|
||||||
* @param typeID
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public boolean setFaceBlock(int typeID) {
|
|
||||||
if (Material.getMaterial(typeID) != null) {
|
|
||||||
if (getCurrentBlock() != null) {
|
|
||||||
Block blk = loc.getWorld().getBlockAt(prevPos.getBlockX(),
|
|
||||||
prevPos.getBlockY(), prevPos.getBlockZ());
|
|
||||||
blk.setTypeId(typeID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the type of the block attached to the face at the sight. Returns
|
|
||||||
* false if the block wasn't set.
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public boolean setFaceBlock(Material type) {
|
|
||||||
if (getCurrentBlock() != null) {
|
|
||||||
Block blk = loc.getWorld().getBlockAt(prevPos.getBlockX(),
|
|
||||||
prevPos.getBlockY(), prevPos.getBlockZ());
|
|
||||||
blk.setType(type);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the type of the block attached to the face at the sight. Returns
|
|
||||||
* false if the block wasn't set. Observe! At the moment this function is
|
|
||||||
* using the built-in enumerator function .valueOf(String) but would
|
|
||||||
* preferably be changed to smarter function, when implemented
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public boolean setFaceBlock(String type) {
|
|
||||||
Material mat = Material.valueOf(type);
|
|
||||||
if (mat != null) {
|
|
||||||
if (getCurrentBlock() != null) {
|
|
||||||
Block blk = loc.getWorld().getBlockAt(prevPos.getBlockX(),
|
|
||||||
prevPos.getBlockY(), prevPos.getBlockZ());
|
|
||||||
blk.setType(mat);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get next block
|
|
||||||
*
|
|
||||||
* @return Block
|
|
||||||
*/
|
|
||||||
public Block getNextBlock() {
|
|
||||||
prevPos = targetPos.clone();
|
|
||||||
do {
|
|
||||||
curDistance += checkDistance;
|
|
||||||
|
|
||||||
targetPosDouble.setX(offset.getX() + targetPosDouble.getX());
|
|
||||||
targetPosDouble.setY(offset.getY() + targetPosDouble.getY());
|
|
||||||
targetPosDouble.setZ(offset.getZ() + targetPosDouble.getZ());
|
|
||||||
targetPos = new Vector(targetPosDouble.getBlockX(),
|
|
||||||
targetPosDouble.getBlockY(), targetPosDouble.getBlockZ());
|
|
||||||
} while (curDistance <= maxDistance
|
|
||||||
&& targetPos.getBlockX() == prevPos.getBlockX()
|
|
||||||
&& targetPos.getBlockY() == prevPos.getBlockY()
|
|
||||||
&& targetPos.getBlockZ() == prevPos.getBlockZ());
|
|
||||||
if (curDistance > maxDistance) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.loc.getWorld().getBlockAt(this.targetPos.getBlockX(),
|
|
||||||
this.targetPos.getBlockY(), this.targetPos.getBlockZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current block along the line of vision
|
|
||||||
*
|
|
||||||
* @return Block
|
|
||||||
*/
|
|
||||||
public Block getCurrentBlock() {
|
|
||||||
if (curDistance > maxDistance) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return this.loc.getWorld().getBlockAt(this.targetPos.getBlockX(),
|
|
||||||
this.targetPos.getBlockY(), this.targetPos.getBlockZ());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets current block type. Returns false if the block wasn't set.
|
|
||||||
*
|
|
||||||
* @param typeID
|
|
||||||
*/
|
|
||||||
public boolean setCurrentBlock(int typeID) {
|
|
||||||
if (Material.getMaterial(typeID) != null) {
|
|
||||||
Block blk = getCurrentBlock();
|
|
||||||
if (blk != null) {
|
|
||||||
blk.setTypeId(typeID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets current block type. Returns false if the block wasn't set.
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
*/
|
|
||||||
public boolean setCurrentBlock(Material type) {
|
|
||||||
Block blk = getCurrentBlock();
|
|
||||||
if (blk != null) {
|
|
||||||
blk.setType(type);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets current block type. Returns false if the block wasn't set. Observe!
|
|
||||||
* At the moment this function is using the built-in enumerator function
|
|
||||||
* .valueOf(String) but would preferably be changed to smarter function,
|
|
||||||
* when implemented
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
*/
|
|
||||||
public boolean setCurrentBlock(String type) {
|
|
||||||
Material mat = Material.valueOf(type);
|
|
||||||
if (mat != null) {
|
|
||||||
Block blk = getCurrentBlock();
|
|
||||||
if (blk != null) {
|
|
||||||
blk.setType(mat);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the previous block in the aimed path
|
|
||||||
*
|
|
||||||
* @return Block
|
|
||||||
*/
|
|
||||||
public Block getPreviousBlock() {
|
|
||||||
return this.loc.getWorld().getBlockAt(prevPos.getBlockX(),
|
|
||||||
prevPos.getBlockY(), prevPos.getBlockZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets previous block type id. Returns false if the block wasn't set.
|
|
||||||
*
|
|
||||||
* @param typeID
|
|
||||||
*/
|
|
||||||
public boolean setPreviousBlock(int typeID) {
|
|
||||||
if (Material.getMaterial(typeID) != null) {
|
|
||||||
Block blk = getPreviousBlock();
|
|
||||||
if (blk != null) {
|
|
||||||
blk.setTypeId(typeID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets previous block type id. Returns false if the block wasn't set.
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
*/
|
|
||||||
public boolean setPreviousBlock(Material type) {
|
|
||||||
Block blk = getPreviousBlock();
|
|
||||||
if (blk != null) {
|
|
||||||
blk.setType(type);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets previous block type id. Returns false if the block wasn't set.
|
|
||||||
* Observe! At the moment this function is using the built-in enumerator
|
|
||||||
* function .valueOf(String) but would preferably be changed to smarter
|
|
||||||
* function, when implemented
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
*/
|
|
||||||
public boolean setPreviousBlock(String type) {
|
|
||||||
Material mat = Material.valueOf(type);
|
|
||||||
if (mat != null) {
|
|
||||||
Block blk = getPreviousBlock();
|
|
||||||
if (blk != null) {
|
|
||||||
blk.setType(mat);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int[] convertStringArraytoIntArray(ArrayList<String> array) {
|
|
||||||
if (array != null) {
|
|
||||||
int intarray[] = new int[array.size()];
|
|
||||||
for (int i = 0; i < array.size(); i++) {
|
|
||||||
try {
|
|
||||||
intarray[i] = Integer.parseInt(array.get(i));
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
intarray[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return intarray;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean blockToIgnoreHasValue(int value) {
|
|
||||||
if (this.blockToIgnore != null) {
|
|
||||||
if (this.blockToIgnore.length > 0) {
|
|
||||||
for (int i : this.blockToIgnore) {
|
|
||||||
if (i == value)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
174
src/com/sk89q/worldedit/util/TargetBlock.java
Normale Datei
174
src/com/sk89q/worldedit/util/TargetBlock.java
Normale Datei
@ -0,0 +1,174 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 toi
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.util;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.BlockWorldVector;
|
||||||
|
import com.sk89q.worldedit.LocalPlayer;
|
||||||
|
import com.sk89q.worldedit.LocalWorld;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class uses an inefficient method to figure out what block a player
|
||||||
|
* is looking towards.
|
||||||
|
*
|
||||||
|
* Originally written by toi. It was ported to WorldEdit and trimmed down by
|
||||||
|
* sk89q. Thanks to Raphfrk for optimization of toi's original class.
|
||||||
|
*
|
||||||
|
* @author toi
|
||||||
|
*/
|
||||||
|
public class TargetBlock {
|
||||||
|
private LocalWorld world;
|
||||||
|
private int maxDistance;
|
||||||
|
private double checkDistance, curDistance;
|
||||||
|
private Vector targetPos = new Vector();
|
||||||
|
private Vector targetPosDouble = new Vector();
|
||||||
|
private Vector prevPos = new Vector();
|
||||||
|
private Vector offset = new Vector();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor requiring a player, uses default values
|
||||||
|
*
|
||||||
|
* @param player player to work with
|
||||||
|
*/
|
||||||
|
public TargetBlock(LocalPlayer player) {
|
||||||
|
this.world = player.getWorld();
|
||||||
|
this.setValues(player.getPosition(), player.getYaw(), player.getPitch(),
|
||||||
|
300, 1.65, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor requiring a player, max distance and a checking distance
|
||||||
|
*
|
||||||
|
* @param player LocalPlayer to work with
|
||||||
|
* @param maxDistance how far it checks for blocks
|
||||||
|
* @param checkDistance how often to check for blocks, the smaller the more precise
|
||||||
|
*/
|
||||||
|
public TargetBlock(LocalPlayer player, int maxDistance, double checkDistance) {
|
||||||
|
this.world = player.getWorld();
|
||||||
|
this.setValues(player.getPosition(), player.getYaw(), player.getPitch(),
|
||||||
|
maxDistance, 1.65, checkDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the values, all constructors uses this function
|
||||||
|
*
|
||||||
|
* @param loc location of the view
|
||||||
|
* @param xRotation
|
||||||
|
* @param yRotation
|
||||||
|
* @param maxDistance how far it checks for blocks
|
||||||
|
* @param viewPos where the view is positioned in y-axis
|
||||||
|
* @param checkDistance how often to check for blocks, the smaller the more precise
|
||||||
|
*/
|
||||||
|
private void setValues(Vector loc, double xRotation, double yRotation,
|
||||||
|
int maxDistance, double viewHeight, double checkDistance) {
|
||||||
|
this.maxDistance = maxDistance;
|
||||||
|
this.checkDistance = checkDistance;
|
||||||
|
this.curDistance = 0;
|
||||||
|
xRotation = (xRotation + 90) % 360;
|
||||||
|
yRotation = yRotation * -1;
|
||||||
|
|
||||||
|
double h = (checkDistance * Math.cos(Math.toRadians(yRotation)));
|
||||||
|
|
||||||
|
offset = new Vector((h * Math.cos(Math.toRadians(xRotation))),
|
||||||
|
(checkDistance * Math.sin(Math.toRadians(yRotation))),
|
||||||
|
(h * Math.sin(Math.toRadians(xRotation))));
|
||||||
|
|
||||||
|
targetPosDouble = loc.add(0, viewHeight, 0);
|
||||||
|
targetPos = targetPosDouble.toBlockPoint();
|
||||||
|
prevPos = targetPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the block at the sight. Returns null if out of range or if no
|
||||||
|
* viable target was found
|
||||||
|
*
|
||||||
|
* @return Block
|
||||||
|
*/
|
||||||
|
public BlockWorldVector getTargetBlock() {
|
||||||
|
while ((getNextBlock() != null)
|
||||||
|
&& (world.getBlockType(getCurrentBlock()) == 0));
|
||||||
|
return getCurrentBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the block at the sight. Returns null if out of range or if no
|
||||||
|
* viable target was found
|
||||||
|
*
|
||||||
|
* @return Block
|
||||||
|
*/
|
||||||
|
public BlockWorldVector getSolidTargetBlock() {
|
||||||
|
while ((getNextBlock() != null)
|
||||||
|
&& BlockType.canPassThrough(world.getBlockType(getCurrentBlock())));
|
||||||
|
return getCurrentBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get next block
|
||||||
|
*
|
||||||
|
* @return next block position
|
||||||
|
*/
|
||||||
|
public BlockWorldVector getNextBlock() {
|
||||||
|
prevPos = targetPos;
|
||||||
|
do {
|
||||||
|
curDistance += checkDistance;
|
||||||
|
|
||||||
|
targetPosDouble = offset.add(targetPosDouble.getX(),
|
||||||
|
targetPosDouble.getY(),
|
||||||
|
targetPosDouble.getZ());
|
||||||
|
targetPos = targetPosDouble.toBlockPoint();
|
||||||
|
} while (curDistance <= maxDistance
|
||||||
|
&& targetPos.getBlockX() == prevPos.getBlockX()
|
||||||
|
&& targetPos.getBlockY() == prevPos.getBlockY()
|
||||||
|
&& targetPos.getBlockZ() == prevPos.getBlockZ());
|
||||||
|
|
||||||
|
if (curDistance > maxDistance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BlockWorldVector(world, targetPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current block along the line of vision
|
||||||
|
*
|
||||||
|
* @return block position
|
||||||
|
*/
|
||||||
|
public BlockWorldVector getCurrentBlock() {
|
||||||
|
if (curDistance > maxDistance) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return new BlockWorldVector(world, targetPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the previous block in the aimed path
|
||||||
|
*
|
||||||
|
* @return block position
|
||||||
|
*/
|
||||||
|
public BlockWorldVector getPreviousBlock() {
|
||||||
|
return new BlockWorldVector(world, prevPos);
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren