Search in sources :

Example 1 with IWeaponCompatibility

use of me.deecaad.weaponmechanics.compatibility.IWeaponCompatibility in project MechanicsMain by WeaponMechanics.

the class Ray method trace.

/**
 * Traces along this ray, colliding with block(s) and/or entity(s), depending on the given
 * <code>collision</code>.
 *
 * @param collision What the ray collides with
 * @param accuracy  The distance (in blocks) between checks
 * @param isShow    Useful for debugging. Spawns redstone particles that are removed after 1 minute
 * @return The collision data
 */
public TraceResult trace(@Nonnull TraceCollision collision, @Nonnegative double accuracy, boolean isShow) {
    IWeaponCompatibility factory = WeaponCompatibilityAPI.getWeaponCompatibility();
    // Store the entities between the starting and ending point of the ray. Map the
    // entities to their hit box. If this ray is too long, this method becomes
    // inefficient -- Ideally rays should be kept to 25 blocks max
    Map<Entity, HitBox> availableEntities = collision.isHitEntity() ? getEntities(collision) : Collections.emptyMap();
    // can hit, then we can take a shortcut and return an empty trace result, saving resources
    if (!collision.isHitBlock() && availableEntities.isEmpty()) {
        return new TraceResult(Collections.emptySet(), Collections.emptySet());
    }
    final LinkedHashSet<Block> blocks = new LinkedHashSet<>();
    final LinkedHashSet<Entity> entities = new LinkedHashSet<>();
    // Step is a number [0.0, 1.0] that defines a percentage of distance
    // between our starting and stopping point. If step exceeds 1, that
    // means the Ray is shorter than the accuracy allows.
    double step = accuracy / directionLength;
    if (step > 1.0) {
        return new TraceResult(entities, blocks);
    }
    // We start i at step to skip the first trace step. Doing this will
    // help prevent explosion rays from being blocks by minor floating
    // point differences. See issue #26.
    boolean collides = false;
    for (double i = step; i <= 1; i += step) {
        Vector point = VectorUtil.lerp(origin, end, i);
        Block block = world.getBlockAt(point.getBlockX(), point.getBlockY(), point.getBlockZ());
        // if this specific block can be hit, and if we actually collide with the block's hitbox
        if (collision.isHitBlock() && collision.canHit(block) && contains(factory.getHitBox(block), point)) {
            blocks.add(block);
            collides = true;
        }
        // entity's hitbox
        for (Map.Entry<Entity, HitBox> entry : availableEntities.entrySet()) {
            Entity entity = entry.getKey();
            HitBox hitbox = entry.getValue();
            if (collision.isHitEntity() && collision.canHit(entity) && contains(hitbox, point)) {
                entities.add(entity);
                collides = true;
                if (collision.isFirst()) {
                    break;
                }
            }
        }
        // once, then break out of the loop
        if (collides && collision.isFirst()) {
            break;
        }
        // particle for each point.
        if (isShow) {
            displayPoint(point, collides);
        }
        collides = false;
    }
    return new TraceResult(entities, blocks);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Entity(org.bukkit.entity.Entity) HitBox(me.deecaad.weaponmechanics.weapon.projectile.HitBox) IWeaponCompatibility(me.deecaad.weaponmechanics.compatibility.IWeaponCompatibility) Block(org.bukkit.block.Block) Vector(org.bukkit.util.Vector) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with IWeaponCompatibility

use of me.deecaad.weaponmechanics.compatibility.IWeaponCompatibility 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;
}
Also used : HitBox(me.deecaad.weaponmechanics.weapon.projectile.HitBox) Block(org.bukkit.block.Block) IWeaponCompatibility(me.deecaad.weaponmechanics.compatibility.IWeaponCompatibility)

Example 3 with IWeaponCompatibility

use of me.deecaad.weaponmechanics.compatibility.IWeaponCompatibility 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);
}
Also used : BlockIterator(org.bukkit.util.BlockIterator) Entity(org.bukkit.entity.Entity) LivingEntity(org.bukkit.entity.LivingEntity) Player(org.bukkit.entity.Player) HitBox(me.deecaad.weaponmechanics.weapon.projectile.HitBox) RayTraceResult(me.deecaad.weaponmechanics.weapon.projectile.weaponprojectile.RayTraceResult) BukkitRunnable(org.bukkit.scheduler.BukkitRunnable) IWeaponCompatibility(me.deecaad.weaponmechanics.compatibility.IWeaponCompatibility) LivingEntity(org.bukkit.entity.LivingEntity) Block(org.bukkit.block.Block) Collection(java.util.Collection) Vector(org.bukkit.util.Vector) Location(org.bukkit.Location)

Aggregations

IWeaponCompatibility (me.deecaad.weaponmechanics.compatibility.IWeaponCompatibility)3 HitBox (me.deecaad.weaponmechanics.weapon.projectile.HitBox)3 Block (org.bukkit.block.Block)3 Entity (org.bukkit.entity.Entity)2 Vector (org.bukkit.util.Vector)2 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 Map (java.util.Map)1 RayTraceResult (me.deecaad.weaponmechanics.weapon.projectile.weaponprojectile.RayTraceResult)1 Location (org.bukkit.Location)1 LivingEntity (org.bukkit.entity.LivingEntity)1 Player (org.bukkit.entity.Player)1 BukkitRunnable (org.bukkit.scheduler.BukkitRunnable)1 BlockIterator (org.bukkit.util.BlockIterator)1