Advertisement
Escad

1.15 entity registration

Feb 6th, 2020
839
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. public class CustomEntityType<T extends EntityLiving> {
  2.  
  3.     @Nullable private static Field REGISTRY_MAT_MAP;
  4.    
  5.     static {
  6.         try {
  7.             REGISTRY_MAT_MAP = RegistryMaterials.class.getDeclaredField("c");
  8.         } catch (ReflectiveOperationException err) {
  9.             err.printStackTrace();
  10.             REGISTRY_MAT_MAP = null;
  11.             // technically should only occur if server version changes or jar is modified in "weird" ways
  12.         }
  13.     }
  14.  
  15.     private final MinecraftKey key;
  16.     private final Class<T> clazz;
  17.     private final EntityTypes.b<T> maker;
  18.     private EntityTypes<? super T> parentType;
  19.     private EntityTypes<T> entityType;
  20.     private boolean registered;
  21.  
  22.     public CustomEntityType(String name, Class<T> customEntityClass, EntityTypes<? super T> parentType, EntityTypes.b<T> maker) {
  23.         this.key = MinecraftKey.a(name); // returns null if 256+ chars, non-alphanumeric, or contains uppercase chars
  24.         this.clazz = customEntityClass;
  25.         this.parentType = parentType;
  26.         this.maker = maker;
  27.     }
  28.  
  29.     public org.bukkit.entity.Entity spawn(Location loc) {
  30.         // Parameters: nmsWorld, initialNBT, customName, spawningPlayer, blockPos, spawnReason, fixPos, flag1(?)
  31.         Entity entity = entityType.spawnCreature(((CraftWorld)loc.getWorld()).getHandle(),
  32.                 null, null, null, new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()),
  33.                 EnumMobSpawn.EVENT, true, false);
  34.         return entity == null ? null : entity.getBukkitEntity();
  35.     }
  36.  
  37.     public void register() throws IllegalStateException {
  38.         if (registered || IRegistry.ENTITY_TYPE.getOptional(key).isPresent()) {
  39.             throw new IllegalStateException(String.format
  40.                     ("Unable to register entity with key '%s' as it is already registered.", key));
  41.         }
  42.         // Add custom entity to data fixers map with parent entity's data fixer
  43.         Map<Object, Type<?>> dataTypes = (Map<Object, Type<?>>)DataConverterRegistry.a()
  44.                 .getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion()))
  45.                 .findChoiceType(DataConverterTypes.ENTITY_TREE).types(); // DataConverterTypes.ENTITY in < 1.15.2
  46.         dataTypes.put(key.toString(), dataTypes.get(parentType.h().toString().replace("entity/", "")));
  47.         // Add our custom entity to the entity registry map
  48.         EntityTypes.a<T> a = EntityTypes.a.a(maker, EnumCreatureType.CREATURE);
  49.         entityType = a.a(key.getKey());
  50.         IRegistry.a(IRegistry.ENTITY_TYPE, key.getKey(), entityType);
  51.         registered = true;
  52.     }
  53.  
  54.     @SuppressWarnings("unchecked")
  55.     public void unregister() throws IllegalStateException {
  56.         if (!registered) {
  57.                 throw new IllegalArgumentException(String.format
  58.                         ("Entity with key '%s' could not be unregistered, as it is not in the registry", key));
  59.         }
  60.         // Remove custom entity from data fixers map
  61.         Map<Object, Type<?>> dataTypes = (Map<Object, Type<?>>)DataConverterRegistry.a()
  62.                 .getSchema(DataFixUtils.makeKey(SharedConstants.getGameVersion().getWorldVersion()))
  63.                 .findChoiceType(DataConverterTypes.ENTITY_TREE).types();
  64.         dataTypes.remove(key.toString());
  65.         try {
  66.             // Remove our custom entity from entity registry map, which takes a little reflection in 1.15
  67.             if (REGISTRY_MAT_MAP == null) {
  68.                 throw new ReflectiveOperationException("Field not initially found");
  69.             }
  70.             REGISTRY_MAT_MAP.setAccessible(true);
  71.             Object o = REGISTRY_MAT_MAP.get(IRegistry.ENTITY_TYPE);
  72.             ((BiMap<MinecraftKey, ?>)o).remove(key);
  73.             REGISTRY_MAT_MAP.set(IRegistry.ENTITY_TYPE, o);
  74.             REGISTRY_MAT_MAP.setAccessible(false);
  75.             registered = false;
  76.         } catch (ReflectiveOperationException err) {
  77.             err.printStackTrace();
  78.         }
  79.     }
  80.  
  81. }
Advertisement
RAW Paste Data Copied
Advertisement