/******************************************************************************* * Copyright 2014 Tobias Welther * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package de.tobiyas.racesandclasses.util.entitysearch; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Queue; import java.util.Set; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.util.BlockIterator; import de.tobiyas.util.math.Bresenham; public class SearchEntity { /** * Searches the first {@link LivingEntity} in the line of sight. * * @param maxDistance to search in * @param toSearchFrom to search from * * @return the Found entity or null if none found. */ @SuppressWarnings("unchecked") public static <T extends LivingEntity> T inLineOfSight(int maxDistance, LivingEntity toSearchFrom){ List<Entity> nearEntities = toSearchFrom.getNearbyEntities(maxDistance * 2, maxDistance * 2, maxDistance * 2); Iterator<Entity> entityIt = nearEntities.iterator(); while(entityIt.hasNext()){ Entity entityToCheck = entityIt.next(); boolean remove = false; if(!(entityToCheck instanceof LivingEntity)){ remove = true; } try{ @SuppressWarnings({ "unused" }) T t = (T) entityToCheck; //This is just a check if it is T type. }catch(ClassCastException exp){ remove = true; } if(remove){ entityIt.remove(); } } Iterator<Block> blockIt = new BlockIterator(toSearchFrom, maxDistance); while(blockIt.hasNext()){ Block block = blockIt.next(); for(Entity entity : nearEntities){ double distance = block.getLocation().distanceSquared(entity.getLocation()); if(distance < 2){ return (T) entity; } if(entity instanceof LivingEntity){ double distanceEye = block.getLocation().distanceSquared(((LivingEntity)entity).getEyeLocation()); if(distanceEye < 2){ return (T) entity; } } } } return null; } /** * Searches the first {@link LivingEntity} in the line of sight. * * @param maxDistance to search in * @param toSearchFrom to search from * * @return the Found entity or null if none found. */ public static LivingEntity inLineOfSight(int maxDistance, LivingEntity toSearchFrom, EntityType toSearch){ List<Entity> nearEntities = toSearchFrom.getNearbyEntities(maxDistance * 2, maxDistance * 2, maxDistance * 2); Iterator<Entity> entityIt = nearEntities.iterator(); while(entityIt.hasNext()){ Entity entityToCheck = entityIt.next(); boolean remove = false; if(!(entityToCheck instanceof LivingEntity)) remove = true; if(entityToCheck.getType() != toSearch) remove = true; if(remove) entityIt.remove(); } Iterator<Block> blockIt = new BlockIterator(toSearchFrom, maxDistance); while(blockIt.hasNext()){ Block block = blockIt.next(); for(Entity entity : nearEntities){ double distance = block.getLocation().distanceSquared(entity.getLocation()); if(distance < 2){ return (LivingEntity) entity; } double distanceEye = block.getLocation().distanceSquared(((LivingEntity)entity).getEyeLocation()); if(distanceEye < 2){ return (LivingEntity) entity; } } } return null; } /** * Searches the first {@link LivingEntity} in the line of sight. * * @param maxDistance to search in * @param toSearchFrom to search from * * @return the Found entity or null if none found. */ public static Set<LivingEntity> allInLineOfSight(int maxDistance, LivingEntity toSearchFrom){ List<Entity> nearEntities = toSearchFrom.getNearbyEntities(maxDistance * 2, maxDistance * 2, maxDistance * 2); Iterator<Entity> entityIt = nearEntities.iterator(); while(entityIt.hasNext()){ Entity entityToCheck = entityIt.next(); if(!(entityToCheck instanceof LivingEntity)) entityIt.remove(); } Set<LivingEntity> targets = new HashSet<LivingEntity>(); Iterator<Block> blockIt = new BlockIterator(toSearchFrom, maxDistance); int i = 0; while(blockIt.hasNext()){ Block block = blockIt.next(); for(Entity entity : nearEntities){ double distance = block.getLocation().distanceSquared(entity.getLocation()); if(distance <= 2){ targets.add((LivingEntity) entity); continue; } if(entity instanceof LivingEntity){ double distanceEye = block.getLocation().distanceSquared(((LivingEntity) entity).getEyeLocation()); if(distanceEye <= 2){ targets.add((LivingEntity) entity); continue; } } } //end. i++; if(i >= maxDistance) break; } return targets; } /** * Returns all Entities in the Range of the Entity. * * @param around * @param range * @return */ public static List<Entity> inCircleAround(Entity around, double range){ List<Entity> entities = around.getNearbyEntities(range, range, range); double rangeSpauare = range * range; Location base = around.getLocation(); Iterator<Entity> it = entities.iterator(); while(it.hasNext()){ if(it.next().getLocation().distanceSquared(base) > rangeSpauare) it.remove(); } return entities; } /** * Returns all Locations from Location 1 to location 2. * * @param loc1 * @param loc2 * * @return */ public static Queue<Location> getAllOnWay(Location loc1, Location loc2){ return Bresenham.line3D(loc1, loc2); } }