001    package org.bukkit.entity;
002    
003    import java.util.HashMap;
004    import java.util.Map;
005    
006    import org.bukkit.inventory.ItemStack;
007    import org.bukkit.Location;
008    import org.bukkit.World;
009    
010    public enum EntityType {
011        // These strings MUST match the strings in nms.EntityTypes and are case sensitive.
012        /**
013         * An item resting on the ground.
014         *
015         * Spawn with {@link World#dropItem(Location, ItemStack)}
016         * or {@link World#dropItemNaturally(Location, ItemStack)}
017         */
018        DROPPED_ITEM("Item", Item.class, 1, false),
019        /**
020         * An experience orb.
021         */
022        EXPERIENCE_ORB("XPOrb", ExperienceOrb.class, 2),
023        /**
024         * A painting on a wall.
025         */
026        PAINTING("Painting", Painting.class, 9),
027        /**
028         * An arrow projectile; may get stuck in the ground.
029         */
030        ARROW("Arrow", Arrow.class, 10),
031        /**
032         * A flyinf snowball.
033         */
034        SNOWBALL("Snowball", Snowball.class, 11),
035        /**
036         * A flying large fireball, as thrown by a Ghast for example.
037         */
038        FIREBALL("Fireball", LargeFireball.class, 12),
039        /**
040         * A flying small fireball, such as thrown by a Blaze or player.
041         */
042        SMALL_FIREBALL("SmallFireball", SmallFireball.class, 13),
043        /**
044         * A flying ender pearl.
045         */
046        ENDER_PEARL("ThrownEnderpearl", EnderPearl.class, 14),
047        /**
048         * An ender eye signal.
049         */
050        ENDER_SIGNAL("EyeOfEnderSignal", EnderSignal.class, 15),
051        /**
052         * A flying experience bottle.
053         */
054        THROWN_EXP_BOTTLE("ThrownExpBottle", ThrownExpBottle.class, 17),
055        /**
056         * An item frame on a wall.
057         */
058        ITEM_FRAME("ItemFrame", ItemFrame.class, 18),
059        /**
060         * A flying wither skull projectile.
061         */
062        WITHER_SKULL("WitherSkull", WitherSkull.class, 19),
063        /**
064         * Primed TNT that is about to explode.
065         */
066        PRIMED_TNT("PrimedTnt", TNTPrimed.class, 20),
067        /**
068         * A block that is going to or is about to fall.
069         */
070        FALLING_BLOCK("FallingSand", FallingBlock.class, 21, false),
071        FIREWORK("FireworksRocketEntity", Firework.class, 22, false),
072        /**
073         * A placed minecart of any type.
074         */
075        MINECART("Minecart", Minecart.class, 40),
076        /**
077         * A placed boat.
078         */
079        BOAT("Boat", Boat.class, 41),
080        CREEPER("Creeper", Creeper.class, 50),
081        SKELETON("Skeleton", Skeleton.class, 51),
082        SPIDER("Spider", Spider.class, 52),
083        GIANT("Giant", Giant.class, 53),
084        ZOMBIE("Zombie", Zombie.class, 54),
085        SLIME("Slime", Slime.class, 55),
086        GHAST("Ghast", Ghast.class, 56),
087        PIG_ZOMBIE("PigZombie", PigZombie.class, 57),
088        ENDERMAN("Enderman", Enderman.class, 58),
089        CAVE_SPIDER("CaveSpider", CaveSpider.class, 59),
090        SILVERFISH("Silverfish", Silverfish.class, 60),
091        BLAZE("Blaze", Blaze.class, 61),
092        MAGMA_CUBE("LavaSlime", MagmaCube.class, 62),
093        ENDER_DRAGON("EnderDragon", EnderDragon.class, 63),
094        WITHER("WitherBoss", Wither.class, 64),
095        BAT("Bat", Bat.class, 65),
096        WITCH("Witch", Witch.class, 66),
097        PIG("Pig", Pig.class, 90),
098        SHEEP("Sheep", Sheep.class, 91),
099        COW("Cow", Cow.class, 92),
100        CHICKEN("Chicken", Chicken.class, 93),
101        SQUID("Squid", Squid.class, 94),
102        WOLF("Wolf", Wolf.class, 95),
103        MUSHROOM_COW("MushroomCow", MushroomCow.class, 96),
104        SNOWMAN("SnowMan", Snowman.class, 97),
105        OCELOT("Ozelot", Ocelot.class, 98),
106        IRON_GOLEM("VillagerGolem", IronGolem.class, 99),
107        VILLAGER("Villager", Villager.class, 120),
108        ENDER_CRYSTAL("EnderCrystal", EnderCrystal.class, 200),
109        // These don't have an entity ID in nms.EntityTypes.
110        /**
111         * A flying splash potion.
112         */
113        SPLASH_POTION(null, ThrownPotion.class, -1, false),
114        /**
115         * A flying chicken egg.
116         */
117        EGG(null, Egg.class, -1, false),
118        /**
119         * A fishing line and bobber.
120         */
121        FISHING_HOOK(null, Fish.class, -1, false),
122        /**
123         * A bolt of lightning.
124         *
125         * Spawn with {@link World#strikeLightning(Location)}.
126         */
127        LIGHTNING(null, LightningStrike.class, -1, false),
128        WEATHER(null, Weather.class, -1, false),
129        PLAYER(null, Player.class, -1, false),
130        COMPLEX_PART(null, ComplexEntityPart.class, -1, false),
131        /**
132         * An unknown entity without an Entity Class
133         */
134        UNKNOWN(null, null, -1, false);
135    
136        private String name;
137        private Class<? extends Entity> clazz;
138        private short typeId;
139        private boolean independent, living;
140    
141        private static final Map<String, EntityType> NAME_MAP = new HashMap<String, EntityType>();
142        private static final Map<Short, EntityType> ID_MAP = new HashMap<Short, EntityType>();
143    
144        static {
145            for (EntityType type : values()) {
146                if (type.name != null) {
147                    NAME_MAP.put(type.name.toLowerCase(), type);
148                }
149                if (type.typeId > 0) {
150                    ID_MAP.put(type.typeId, type);
151                }
152            }
153        }
154    
155        private EntityType(String name, Class<? extends Entity> clazz, int typeId) {
156            this(name, clazz, typeId, true);
157        }
158    
159        private EntityType(String name, Class<? extends Entity> clazz, int typeId, boolean independent) {
160            this.name = name;
161            this.clazz = clazz;
162            this.typeId = (short) typeId;
163            this.independent = independent;
164            if (clazz != null) {
165                this.living = LivingEntity.class.isAssignableFrom(clazz);
166            }
167        }
168    
169        public String getName() {
170            return name;
171        }
172    
173        public Class<? extends Entity> getEntityClass() {
174            return clazz;
175        }
176    
177        public short getTypeId() {
178            return typeId;
179        }
180    
181        public static EntityType fromName(String name) {
182            if (name == null) {
183                return null;
184            }
185            return NAME_MAP.get(name.toLowerCase());
186        }
187    
188        public static EntityType fromId(int id) {
189            if (id > Short.MAX_VALUE) {
190                return null;
191            }
192            return ID_MAP.get((short) id);
193        }
194    
195        /**
196         * Some entities cannot be spawned using {@link World#spawnEntity(Location, EntityType)}
197         * or {@link World#spawn(Location, Class)}, usually
198         * because they require additional information in order to spawn.
199         * @return False if the entity type cannot be spawned
200         */
201        public boolean isSpawnable() {
202            return independent;
203        }
204    
205        public boolean isAlive() {
206            return living;
207        }
208    }