Warning
Do note this continues on AFTER attributes, if you want to follow along start there!
Basic Steps
To start off let's make an ExampleItemInterface
public class ExampleItemInterface<T extends SmartAnimalBase> implements TravelersItemInterface<T> {private Supplier<Item> spawnEgg;private Supplier<Item> rawMeat;private Supplier<Item> cookedMeat;@Overridepublic void init(TravelersAnimalAttributes<T> travelersAnimalAttributes, TravelersAnimal<T> travelersAnimal) {var name = travelersAnimalAttributes.getAnimalName();rawMeat = ExampleItemRegistry.registerItem(name + "_raw", () -> new Item(new Item.Properties().food(new FoodProperties.Builder().build())));cookedMeat = ExampleItemRegistry.registerItem(name + "_cooked", () -> new Item(new Item.Properties().food(new FoodProperties.Builder().build())));}public Supplier<Item> getRawMeat() {return rawMeat;}public Supplier<Item> getCookedMeat() {return cookedMeat;}@Overridepublic void initSpawnEgg(TravelersAnimalAttributes<?> travelersAnimalAttributes, TravelersAnimal<?> travelersAnimal) {// This runs later because you NEED the entityType to be initialized first.spawnEgg = ExampleItemRegistry.registerItem(travelersAnimalAttributes.getAnimalName() + "_spawn_egg", () ->// Cast is needed because the entityType's class is unknownnew DeferredSpawnEggItem(() -> (EntityType<? extends Mob>)travelersAnimal.getEntityType().get(), 0, 0, new Item.Properties()));}public Supplier<Item> getSpawnEgg() {return spawnEgg;}@Overridepublic HashMap<ItemLike, DropObject> initDrops(TravelersItemInterface<T> travelersItemInterface, HashMap<ItemLike, DropObject> hashMap) {// Unused in this examplereturn null;}@Overridepublic @Nullable ItemStack getPickItem(SmartAnimalBase smartAnimalBase) {// The item the entity gets if you middle-click it.return spawnEgg.get().getDefaultInstance();}}
Besides this it isn't really that hard to understand, it's an simple class that helps with automatic registries.
Do note this uses an part of the registry guide.