Balm (Fabric Edition)

Balm (Fabric Edition)

27M Downloads

Rewrite capability support in a way that's more easily supported by all loaders without duplicate code

BlayTheNinth opened this issue ยท 1 comments

commented

Super messy right now since it requires lots of loader-specific code. It also doesn't help that NeoForge has no real fallback providers, meaning every Balm***Provider has to be registered manually.

e.g. Forge

public ForgeCookingForBlockheads(FMLJavaModLoadingContext context) {
    ForgeBalmProviders providers = (ForgeBalmProviders) Balm.getProviders();
    providers.register(KitchenItemProvider.class, new CapabilityToken<>() {
    });
    providers.register(KitchenItemProcessor.class, new CapabilityToken<>() {
    });
}

private void registerCapabilities(RegisterCapabilitiesEvent event) {
    event.register(KitchenItemProvider.class);
    event.register(KitchenItemProcessor.class);
}

Fabric

@Override
public void onInitialize() {
    registerProvider("kitchen_item_provider",
            KitchenItemProvider.class,
            ModBlockEntities.milkJar.get(),
            ModBlockEntities.cowJar.get(),
            ModBlockEntities.fridge.get(),
            ModBlockEntities.sink.get(),
            ModBlockEntities.cuttingBoard.get(),
            ModBlockEntities.counter.get(),
            ModBlockEntities.cabinet.get(),
            ModBlockEntities.fruitBasket.get(),
            ModBlockEntities.spiceRack.get());

    registerProvider("kitchen_item_processor", KitchenItemProcessor.class, ModBlockEntities.oven.get());

    registerLookup(ResourceLocation.fromNamespaceAndPath("balm", "fluid_tank"), FluidTank.class,
            ModBlockEntities.sink.get(), ModBlockEntities.milkJar.get(), ModBlockEntities.cowJar.get());

    var itemProviderLookup = BlockApiLookup.get(ResourceLocation.fromNamespaceAndPath(CookingForBlockheads.MOD_ID, "kitchen_item_provider"),
            KitchenItemProvider.class,
            Void.class);
    itemProviderLookup.registerFallback((level, pos, state, blockEntity, context) -> {
        if (state.is(ModBlockTags.KITCHEN_ITEM_PROVIDERS)) {
            if (blockEntity instanceof Container container) {
                return new ContainerKitchenItemProvider(container);
            } else if (blockEntity instanceof BalmContainerProvider containerProvider) {
                return new ContainerKitchenItemProvider(containerProvider.getContainer());
            }
        }
        return null;
    });
}

private <T> void registerProvider(String name, Class<T> clazz, BlockEntityType<?>... blockEntities) {
    var providers = ((FabricBalmProviders) Balm.getProviders());
    ResourceLocation identifier = ResourceLocation.fromNamespaceAndPath(CookingForBlockheads.MOD_ID, name);
    providers.registerProvider(identifier, clazz);
    registerLookup(identifier, clazz, blockEntities);
}

private <T> void registerLookup(ResourceLocation identifier, Class<T> clazz, BlockEntityType<?>... blockEntities) {
    var lookup = BlockApiLookup.get(identifier, clazz, Void.class);
    lookup.registerForBlockEntities((blockEntity, context) -> ((BalmBlockEntity) blockEntity).getProvider(clazz), blockEntities);
}

NeoForge

 private static final BlockCapability<KitchenItemProvider, Void> KITCHEN_ITEM_PROVIDER = BlockCapability.createVoid(ResourceLocation.fromNamespaceAndPath(
            CookingForBlockheads.MOD_ID,
            "kitchen_item_provider"), KitchenItemProvider.class);
private static final BlockCapability<KitchenItemProcessor, Void> KITCHEN_ITEM_PROCESSOR = BlockCapability.createVoid(ResourceLocation.fromNamespaceAndPath(
            CookingForBlockheads.MOD_ID,
            "kitchen_item_processor"), KitchenItemProcessor.class);

public NeoForgeCookingForBlockheads(IEventBus eventBus) {
    final var providers = ((NeoForgeBalmProviders) Balm.getProviders());
    providers.registerBlockProvider(KitchenItemProvider.class, KITCHEN_ITEM_PROVIDER);
    providers.registerBlockProvider(KitchenItemProcessor.class, KITCHEN_ITEM_PROCESSOR);
}

private void registerCapabilities(RegisterCapabilitiesEvent event) {
    event.registerBlockEntity(KITCHEN_ITEM_PROVIDER,
            ModBlockEntities.milkJar.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProvider.class));
    event.registerBlockEntity(KITCHEN_ITEM_PROVIDER,
            ModBlockEntities.cowJar.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProvider.class));
    event.registerBlockEntity(KITCHEN_ITEM_PROVIDER,
            ModBlockEntities.fridge.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProvider.class));
    event.registerBlockEntity(KITCHEN_ITEM_PROVIDER,
            ModBlockEntities.sink.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProvider.class));
    event.registerBlockEntity(KITCHEN_ITEM_PROVIDER,
            ModBlockEntities.fruitBasket.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProvider.class));
    event.registerBlockEntity(KITCHEN_ITEM_PROVIDER,
            ModBlockEntities.spiceRack.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProvider.class));
    event.registerBlockEntity(KITCHEN_ITEM_PROVIDER,
            ModBlockEntities.cabinet.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProvider.class));
    event.registerBlockEntity(KITCHEN_ITEM_PROVIDER,
            ModBlockEntities.counter.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProvider.class));
    event.registerBlockEntity(Capabilities.ItemHandler.BLOCK,
            ModBlockEntities.counter.get(),
            (blockEntity, context) -> new InvWrapper(blockEntity.getContainer()));
    event.registerBlockEntity(Capabilities.ItemHandler.BLOCK,
            ModBlockEntities.cabinet.get(),
            (blockEntity, context) -> new InvWrapper(blockEntity.getContainer()));
    event.registerBlockEntity(Capabilities.ItemHandler.BLOCK,
            ModBlockEntities.oven.get(),
            (blockEntity, context) -> new InvWrapper(blockEntity.getContainer()));
    event.registerBlockEntity(Capabilities.ItemHandler.BLOCK,
            ModBlockEntities.fridge.get(),
            (blockEntity, context) -> new InvWrapper(blockEntity.getContainer()));
    event.registerBlockEntity(Capabilities.FluidHandler.BLOCK,
            ModBlockEntities.sink.get(),
            (blockEntity, context) -> new NeoForgeFluidTank(blockEntity.getFluidTank()));
    event.registerBlockEntity(Capabilities.FluidHandler.BLOCK,
            ModBlockEntities.milkJar.get(),
            (blockEntity, context) -> new NeoForgeFluidTank(blockEntity.getFluidTank()));
    event.registerBlockEntity(Capabilities.FluidHandler.BLOCK,
            ModBlockEntities.cowJar.get(),
            (blockEntity, context) -> new NeoForgeFluidTank(blockEntity.getFluidTank()));
    event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK,
            ModBlockEntities.oven.get(),
            (blockEntity, context) -> new NeoForgeEnergyStorage(blockEntity.getEnergyStorage()));
    event.registerBlockEntity(KITCHEN_ITEM_PROVIDER,
            ModBlockEntities.cuttingBoard.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProvider.class));

    event.registerBlockEntity(KITCHEN_ITEM_PROCESSOR,
            ModBlockEntities.oven.get(),
            (blockEntity, context) -> blockEntity.getProvider(KitchenItemProcessor.class));
}
commented

Implemented for 1.21.5 via #134