package com.bergerkiller.bukkit.common.utils; import java.util.EnumMap; import java.util.Locale; import org.bukkit.Material; import org.bukkit.entity.Animals; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.FallingBlock; import org.bukkit.entity.Ghast; import org.bukkit.entity.Golem; import org.bukkit.entity.Item; import org.bukkit.entity.Monster; import org.bukkit.entity.NPC; import org.bukkit.entity.Slime; import org.bukkit.entity.Squid; import com.bergerkiller.bukkit.common.collections.StringMapCaseInsensitive; /** * Contains entity naming and grouping functions to categorize entities */ public class EntityGroupingUtil { private static final StringMapCaseInsensitive<EntityCategory> entityCategories = new StringMapCaseInsensitive<EntityCategory>(); private static final EnumMap<EntityType, String> typeNames = new EnumMap<EntityType, String>(EntityType.class); private static final Class<?>[] ANIMAL_CLASSES = {Animals.class, Squid.class}; private static final Class<?>[] MONSTER_CLASSES = {Monster.class, Slime.class, Ghast.class, Golem.class}; static { // Note: These categories are ONLY used to map by name for (EntityType type : EntityType.values()) { // Obtain type name @SuppressWarnings("deprecation") String name = type.getName(); if (name == null) { Class<?> clazz = type.getEntityClass(); if (clazz == null) { name = "unknown"; } else { name = clazz.getSimpleName(); } } name = name.toLowerCase(Locale.ENGLISH); // Store it entityCategories.put(name, getCategory(type)); typeNames.put(type, name); } } public static EntityCategory getCategory(String name) { return LogicUtil.fixNull(entityCategories.get(name), EntityCategory.OTHER); } public static EntityCategory getCategory(EntityType type) { return getCategory(type.getEntityClass()); } public static EntityCategory getCategory(Class<? extends Entity> entityClass) { if (isAnimal(entityClass)) { return EntityCategory.ANIMAL; } else if (isMonster(entityClass)) { return EntityCategory.MONSTER; } else if (isNPC(entityClass)) { return EntityCategory.NPC; } else { return EntityCategory.OTHER; } } public static boolean isMob(String name) { return getCategory(name).isMob(); } public static boolean isNPC(String name) { return getCategory(name) == EntityCategory.NPC; } public static boolean isAnimal(String name) { return getCategory(name) == EntityCategory.ANIMAL; } public static boolean isMonster(String name) { return getCategory(name) == EntityCategory.MONSTER; } public static boolean isMob(Entity entity) { return entity != null && isMob(entity.getClass()); } public static boolean isMob(EntityType entityType) { return isMob(entityType.getEntityClass()); } public static boolean isMob(Class<? extends Entity> entityClass) { return isAnimal(entityClass) || isMonster(entityClass) || isNPC(entityClass); } public static boolean isNPC(Entity entity) { return entity != null && isNPC(entity.getClass()); } public static boolean isNPC(EntityType entityType) { return isNPC(entityType.getEntityClass()); } public static boolean isNPC(Class<? extends Entity> entityClass) { return entityClass != null && NPC.class.isAssignableFrom(entityClass); } public static boolean isAnimal(Entity entity) { return entity != null && isAnimal(entity.getClass()); } public static boolean isAnimal(EntityType entityType) { return isAnimal(entityType.getEntityClass()); } public static boolean isAnimal(Class<? extends Entity> entityClass) { if (entityClass == null) { return false; } for (Class<?> animalClass : ANIMAL_CLASSES) { if (animalClass.isAssignableFrom(entityClass)) { return true; } } return false; } public static boolean isMonster(Entity entity) { return entity != null && isMonster(entity.getClass()); } public static boolean isMonster(EntityType entityType) { return isMonster(entityType.getEntityClass()); } public static boolean isMonster(Class<? extends Entity> entityClass) { if (entityClass == null) { return false; } for (Class<?> monsterClass : MONSTER_CLASSES) { if (monsterClass.isAssignableFrom(entityClass)) { return true; } } return false; } /** * Gets the lower-cased name of a given Entity<br> * - Items will get the name 'item' with the item type appended to it<br> * - Falling blocks will get the name 'falling' with the block type appended to it * * @param entity to get the name of * @return Entity name */ public static String getName(Entity entity) { if (entity == null) { return ""; } else if (entity instanceof Item) { Material mat = ((Item) entity).getItemStack().getType(); if (mat == null || mat == Material.AIR) { return "item"; } else { return "item" + mat.toString().toLowerCase(Locale.ENGLISH); } } else if (entity instanceof FallingBlock) { Material mat = ((FallingBlock) entity).getMaterial(); if (mat == null || mat == Material.AIR) { return "fallingblock"; } else { return "falling" + mat.toString().toLowerCase(Locale.ENGLISH); } } else { return getName(entity.getType()); } } /** * Gets the lower-cased name of a given Entity Class * * @param entityClass to get the name of * @return Entity name */ public static String getName(Class<? extends Entity> entityClass) { if (entityClass == null) { return ""; } for (EntityType type : EntityType.values()) { Class<?> typeEntityClass = type.getEntityClass(); if (typeEntityClass != null && typeEntityClass.isAssignableFrom(entityClass)) { return getName(type); } } return entityClass.getSimpleName().toLowerCase(Locale.ENGLISH); } /** * Gets the lower-cased name of a given Entity Type * * @param type to get the name of * @return Entity Type name */ public static String getName(EntityType type) { return typeNames.get(type); } /** * Represents a certain category of entities */ public static enum EntityCategory { ANIMAL(true), MONSTER(true), NPC(true), OTHER(false); private final boolean isMob; private EntityCategory(boolean isMob) { this.isMob = isMob; } public boolean isMob() { return isMob; } } }