Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class CustomEntityType<T extends EntityLiving> {
- @Nullable
- private static Field REGISTRY_MAT_MAP;
- static {
- try {
- REGISTRY_MAT_MAP = RegistryMaterials.class.getDeclaredField("c");
- } catch (ReflectiveOperationException err) {
- // Should only occur if REGISTRY_MAT_MAP field name changes
- REGISTRY_MAT_MAP = null;
- err.printStackTrace();
- }
- }
- private final MinecraftKey key;
- private final Class<T> clazz;
- private final EntityTypes.b<T> maker;
- private EntityTypes<? super T> parentType;
- private EntityTypes<T> entityType;
- private boolean registered;
- public CustomEntityType(String name, Class<T> customEntityClass, EntityTypes<? super T> parentType, EntityTypes.b<T> maker) {
- this.key = MinecraftKey.a(name);
- this.clazz = customEntityClass;
- this.parentType = parentType;
- this.maker = maker;
- }
- public boolean isRegistered() {
- return registered;
- }
- public org.bukkit.entity.Entity spawn(WorldServer server, Location loc) {
- Entity entity = entityType.spawnCreature(server,
- null, null, null, new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()),
- EnumMobSpawn.EVENT, true, false);
- return entity == null ? null : entity.getBukkitEntity();
- }
- public void register() throws IllegalStateException {
- if (registered || IRegistry.ENTITY_TYPE.getOptional(key).isPresent()) {
- // Throw exception if for some reason a registered custom entity is being registered again
- throw new IllegalStateException(String.format
- ("Unable to register entity with key '%s' as it is already registered.", key));
- return;
- }
- // Get name-datafixer mappings
- Map<Object, Type<?>> dataTypes = (Map<Object, Type<?>>)DataConverterRegistry.a()
- .getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion()))
- .findChoiceType(DataConverterTypes.ENTITY_TREE).types();
- // Map custom entity name to parent entity datafixer
- dataTypes.put(key.toString(), dataTypes.get(parentType.h().toString().replace("entity/", "")));
- EntityTypes.a<T> a = EntityTypes.a.a(maker, EnumCreatureType.CREATURE);
- entityType = a.a(key.getKey());
- // Map custom entity key to entity type in deep registry materials map
- IRegistry.a(IRegistry.ENTITY_TYPE, key.getKey(), entityType);
- registered = true; // boolean checker to prevent illegal registration states
- }
- @SuppressWarnings("unchecked") // Suppress warning on cast to registry material map
- public void unregister() throws IllegalStateException {
- if (!registered) {
- // Throw exception if for some reason an non-registered custom entity is being "unregistered"
- throw new IllegalArgumentException(String.format
- ("Entity with key '%s' could not be unregistered, as it is not in the registry", key));
- }
- // Remove the mapping for our custom entity type to a vanilla entity type
- Map<Object, Type<?>> dataTypes = (Map<Object, Type<?>>)DataConverterRegistry.a()
- .getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion()))
- .findChoiceType(DataConverterTypes.ENTITY_TREE).types();
- dataTypes.remove(key.toString());
- try {
- if (REGISTRY_MAT_MAP == null) {
- // Should only occur if REGISTRY_MAT_MAP's field name changes
- throw new ReflectiveOperationException("Field not initially found");
- }
- // Remove deep registry mapping for our custom entity's NamespacedKey
- REGISTRY_MAT_MAP.setAccessible(true);
- Object o = REGISTRY_MAT_MAP.get(IRegistry.ENTITY_TYPE);
- ((BiMap<MinecraftKey, ?>)o).remove(key);
- // Set the modified map
- REGISTRY_MAT_MAP.set(IRegistry.ENTITY_TYPE, o);
- REGISTRY_MAT_MAP.setAccessible(false);
- registered = false;
- } catch (ReflectiveOperationException err) {
- // Should only occur if REGISTRY_MAT_MAP's type changes
- err.printStackTrace();
- }
- }
- }
Add Comment
Please, Sign In to add comment