Interface EntityApiLookup<A,C>

Type Parameters:
A - the type of the API we want to query.
C - the type of the additional context object. Completely arbitrary. If no context is necessary, Void should be used and null instances should be passed.

@NonExtendable public interface EntityApiLookup<A,C>
An object that allows retrieving APIs from entities. Instances of this interface can be obtained through get(net.minecraft.util.Identifier, java.lang.Class<A>, java.lang.Class<C>)

When trying to find(net.minecraft.entity.Entity, C) an API for an entity, the provider registered for the entity type will be queried if it exists. If it doesn't exist, or if it returns null, the fallback providers will be queried in order.

Usage Example

Let's pretend that we have the following interface that we want to attach to entities.

 public interface Leveled {
     int getLevel();
 }
 

We need to create the EntityApiLookup. We don't need any context so we use Void.


 public class MyApi {
     public static final EntityApiLookup<Leveled, Void> LEVELED_ENTITY = EntityApiLookup.get(new Identifier("mymod:leveled_entity"), Leveled.class, Void.class);
 }
 

Now we can query instances of Leveled.


 Leveled leveled = MyApi.LEVELED_ENTITY.find(entity, null);
 if (leveled != null) {
     // Do something with the API.
     System.out.println("Entity " + entity.getEntityName() + " is level " + leveled.getLevel());
 }
 

For query to return useful result, we must expose the API.


 // If the entity directly implements the interface, registerSelf can be used.
 public class LeveledPigEntity extends PigEntity implements Leveled {
     ...
 }
 MyApi.LEVELED_ENTITY.registerSelf(LEVELED_PIG_ENTITY_TYPE);

 // Otherwise, registerForType can be used.
 MyApi.LEVELED_ENTITY.registerForType((zombieEntity, ignored) -> {
     // Return a Leveled instance for your entity here, or null if there's none.
     // The context is Void in this case, so it can be ignored.
 }, EntityType.ZOMBIE);

 // Generic fallback, to interface with anything, for example if we want to all other entity level defaults to 1.
 MyApi.LEVELED_ENTITY.registerFallback((entity, ignored) -> {
     // Return something if available, or null otherwise.
 });
 
  • Method Details

    • get

      static <A, C> EntityApiLookup<A,C> get(Identifier lookupId, Class<A> apiClass, Class<C> contextClass)
      Retrieve the EntityApiLookup associated with an identifier, or create it if it didn't exist yet.
      Parameters:
      lookupId - the unique identifier of the lookup.
      apiClass - the class of the API.
      contextClass - the class of the additional context.
      Returns:
      the unique lookup with the passed lookupId.
      Throws:
      IllegalArgumentException - If another apiClass or another contextClass was already registered with the same identifier.
    • find

      @Nullable A find(Entity entity, C context)
      Attempt to retrieve an API from an entity.
      Parameters:
      entity - the entity.
      context - additional context for the query, defined by type parameter C.
      Returns:
      The retrieved API, or null if no API was found.
    • registerSelf

      void registerSelf(EntityType<?>... entityTypes)
      Expose the API for the passed entities that directly implements it.

      Implementation note: this is checked once after the first server started event fired by creating entity instances using the types.

      Parameters:
      entityTypes - the entity types for which the API are exposed to.
      Throws:
      IllegalArgumentException - if the entity is not an instance of the API class.
    • registerForType

      default <T extends Entity> void registerForType(BiFunction<T,C,@Nullable A> provider, EntityType<T> entityType)
      Expose the API for instances of the entity type. This overload allows using the correct entity class directly.
      Type Parameters:
      T - the entity class for which the API is exposed to
      Parameters:
      provider - the provider: returns an API if it's available in the entity with specified context, or null otherwise.
      entityType - the entity type.
    • registerForTypes

      void registerForTypes(EntityApiLookup.EntityApiProvider<A,C> provider, EntityType<?>... entityTypes)
      Expose the API for instances of the entity types. This overload allows for registering multiple entity types at once, but due to how generics work in java, the provider has to cast to the correct type if necessary.
      Parameters:
      provider - the provider.
      entityTypes - the entity types for which the API are exposed to.
    • registerFallback

      void registerFallback(EntityApiLookup.EntityApiProvider<A,C> fallbackProvider)
      Expose the API for all queries: the provider will be invoked if no object was found using the entity providers. May have big performance impact on all queries, use cautiously.
    • getId

      Identifier getId()
      Return the identifier of this lookup.
    • apiClass

      Class<A> apiClass()
      Returns the API class of this lookup.
    • contextClass

      Class<C> contextClass()
      Returns the context class of this lookup.
    • getProvider

      @Nullable @Nullable EntityApiLookup.EntityApiProvider<A,C> getProvider(EntityType<?> entityType)
      Returns the provider for the passed entity type (registered with one of the register functions), or null if none was registered (yet). Queries should go through find(net.minecraft.entity.Entity, C), only use this to inspect registered providers!