/* * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT). * * Copyright (c) JCThePants (www.jcwhatever.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.jcwhatever.nucleus.utils.entity; import com.google.common.collect.Multimap; import com.google.common.collect.MultimapBuilder; import com.jcwhatever.nucleus.utils.PreCon; import org.bukkit.entity.EntityType; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * Utility to filter and identify {@link org.bukkit.entity.EntityType}'s by * property. */ public class EntityTypes { private EntityTypes() {} private static Multimap<EntityType, EntityTypeProperty> _properties = MultimapBuilder.enumKeys(EntityType.class).hashSetValues().build(); private static Multimap<EntityTypeProperty, EntityType> _typeByProperty = MultimapBuilder.hashKeys().enumSetValues(EntityType.class).build(); /** * Determine if an entity type has a property. * * @param type The {@link org.bukkit.entity.EntityType} to check. * @param propertyName The name of the property to check. */ public static boolean hasProperty(EntityType type, String propertyName) { PreCon.notNull(type); PreCon.notNull(propertyName); return hasProperty(type, EntityTypeProperty.forLookup(propertyName)); } /** * Determine if an entity type has a property. * * @param type The {@link org.bukkit.entity.EntityType} to check. * @param property The {@link EntityTypeProperty} to check. */ public static boolean hasProperty(EntityType type, EntityTypeProperty property) { PreCon.notNull(type); PreCon.notNull(property); return _properties.get(type).contains(property); } /** * Get all {@link org.bukkit.entity.EntityType}'s that match the specified properties. * * @param properties The {@link EntityTypeProperty}'s to check for. */ public static Set<EntityType> get(EntityTypeProperty... properties) { PreCon.notNull(properties); Set<EntityType> results = EnumSet.noneOf(EntityType.class); for (EntityTypeProperty property : properties) { Collection<EntityType> stored = _typeByProperty.get(property); Iterator<EntityType> iterator = results.iterator(); while (iterator.hasNext()) { EntityType type = iterator.next(); if (!stored.contains(type)) iterator.remove(); } results.addAll(stored); } return results; } /** * Get all {@link EntityTypeProperty}'s of the specified {@link org.bukkit.entity.EntityType}. * * @param type The entity type to check. */ public static Set<EntityTypeProperty> getProperties(EntityType type) { PreCon.notNull(type); Collection<EntityTypeProperty> stored = _properties.get(type); return new HashSet<>(stored); } /** * Removes {@link org.bukkit.entity.EntityType}'s from the provided * {@link java.util.Collection} that have the specified {@link EntityTypeProperty}'s. * * <p>Requires the provided collections iterator to implement the remove method.</p> * * @param types The collection of entity types to modify. * @param properties The properties to remove from the collection. */ public static void remove(Collection<EntityType> types, EntityTypeProperty... properties) { PreCon.notNull(types); PreCon.notNull(properties); Iterator<EntityType> iterator = types.iterator(); while (iterator.hasNext()) { EntityType type = iterator.next(); for (EntityTypeProperty property : properties) { if (hasProperty(type, property)) { iterator.remove(); break; } } } } /** * Determine if the entity type can fly. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#FLY */ public static boolean canFly(EntityType type) { return hasProperty(type, EntityTypeProperty.FLY); } /** * Determine if the entity type can walk. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#WALK */ public static boolean canWalk(EntityType type) { return hasProperty(type, EntityTypeProperty.WALK); } /** * Determine if the entity type can swim. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#SWIM */ public static boolean canSwim(EntityType type) { return hasProperty(type, EntityTypeProperty.SWIM); } /** * Determine if the entity type can climb. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#CLIMB */ public static boolean canClimb(EntityType type) { return hasProperty(type, EntityTypeProperty.CLIMB); } /** * Determine if the entity type can be ridden by players. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#RIDE */ public static boolean canRide(EntityType type) { return hasProperty(type, EntityTypeProperty.RIDE); } /** * Determine if the entity type can have a saddle attached. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#SADDLE */ public static boolean canSaddle(EntityType type) { return hasProperty(type, EntityTypeProperty.SADDLE); } /** * Determine if the entity type can shoot projectiles. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#SHOOT */ public static boolean canShoot(EntityType type) { return hasProperty(type, EntityTypeProperty.SHOOT); } /** * Determine if the entity type can teleport itself. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#TELEPORT */ public static boolean canTeleport(EntityType type) { return hasProperty(type, EntityTypeProperty.TELEPORT); } /** * Determine if the entity type can explode. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#EXPLODE */ public static boolean canExplode(EntityType type) { return hasProperty(type, EntityTypeProperty.EXPLODE); } /** * Determine if the entity type is alive. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#ALIVE */ public static boolean isAlive(EntityType type) { return hasProperty(type, EntityTypeProperty.ALIVE); } /** * Determine if the entity type is always hostile towards players. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#HOSTILE */ public static boolean isHostile(EntityType type) { return hasProperty(type, EntityTypeProperty.HOSTILE); } /** * Determine if the entity type is hostile when aggravated by * a player action. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#HOSTILE_AGRO */ public static boolean isHostileAgro(EntityType type) { return hasProperty(type, EntityTypeProperty.HOSTILE_AGRO); } /** * Determine if the entity type is a projectile. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#PROJECTILE */ public static boolean isProjectile(EntityType type) { return hasProperty(type, EntityTypeProperty.PROJECTILE); } /** * Determine if the entity type is a boss. * * @param type The {@link org.bukkit.entity.EntityType} to check. * * @see EntityTypeProperty#BOSS */ public static boolean isBoss(EntityType type) { return hasProperty(type, EntityTypeProperty.BOSS); } /** * Determine if the entity type is an animal. * * @param type The {@link org.bukkit.entity.EntityType} to check. * @see EntityTypeProperty#ANIMAL */ public static boolean isAnimal(EntityType type) { return hasProperty(type, EntityTypeProperty.ANIMAL); } /** * Determine if the entity type is a monster. * * @param type The {@link org.bukkit.entity.EntityType} to check. * @see EntityTypeProperty#MONSTER */ public static boolean isMonster(EntityType type) { return hasProperty(type, EntityTypeProperty.MONSTER); } /** * Register custom {@link EntityTypeProperty}'s for the specified * {@link org.bukkit.entity.EntityType}. * * @param type The {@link org.bukkit.entity.EntityType}. * @param properties The {@link EntityTypeProperty}'s to register. */ public static void register(EntityType type, EntityTypeProperty... properties) { PreCon.notNull(type); if (properties == null || properties.length == 0) return; // make sure a default property type is not being registered. for (EntityTypeProperty property : properties) { if (property.isDefaultProperty()) { throw new IllegalArgumentException("Cannot register a default property type."); } } add(type, properties); } private static void add(EntityType type, EntityTypeProperty... properties) { _properties.putAll(type, Arrays.asList(properties)); for (EntityTypeProperty property : properties) { _typeByProperty.put(property, type); } } static { add(EntityType.AREA_EFFECT_CLOUD); add(EntityType.ARMOR_STAND); add(EntityType.ARROW, EntityTypeProperty.PROJECTILE); add(EntityType.BAT, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.FLY); add(EntityType.BLAZE, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.FLY, EntityTypeProperty.SHOOT); add(EntityType.BOAT, EntityTypeProperty.SWIM); add(EntityType.CAVE_SPIDER, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.CLIMB, EntityTypeProperty.WALK); add(EntityType.CHICKEN, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.WALK); add(EntityType.COMPLEX_PART); add(EntityType.COW, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.WALK); add(EntityType.CREEPER, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.EXPLODE, EntityTypeProperty.WALK); add(EntityType.DRAGON_FIREBALL, EntityTypeProperty.PROJECTILE); add(EntityType.DROPPED_ITEM); add(EntityType.EGG, EntityTypeProperty.PROJECTILE); add(EntityType.ENDER_CRYSTAL); add(EntityType.ENDER_DRAGON, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.FLY, EntityTypeProperty.BOSS); add(EntityType.ENDER_PEARL, EntityTypeProperty.PROJECTILE); add(EntityType.ENDER_SIGNAL); add(EntityType.ENDERMAN, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE_AGRO, EntityTypeProperty.TELEPORT, EntityTypeProperty.WALK); add(EntityType.EXPERIENCE_ORB); add(EntityType.FALLING_BLOCK); add(EntityType.FIREBALL, EntityTypeProperty.PROJECTILE); add(EntityType.FIREWORK, EntityTypeProperty.PROJECTILE); add(EntityType.FISHING_HOOK); add(EntityType.GHAST, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.FLY, EntityTypeProperty.SHOOT); add(EntityType.GIANT, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.WALK); add(EntityType.GUARDIAN, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.SWIM); add(EntityType.HORSE, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.RIDE, EntityTypeProperty.SADDLE, EntityTypeProperty.WALK); add(EntityType.IRON_GOLEM, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE_AGRO, EntityTypeProperty.WALK); add(EntityType.ITEM_FRAME); add(EntityType.LEASH_HITCH); add(EntityType.LIGHTNING, EntityTypeProperty.PROJECTILE); add(EntityType.MAGMA_CUBE, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.WALK); add(EntityType.MINECART, EntityTypeProperty.RIDE); add(EntityType.MINECART_CHEST); add(EntityType.MINECART_FURNACE); add(EntityType.MINECART_HOPPER); add(EntityType.MINECART_MOB_SPAWNER); add(EntityType.MINECART_TNT); add(EntityType.MUSHROOM_COW, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.WALK); add(EntityType.OCELOT, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.WALK); add(EntityType.PAINTING); add(EntityType.PIG, EntityTypeProperty.ANIMAL, EntityTypeProperty.RIDE, EntityTypeProperty.SADDLE, EntityTypeProperty.WALK); add(EntityType.PIG_ZOMBIE, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE_AGRO, EntityTypeProperty.WALK); add(EntityType.PLAYER); add(EntityType.PRIMED_TNT, EntityTypeProperty.EXPLODE); add(EntityType.RABBIT, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.WALK); add(EntityType.SHEEP, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.WALK); add(EntityType.SHULKER, EntityTypeProperty.ALIVE, EntityTypeProperty.MONSTER, EntityTypeProperty.SHOOT, EntityTypeProperty.HOSTILE); add(EntityType.SHULKER_BULLET, EntityTypeProperty.PROJECTILE); add(EntityType.SILVERFISH, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.WALK); add(EntityType.SKELETON, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.SHOOT, EntityTypeProperty.WALK); add(EntityType.SLIME, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.WALK); add(EntityType.SMALL_FIREBALL, EntityTypeProperty.PROJECTILE); add(EntityType.SNOWBALL, EntityTypeProperty.PROJECTILE); add(EntityType.SNOWMAN, EntityTypeProperty.ALIVE, EntityTypeProperty.WALK); add(EntityType.SPECTRAL_ARROW, EntityTypeProperty.PROJECTILE); add(EntityType.SPIDER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.MONSTER, EntityTypeProperty.CLIMB, EntityTypeProperty.WALK); add(EntityType.SPLASH_POTION, EntityTypeProperty.PROJECTILE); add(EntityType.SQUID, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.SWIM); add(EntityType.THROWN_EXP_BOTTLE, EntityTypeProperty.PROJECTILE); add(EntityType.TIPPED_ARROW, EntityTypeProperty.PROJECTILE); add(EntityType.UNKNOWN); add(EntityType.VILLAGER, EntityTypeProperty.ALIVE, EntityTypeProperty.WALK); add(EntityType.WEATHER); add(EntityType.WITCH, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.SHOOT, EntityTypeProperty.WALK); add(EntityType.WITHER, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.SHOOT, EntityTypeProperty.FLY, EntityTypeProperty.BOSS); add(EntityType.WITHER_SKULL, EntityTypeProperty.PROJECTILE); add(EntityType.WOLF, EntityTypeProperty.ANIMAL, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE_AGRO, EntityTypeProperty.WALK); add(EntityType.ZOMBIE, EntityTypeProperty.MONSTER, EntityTypeProperty.ALIVE, EntityTypeProperty.HOSTILE, EntityTypeProperty.WALK); } }