
Rewrite capability support in a way that's more easily supported by all loaders without duplicate code
BlayTheNinth opened this issue ยท 1 comments
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));
}
Implemented for 1.21.5 via #134