use of me.deecaad.weaponmechanics.weapon.projectile.weaponprojectile.RayTraceResult in project MechanicsMain by WeaponMechanics.
the class MeleeHandler method meleeWithoutTimings.
private boolean meleeWithoutTimings(EntityWrapper entityWrapper, String weaponTitle, ItemStack weaponStack, EquipmentSlot slot, TriggerType triggerType, boolean dualWield, @Nullable LivingEntity knownVictim) {
Configuration config = getConfigurations();
HandData handData = entityWrapper.getMainHandData();
int meleeHitDelay = config.getInt(weaponTitle + ".Melee.Melee_Hit_Delay");
if (meleeHitDelay != 0 && !NumberUtil.hasMillisPassed(handData.getLastMeleeTime(), meleeHitDelay))
return false;
int meleeMissDelay = config.getInt(weaponTitle + ".Melee.Melee_Miss.Melee_Miss_Delay");
if (meleeMissDelay != 0 && !NumberUtil.hasMillisPassed(handData.getLastMeleeMissTime(), meleeMissDelay))
return false;
double meleeRange = config.getDouble(weaponTitle + ".Melee.Melee_Range");
LivingEntity shooter = entityWrapper.getEntity();
Location eyeLocation = shooter.getEyeLocation();
Vector direction = eyeLocation.getDirection();
RayTraceResult hit = getHit(shooter, eyeLocation, direction, meleeRange, knownVictim);
boolean result = false;
if (hit != null) {
result = weaponHandler.getShootHandler().shootWithoutTrigger(entityWrapper, weaponTitle, weaponStack, slot, triggerType, dualWield);
if (result) {
if (meleeHitDelay != 0) {
handData.setLastMeleeTime(System.currentTimeMillis());
if (getConfigurations().getBool(weaponTitle + ".Info.Show_Cooldown.Melee_Hit_Delay") && shooter.getType() == EntityType.PLAYER) {
CompatibilityAPI.getEntityCompatibility().setCooldown((Player) shooter, weaponStack.getType(), meleeHitDelay / 50);
}
}
hit.handleMeleeHit(shooter, direction, weaponTitle, weaponStack);
}
} else {
// Handle miss
Mechanics meleeMissMechanics = getConfigurations().getObject(weaponTitle + ".Melee.Melee_Miss.Mechanics", Mechanics.class);
if (meleeMissMechanics != null)
meleeMissMechanics.use(new CastData(entityWrapper, weaponTitle, weaponStack));
if (getConfigurations().getBool(weaponTitle + ".Melee.Melee_Miss.Consume_On_Miss")) {
weaponHandler.getShootHandler().shootWithoutTrigger(entityWrapper, weaponTitle, weaponStack, slot, triggerType, dualWield);
result = true;
}
if (meleeMissDelay != 0) {
handData.setLastMeleeMissTime(System.currentTimeMillis());
if (getConfigurations().getBool(weaponTitle + ".Info.Show_Cooldown.Melee_Miss_Delay") && shooter.getType() == EntityType.PLAYER) {
CompatibilityAPI.getEntityCompatibility().setCooldown((Player) shooter, weaponStack.getType(), meleeMissDelay / 50);
}
}
}
return result;
}
use of me.deecaad.weaponmechanics.weapon.projectile.weaponprojectile.RayTraceResult in project MechanicsMain by WeaponMechanics.
the class HitBox method rayTrace.
/**
* Uses BoundingBox class method rayTrace(Vector, Vector, double) with slight modifications. Easier backwards compatibility this way.
* https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/util/BoundingBox.html#rayTrace(org.bukkit.util.Vector,org.bukkit.util.Vector,double)
*
* @param location the start location of ray
* @param normalizedMotion the normalized direction
* @return the ray trace result or null if there is no hit
*/
private RayTraceResult rayTrace(Vector location, Vector normalizedMotion, Block block, LivingEntity livingEntity) {
double startX = location.getX();
double startY = location.getY();
double startZ = location.getZ();
double dirX = normalizedMotion.getX();
double dirY = normalizedMotion.getY();
double dirZ = normalizedMotion.getZ();
double divX = 1.0D / dirX;
double divY = 1.0D / dirY;
double divZ = 1.0D / dirZ;
double tMin, tMax, tyMin, tyMax;
BlockFace hitBlockFaceMin, hitBlockFaceMax, hitBlockFaceYMin, hitBlockFaceYMax;
// x
if (dirX >= 0.0D) {
tMin = (this.minX - startX) * divX;
tMax = (this.maxX - startX) * divX;
hitBlockFaceMin = BlockFace.WEST;
hitBlockFaceMax = BlockFace.EAST;
} else {
tMin = (this.maxX - startX) * divX;
tMax = (this.minX - startX) * divX;
hitBlockFaceMin = BlockFace.EAST;
hitBlockFaceMax = BlockFace.WEST;
}
// y
if (dirY >= 0.0D) {
tyMin = (this.minY - startY) * divY;
tyMax = (this.maxY - startY) * divY;
hitBlockFaceYMin = BlockFace.DOWN;
hitBlockFaceYMax = BlockFace.UP;
} else {
tyMin = (this.maxY - startY) * divY;
tyMax = (this.minY - startY) * divY;
hitBlockFaceYMin = BlockFace.UP;
hitBlockFaceYMax = BlockFace.DOWN;
}
if ((tMin > tyMax) || (tMax < tyMin)) {
return null;
}
if (tyMin > tMin) {
tMin = tyMin;
hitBlockFaceMin = hitBlockFaceYMin;
}
if (tyMax < tMax) {
tMax = tyMax;
hitBlockFaceMax = hitBlockFaceYMax;
}
// z
double tzMin, tzMax;
BlockFace hitBlockFaceZMin, hitBlockFaceZMax;
if (dirZ >= 0.0D) {
tzMin = (this.minZ - startZ) * divZ;
tzMax = (this.maxZ - startZ) * divZ;
hitBlockFaceZMin = BlockFace.NORTH;
hitBlockFaceZMax = BlockFace.SOUTH;
} else {
tzMin = (this.maxZ - startZ) * divZ;
tzMax = (this.minZ - startZ) * divZ;
hitBlockFaceZMin = BlockFace.SOUTH;
hitBlockFaceZMax = BlockFace.NORTH;
}
if ((tMin > tzMax) || (tMax < tzMin)) {
return null;
}
if (tzMin > tMin) {
tMin = tzMin;
hitBlockFaceMin = hitBlockFaceZMin;
}
if (tzMax < tMax) {
tMax = tzMax;
hitBlockFaceMax = hitBlockFaceZMax;
}
if (tMax < 0.0D)
return null;
double t;
BlockFace hitBlockFace;
if (tMin < 0.0D) {
t = tMax;
hitBlockFace = hitBlockFaceMax;
} else {
t = tMin;
hitBlockFace = hitBlockFaceMin;
}
if (block != null) {
return new RayTraceResult(normalizedMotion.clone().multiply(t).add(location), t, hitBlockFace, block);
}
Vector hitLocation = normalizedMotion.clone().multiply(t).add(location);
return new RayTraceResult(hitLocation, t, hitBlockFace, livingEntity, getDamagePoint(hitLocation, normalizedMotion, livingEntity));
}
use of me.deecaad.weaponmechanics.weapon.projectile.weaponprojectile.RayTraceResult in project MechanicsMain by WeaponMechanics.
the class HitBox method rayTrace.
public RayTraceResult rayTrace(Vector location, Vector normalizedMotion) {
RayTraceResult mainBoxHit = rayTrace(location, normalizedMotion, block, livingEntity);
// Voxel shape not used or didn't hit main hitbox
if (voxelShape == null || mainBoxHit == null)
return mainBoxHit;
// Here we know main hitbox was hit, now check all voxel shapes
RayTraceResult hit = null;
double closestHit = -1;
for (HitBox boxPart : voxelShape) {
RayTraceResult boxPartHit = boxPart.rayTrace(location, normalizedMotion, block, livingEntity);
if (boxPartHit == null)
continue;
// Only closes hit
if (closestHit == -1 || boxPartHit.getDistanceTravelled() < closestHit) {
closestHit = boxPartHit.getDistanceTravelled();
hit = boxPartHit;
}
}
return hit;
}
use of me.deecaad.weaponmechanics.weapon.projectile.weaponprojectile.RayTraceResult 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.weaponprojectile.RayTraceResult in project MechanicsMain by WeaponMechanics.
the class RayTraceCommand method execute.
@Override
public void execute(CommandSender sender, String[] args) {
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "This command is only available for players.");
return;
}
Player player = (Player) sender;
boolean onlyHitPosition = args.length > 0 && Boolean.parseBoolean(args[0]);
int distance = (args.length > 1) ? Integer.parseInt(args[1]) : 5;
if (distance < 1) {
sender.sendMessage(ChatColor.RED + "Distance was less than 1");
return;
}
int time = (args.length > 2) ? Integer.parseInt(args[2]) : 200;
sender.sendMessage(ChatColor.GREEN + "Showing hitboxes in distance " + distance + " for " + time + " ticks");
IWeaponCompatibility weaponCompatibility = WeaponCompatibilityAPI.getWeaponCompatibility();
new BukkitRunnable() {
int ticker = 0;
@Override
public void run() {
Location location = player.getEyeLocation();
Vector direction = location.getDirection();
BlockIterator blocks = new BlockIterator(player.getWorld(), location.toVector(), direction, 0.0, distance);
while (blocks.hasNext()) {
Block block = blocks.next();
HitBox blockBox = weaponCompatibility.getHitBox(block);
if (blockBox == null)
continue;
RayTraceResult rayTraceResult = blockBox.rayTrace(location.toVector(), direction);
if (rayTraceResult == null)
continue;
if (onlyHitPosition) {
rayTraceResult.outlineOnlyHitPosition(player);
} else {
blockBox.outlineAllBoxes(player);
}
player.sendMessage("Block: " + block.getType());
break;
}
Collection<Entity> entities = player.getWorld().getNearbyEntities(location, distance, distance, distance);
if (!entities.isEmpty()) {
for (Entity entity : entities) {
if (!(entity instanceof LivingEntity) || entity.getEntityId() == player.getEntityId())
continue;
HitBox entityBox = weaponCompatibility.getHitBox(entity);
if (entityBox == null)
continue;
RayTraceResult rayTraceResult = entityBox.rayTrace(location.toVector(), direction);
if (rayTraceResult == null)
continue;
if (onlyHitPosition) {
rayTraceResult.outlineOnlyHitPosition(player);
} else {
entityBox.outlineAllBoxes(player);
}
player.sendMessage("Entity: " + entity.getType());
break;
}
}
if (++ticker >= time) {
cancel();
}
}
}.runTaskTimer(WeaponMechanics.getPlugin(), 0, 0);
}
Aggregations