use of me.deecaad.weaponmechanics.weapon.explode.raytrace.TraceResult in project MechanicsMain by WeaponMechanics.
the class RemoveOnBlockCollisionProjectile method handleCollisions.
@Override
public boolean handleCollisions(boolean disableEntityCollisions) {
Vector possibleNextLocation = getLocation().add(getMotion());
TraceResult result = new Ray(getWorld(), getLocation(), possibleNextLocation).trace(TraceCollision.BLOCK, 0.3);
if (!result.isEmpty()) {
Block hit = result.getOneBlock();
setRawLocation(hit.getLocation().toVector());
onCollide(result.getOneBlock());
return true;
}
setRawLocation(possibleNextLocation);
return false;
}
use of me.deecaad.weaponmechanics.weapon.explode.raytrace.TraceResult in project MechanicsMain by WeaponMechanics.
the class DefaultExposure method getExposure.
/**
* Gets a double [0, 1] representing how exposed the entity is to the explosion
*
* @param vec3d The origin of the explosion
* @param entity The entity exposed to the explosion
* @return The level of exposure of the entity to the epxlosion
*/
private static double getExposure(Vector vec3d, Entity entity) {
HitBox box = WeaponCompatibilityAPI.getWeaponCompatibility().getHitBox(entity);
if (box == null) {
return 0.0;
}
// Get the dimensions of the bounding box
double width = box.getWidth();
double height = box.getHeight();
double depth = box.getDepth();
// Gets the size of the grid in each axis
double stepX = width * 2.0 + 1.0;
double stepY = height * 2.0 + 1.0;
double stepZ = depth * 2.0 + 1.0;
double gridX = 1.0 / stepX;
double gridY = 1.0 / stepY;
double gridZ = 1.0 / stepZ;
// Outside the grid
if (gridX < 0.0 || gridY < 0.0 || gridZ < 0.0)
return 0.0;
double d3 = (1.0 - Math.floor(stepX) * gridX) / 2.0;
double d4 = (1.0 - Math.floor(stepZ) * gridZ) / 2.0;
// Setup variables for the loop
World world = entity.getWorld();
int successfulTraces = 0;
int totalTraces = 0;
// For each grid on the bounding box
for (double x = 0; x <= 1; x += gridX) {
for (double y = 0; y <= 1; y += gridY) {
for (double z = 0; z <= 1; z += gridZ) {
double a = NumberUtil.lerp(box.getMinX(), box.getMaxX(), x);
double b = NumberUtil.lerp(box.getMinY(), box.getMaxY(), y);
double c = NumberUtil.lerp(box.getMinZ(), box.getMaxZ(), z);
// Calculates a path from the origin of the explosion
// (0, 0, 0) to the current grid on the entity's bounding
// box. The Vector is then ray traced to check for obstructions
Vector vector = new Vector(a + d3, b, c + d4).subtract(vec3d);
Ray ray = new Ray(vec3d.toLocation(world), vector);
TraceResult trace = ray.trace(TraceCollision.BLOCK, 0.3);
if (trace.getBlocks().isEmpty()) {
successfulTraces++;
}
totalTraces++;
}
}
}
// The percentage of successful traces
return ((double) successfulTraces) / totalTraces;
}
use of me.deecaad.weaponmechanics.weapon.explode.raytrace.TraceResult in project MechanicsMain by WeaponMechanics.
the class ExplosionExposure method canSee.
/**
* Determines if the given entity can see the given <code>Location</code>.
*
* @param originLoc The point to check if the entity can see
* @param entity The entity to check against
* @param fov The field of view of the entity
* @return true if the entity can see the origin
*/
default boolean canSee(@Nonnull Location originLoc, @Nonnull LivingEntity entity, double fov) {
// Get the vector between the entity and origin, and the player's eye
// vector, and determine the angle between the 2 vectors.
Vector origin = originLoc.toVector();
Vector end = entity.getEyeLocation().toVector();
Vector direction = entity.getLocation().getDirection();
Vector between = origin.clone().subtract(end);
double angle = VectorUtil.getAngleBetween(direction, between);
// then we need to do more calculations
if (angle > fov) {
return false;
}
Ray ray = new Ray(originLoc.getWorld(), origin, end, between.length());
TraceCollision collision = new TraceCollision(BLOCK_OR_ENTITY) {
@Override
public boolean canHit(Block block) {
String name = block.getType().name();
// GLASS
if (name.endsWith("GLASS") || name.endsWith("PANE")) {
return false;
} else // LEAVES
if (name.endsWith("LEAVES")) {
return false;
} else // OAK_FENCE
if (name.endsWith("FENCE") || name.endsWith("FENCE_GATE")) {
return false;
} else if (name.equals("SLIME_BLOCK")) {
return false;
} else {
return WeaponCompatibilityAPI.getWeaponCompatibility().getHitBox(block) != null;
}
}
@Override
public boolean canHit(Entity entity1) {
return !entity1.equals(entity);
}
};
TraceResult result = ray.trace(collision, 0.2);
// origin, than the entity can see the explosion
return result.isEmpty();
}
use of me.deecaad.weaponmechanics.weapon.explode.raytrace.TraceResult in project MechanicsMain by WeaponMechanics.
the class OptimizedExposure method getExposure.
/**
* Gets a double [0.0, 1.0] representing how exposed the entity is to the explosion.
* Exposure is determined by 8 rays, 1 ray for each corner of an entity's
* bounding box. The returned exposure is equal to the number of rays that hit
* the entity divided by 8.
*
* <p>There is also one ray going to the center of the entity hit-box that
* has the power of 4 rays.
*
* @param vec3d The origin point
* @param entity The entity exposed to the explosion
* @return The level of exposure of the entity to the explosion
*/
private static double getExposure(Vector vec3d, Entity entity) {
HitBox box = WeaponCompatibilityAPI.getWeaponCompatibility().getHitBox(entity);
if (box == null) {
return 0.0;
}
// Setup variables for the loop
World world = entity.getWorld();
Vector min = box.getMin();
Vector max = box.getMax();
int successfulTraces = 0;
int totalTraces = 0;
// For each corner of the bounding box
for (int x = 0; x <= 1; x++) {
for (int y = 0; y <= 1; y++) {
for (int z = 0; z <= 1; z++) {
Vector lerp = VectorUtil.lerp(min, max, x, y, z);
// Determine if the ray can hit the entity without hitting a block
Ray ray = new Ray(world, vec3d, lerp);
TraceResult trace = ray.trace(TraceCollision.BLOCK, 0.3);
if (trace.getBlocks().isEmpty()) {
successfulTraces++;
}
totalTraces++;
}
}
}
// Add one more ray pointing to the center of the bound box. If this
// ray hits the entity, it has the power of 4 rays. If this ray does
// not hit the entity, it has the power of 0 rays
Ray ray = new Ray(world, vec3d, VectorUtil.lerp(min, max, 0.5));
TraceResult trace = ray.trace(TraceCollision.BLOCK, 0.3);
if (trace.getBlocks().isEmpty()) {
successfulTraces += 4;
totalTraces += 4;
}
// The percentage of successful traces
return ((double) successfulTraces) / totalTraces;
}
Aggregations