Skip to content

Attributes

AlexIIL edited this page Mar 28, 2019 · 1 revision

An "attribute" is just a class that has an instance of "alexiil.mc.lib.attributes.Attribute" stored in a public static final field.

A block can provide attribute instances by implementing AttributeProviderBlock and then offering instances like this:

public class MyBlock extends Block implements AttributeProviderBlock {
    @Override
    public void addAllAttributes(World world, BlockPos pos, BlockState state, AttributeList<?> to) {
        to.offer(an_attribute_instance);
    }
}

A block can request instances of a specific attribute by:

  1. Finding the appropriate public static final Attribute<> field.
    • This defines item attributes in "ItemAttributes", and fluid attributes in "FluidAttributes"
  2. Calling either "getAll", "getFirstOrNull", "getFirst", or "get" and passing in the appropriate world, position, and SearchOption.

For example a hopper-like block might call this:

/**
 * Finds an {@link ItemInsertable} in the given direction.
 *
 * @param world The world object to search within
 * @param thisPos The position to search from.
 * @param direction The direction to search in.
 * @return An {@link ItemInsertable} that we can attempt to insert into.
 */
public static ItemInsertable getNeighbourInsertable(World world, BlockPos thisPos, Direction direction) {

    BlockPos offsetPos = thisPos.offset(direction);

    // Note that the direction is always the direction of the search:
    // so it's always from the hopper to it's neighbour, and not the
    // side of the neighbour to search.
    SearchOption option = SearchOptions.inDirection(direction);

    // Note that this object will never be null - it will just return
    // a "rejecting" item insertable that never allows anything to be
    // inserted if there's no valid item insertable there. 
    return ItemAttributes.INSERTABLE.get(world, offsetPos, option);
}

You can create custom attributes by calling one of the create methods in Attributes. Note that attribute instances are never registered anywhere so you should store the attribute in a public static final Attribute<MyAttributeClass> field.

In addition there are three type of attribute:

  • Attribute: The base type, implies nothing about attribute instances but only provides the getAll() and getFirstOrNull() accessor methods.
  • DefaultedAttribute: This implies that it is always possible to have a default instance which can used safely everywhere that normal instances could be. This also provides the getFirst() accessor method.
  • CombinableAttribute: (extends DefaultedAttribute) This implies that it is always possible to combine multiple attribute instances and use them safely everywhere that normal instances can be. This provides the get() method which returns a combined version of getAll().

For example a custom attribute based around a fictional class RobotDockingPort (which could be used by buildcraft robots) would be defined like this:

public static final Attribute<RobotDockingPort> DOCKING_PORT = Attributes.create(RobotDockingPort.class);

Alternatively you can look inside FluidAttributes for an example involving combinable attributes.

Clone this wiki locally