use of me.deecaad.weaponmechanics.weapon.projectile.HitBox 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;
}
use of me.deecaad.weaponmechanics.weapon.projectile.HitBox in project MechanicsMain by WeaponMechanics.
the class MeleeHandler method getHit.
private RayTraceResult getHit(LivingEntity shooter, Location eyeLocation, Vector direction, double range, @Nullable LivingEntity knownVictim) {
Vector eyeLocationToVector = eyeLocation.toVector();
if (knownVictim == null) {
if (range <= 0) {
return null;
}
double blockIteratorDistance = Math.ceil(range);
RayTraceResult hit = null;
BlockIterator blocks = new BlockIterator(eyeLocation.getWorld(), eyeLocationToVector, direction, 0.0, (int) (blockIteratorDistance < 1 ? 1 : blockIteratorDistance));
while (blocks.hasNext()) {
Block block = blocks.next();
HitBox blockBox = weaponCompatibility.getHitBox(block);
if (blockBox == null)
continue;
RayTraceResult rayTraceResult = blockBox.rayTrace(eyeLocationToVector, direction);
// Didn't hit
if (rayTraceResult == null)
continue;
hit = rayTraceResult;
break;
}
double distanceTravelledCheck = hit != null ? hit.getDistanceTravelled() : -1;
List<LivingEntity> entities = getPossibleEntities(shooter, eyeLocation, (hit != null ? hit.getHitLocation() : eyeLocation.toVector().add(direction.clone().multiply(range))));
hit = null;
if (entities != null && !entities.isEmpty()) {
for (LivingEntity entity : entities) {
HitBox entityBox = weaponCompatibility.getHitBox(entity);
if (entityBox == null)
continue;
RayTraceResult rayTraceResult = entityBox.rayTrace(eyeLocationToVector, direction);
// Didn't hit
if (rayTraceResult == null)
continue;
double rayTraceResultDistance = rayTraceResult.getDistanceTravelled();
// Didn't hit in range
if (rayTraceResultDistance > range)
continue;
if (distanceTravelledCheck == -1 || rayTraceResultDistance < distanceTravelledCheck) {
// Only change if closer than last hit result
hit = rayTraceResult;
distanceTravelledCheck = rayTraceResultDistance;
}
}
}
return hit;
}
// Simply check where known victim was hit and whether it was in range
HitBox entityBox = weaponCompatibility.getHitBox(knownVictim);
if (entityBox == null)
return null;
RayTraceResult rayTraceResult = entityBox.rayTrace(eyeLocationToVector, direction);
// Didn't hit in range
if (rayTraceResult == null || (range > 0 && rayTraceResult.getDistanceTravelled() > range))
return null;
return rayTraceResult;
}
use of me.deecaad.weaponmechanics.weapon.projectile.HitBox in project MechanicsMain by WeaponMechanics.
the class WeaponProjectile method getPossibleEntities.
private List<LivingEntity> getPossibleEntities() {
// Get the box of current location to end of this iteration
HitBox hitBox = new HitBox(getLocation(), getLocation().add(getMotion()));
int minX = floor((hitBox.getMinX() - 2.0D) / 16.0D);
int maxX = floor((hitBox.getMaxX() + 2.0D) / 16.0D);
int minZ = floor((hitBox.getMinZ() - 2.0D) / 16.0D);
int maxZ = floor((hitBox.getMaxZ() + 2.0D) / 16.0D);
List<LivingEntity> entities = new ArrayList<>(8);
for (int x = minX; x <= maxX; ++x) {
for (int z = minZ; z <= maxZ; ++z) {
Chunk chunk = getWorld().getChunkAt(x, z);
for (final Entity entity : chunk.getEntities()) {
if (!entity.getType().isAlive() || entity.isInvulnerable() || (getShooter() != null && getAliveTicks() < 10 && entity.getEntityId() == getShooter().getEntityId()))
continue;
entities.add((LivingEntity) entity);
}
}
}
return entities.isEmpty() ? null : entities;
}
use of me.deecaad.weaponmechanics.weapon.projectile.HitBox in project MechanicsMain by WeaponMechanics.
the class MoveTask method isInMidair.
/**
* Basically checks if entity is in mid air.
* Mid air is determined on if current block in player's position doesn't have hit box and block below that doesn't have hit box either
*/
private boolean isInMidair(LivingEntity livingEntity) {
IWeaponCompatibility weaponCompatibility = WeaponCompatibilityAPI.getWeaponCompatibility();
Block current = livingEntity.getLocation().getBlock();
Block below = current.getRelative(BlockFace.DOWN);
// Check for liquid as hit boxes are considered null if block is liquid
if (current.isLiquid() || below.isLiquid())
return false;
HitBox belowHitBox = weaponCompatibility.getHitBox(below);
HitBox currentHitBox = weaponCompatibility.getHitBox(current);
return belowHitBox == null && currentHitBox == null;
}
use of me.deecaad.weaponmechanics.weapon.projectile.HitBox in project MechanicsMain by WeaponMechanics.
the class v1_9_R2 method getHitBox.
@Override
public HitBox getHitBox(org.bukkit.block.Block block) {
if (block.isEmpty() || block.isLiquid())
return null;
WorldServer worldServer = ((CraftWorld) block.getWorld()).getHandle();
BlockPosition blockPosition = new BlockPosition(block.getX(), block.getY(), block.getZ());
IBlockData blockData = worldServer.getType(blockPosition);
Block nmsBlock = blockData.getBlock();
// Passable block check -> false means passable (thats why !)
if (!(blockData.d(worldServer, blockPosition) != Block.k && nmsBlock.a(blockData, false)))
return null;
AxisAlignedBB aabb = blockData.c(worldServer, blockPosition);
// 1.12 -> e
// 1.11 -> d
// 1.9 - 1.10 -> c
int x = blockPosition.getX(), y = blockPosition.getY(), z = blockPosition.getZ();
HitBox hitBox = new HitBox(x + aabb.a, y + aabb.b, z + aabb.c, x + aabb.d, y + aabb.e, z + aabb.f);
hitBox.setBlockHitBox(block);
return hitBox;
}
Aggregations