Skip to content

Commit

Permalink
Partial refactor for NeoForge capability rework
Browse files Browse the repository at this point in the history
- use NeoForge data attachments for internal data components
- move capability/component IDs to individual interfaces/component classes, so they can be shared between Fabric and NeoForge
(probably not complete)
  • Loading branch information
TheRealWormbo committed Sep 5, 2024
1 parent 97f60d5 commit 30d5475
Show file tree
Hide file tree
Showing 29 changed files with 282 additions and 174 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import net.fabricmc.fabric.api.lookup.v1.block.BlockApiLookup;
import net.fabricmc.fabric.api.lookup.v1.item.ItemApiLookup;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Unit;

import vazkii.botania.api.block.ExoflameHeatable;
Expand All @@ -21,23 +20,33 @@
import vazkii.botania.api.mana.spark.SparkAttachable;

public final class BotaniaFabricCapabilities {
public static final ItemApiLookup<AvatarWieldable, Unit> AVATAR_WIELDABLE = ItemApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "avatar_wieldable"), AvatarWieldable.class, Unit.class);
public static final ItemApiLookup<BlockProvider, Unit> BLOCK_PROVIDER = ItemApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "block_provider"), BlockProvider.class, Unit.class);
public static final ItemApiLookup<CoordBoundItem, Unit> COORD_BOUND_ITEM = ItemApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "coord_bound_item"),
CoordBoundItem.class, Unit.class);
public static final ItemApiLookup<ManaItem, Unit> MANA_ITEM = ItemApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "mana_item"),
ManaItem.class, Unit.class);
public static final ItemApiLookup<Relic, Unit> RELIC = ItemApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "relic"),
Relic.class, Unit.class);
public static final ItemApiLookup<AvatarWieldable, Unit> AVATAR_WIELDABLE =
ItemApiLookup.get(AvatarWieldable.ID, AvatarWieldable.class, Unit.class);
public static final ItemApiLookup<BlockProvider, Unit> BLOCK_PROVIDER =
ItemApiLookup.get(BlockProvider.ID, BlockProvider.class, Unit.class);
public static final ItemApiLookup<CoordBoundItem, Unit> COORD_BOUND_ITEM =
ItemApiLookup.get(CoordBoundItem.ID, CoordBoundItem.class, Unit.class);
public static final ItemApiLookup<ManaItem, Unit> MANA_ITEM =
ItemApiLookup.get(ManaItem.ID, ManaItem.class, Unit.class);
public static final ItemApiLookup<Relic, Unit> RELIC =
ItemApiLookup.get(Relic.ID, Relic.class, Unit.class);

public static final BlockApiLookup<ExoflameHeatable, Unit> EXOFLAME_HEATABLE = BlockApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "exoflame_heatable"), ExoflameHeatable.class, Unit.class);
public static final BlockApiLookup<HornHarvestable, Unit> HORN_HARVEST = BlockApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "horn_harvestable"), HornHarvestable.class, Unit.class);
public static final BlockApiLookup<HourglassTrigger, Unit> HOURGLASS_TRIGGER = BlockApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "hourglass_trigger"), HourglassTrigger.class, Unit.class);
public static final BlockApiLookup<ManaCollisionGhost, Unit> MANA_GHOST = BlockApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "mana_ghost"), ManaCollisionGhost.class, Unit.class);
public static final BlockApiLookup<ManaReceiver, /* @Nullable */ Direction> MANA_RECEIVER = BlockApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "mana_receiver"), ManaReceiver.class, Direction.class);
public static final BlockApiLookup<SparkAttachable, Direction> SPARK_ATTACHABLE = BlockApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "spark_attachable"), SparkAttachable.class, Direction.class);
public static final BlockApiLookup<ManaTrigger, Unit> MANA_TRIGGER = BlockApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "mana_trigger"), ManaTrigger.class, Unit.class);
public static final BlockApiLookup<Wandable, Unit> WANDABLE = BlockApiLookup.get(new ResourceLocation(BotaniaAPI.MODID, "wandable"), Wandable.class, Unit.class);
public static final BlockApiLookup<ExoflameHeatable, Unit> EXOFLAME_HEATABLE =
BlockApiLookup.get(ExoflameHeatable.ID, ExoflameHeatable.class, Unit.class);
public static final BlockApiLookup<HornHarvestable, Unit> HORN_HARVEST =
BlockApiLookup.get(HornHarvestable.ID, HornHarvestable.class, Unit.class);
public static final BlockApiLookup<HourglassTrigger, Unit> HOURGLASS_TRIGGER =
BlockApiLookup.get(HourglassTrigger.ID, HourglassTrigger.class, Unit.class);
public static final BlockApiLookup<ManaCollisionGhost, Unit> MANA_GHOST =
BlockApiLookup.get(ManaCollisionGhost.ID, ManaCollisionGhost.class, Unit.class);
public static final BlockApiLookup<ManaReceiver, /* @Nullable */ Direction> MANA_RECEIVER =
BlockApiLookup.get(ManaReceiver.ID, ManaReceiver.class, Direction.class);
public static final BlockApiLookup<SparkAttachable, Direction> SPARK_ATTACHABLE =
BlockApiLookup.get(SparkAttachable.ID, SparkAttachable.class, Direction.class);
public static final BlockApiLookup<ManaTrigger, Unit> MANA_TRIGGER =
BlockApiLookup.get(ManaTrigger.ID, ManaTrigger.class, Unit.class);
public static final BlockApiLookup<Wandable, Unit> WANDABLE =
BlockApiLookup.get(Wandable.ID, Wandable.class, Unit.class);

private BotaniaFabricCapabilities() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,14 @@

import vazkii.botania.common.internal_caps.*;

import static vazkii.botania.common.lib.ResourceLocationHelper.prefix;

public class CCAInternalEntityComponents implements EntityComponentInitializer {
public static final ComponentKey<CCAEthicalComponent> TNT_ETHICAL = ComponentRegistryV3.INSTANCE.getOrCreate(prefix("tnt_ethical"), CCAEthicalComponent.class);
public static final ComponentKey<CCASpectralRailComponent> GHOST_RAIL = ComponentRegistryV3.INSTANCE.getOrCreate(prefix("ghost_rail"), CCASpectralRailComponent.class);
public static final ComponentKey<CCAItemFlagsComponent> INTERNAL_ITEM = ComponentRegistryV3.INSTANCE.getOrCreate(prefix("iitem"), CCAItemFlagsComponent.class);
public static final ComponentKey<CCAKeptItemsComponent> KEPT_ITEMS = ComponentRegistryV3.INSTANCE.getOrCreate(prefix("kept_items"), CCAKeptItemsComponent.class);
public static final ComponentKey<CCALooniumComponent> LOONIUM_DROP = ComponentRegistryV3.INSTANCE.getOrCreate(prefix("loonium_drop"), CCALooniumComponent.class);
public static final ComponentKey<CCANarslimmusComponent> NARSLIMMUS = ComponentRegistryV3.INSTANCE.getOrCreate(prefix("narslimmus"), CCANarslimmusComponent.class);
public static final ComponentKey<CCATigerseyeComponent> TIGERSEYE = ComponentRegistryV3.INSTANCE.getOrCreate(prefix("tigerseye_pacified"), CCATigerseyeComponent.class);
public static final ComponentKey<CCAEthicalComponent> TNT_ETHICAL = ComponentRegistryV3.INSTANCE.getOrCreate(EthicalComponent.ID, CCAEthicalComponent.class);
public static final ComponentKey<CCASpectralRailComponent> GHOST_RAIL = ComponentRegistryV3.INSTANCE.getOrCreate(SpectralRailComponent.ID, CCASpectralRailComponent.class);
public static final ComponentKey<CCAItemFlagsComponent> INTERNAL_ITEM = ComponentRegistryV3.INSTANCE.getOrCreate(ItemFlagsComponent.ID, CCAItemFlagsComponent.class);
public static final ComponentKey<CCAKeptItemsComponent> KEPT_ITEMS = ComponentRegistryV3.INSTANCE.getOrCreate(KeptItemsComponent.ID, CCAKeptItemsComponent.class);
public static final ComponentKey<CCALooniumComponent> LOONIUM_DROP = ComponentRegistryV3.INSTANCE.getOrCreate(LooniumComponent.ID, CCALooniumComponent.class);
public static final ComponentKey<CCANarslimmusComponent> NARSLIMMUS = ComponentRegistryV3.INSTANCE.getOrCreate(NarslimmusComponent.ID, CCANarslimmusComponent.class);
public static final ComponentKey<CCATigerseyeComponent> TIGERSEYE = ComponentRegistryV3.INSTANCE.getOrCreate(TigerseyeComponent.ID, CCATigerseyeComponent.class);

@Override
public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,22 @@
*/
package vazkii.botania.fabric.mixin;

import com.google.common.collect.ImmutableSet;

import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;

import vazkii.botania.common.item.BotaniaItems;

import java.util.HashSet;
import java.util.Set;

@Mixin(ItemPredicate.class)
public abstract class ItemPredicateFabricMixin {
@ModifyVariable(at = @At("HEAD"), method = "<init>(Lnet/minecraft/tags/TagKey;Ljava/util/Set;Lnet/minecraft/advancements/critereon/MinMaxBounds$Ints;Lnet/minecraft/advancements/critereon/MinMaxBounds$Ints;[Lnet/minecraft/advancements/critereon/EnchantmentPredicate;[Lnet/minecraft/advancements/critereon/EnchantmentPredicate;Lnet/minecraft/world/item/alchemy/Potion;Lnet/minecraft/advancements/critereon/NbtPredicate;)V", argsOnly = true)
private static Set<Item> addBotaniaShears(Set<Item> set) {
if (set != null && set.contains(Items.SHEARS)) {
set = new HashSet<>(set);
set.add(BotaniaItems.manasteelShears);
set.add(BotaniaItems.elementiumShears);
set = ImmutableSet.copyOf(set);
}
return set;
}
// TODO: probably worth dropping in favor of conventional item tag #c:tools/shears instead of trying to hack into record

// @ModifyVariable(at = @At("HEAD"), method = "<init>(Lnet/minecraft/tags/TagKey;Ljava/util/Set;Lnet/minecraft/advancements/critereon/MinMaxBounds$Ints;Lnet/minecraft/advancements/critereon/MinMaxBounds$Ints;[Lnet/minecraft/advancements/critereon/EnchantmentPredicate;[Lnet/minecraft/advancements/critereon/EnchantmentPredicate;Lnet/minecraft/world/item/alchemy/Potion;Lnet/minecraft/advancements/critereon/NbtPredicate;)V", argsOnly = true)
// private static Set<Item> addBotaniaShears(Set<Item> set) {
// if (set != null && set.contains(Items.SHEARS)) {
// set = new HashSet<>(set);
// set.add(BotaniaItems.manasteelShears);
// set.add(BotaniaItems.elementiumShears);
// set = ImmutableSet.copyOf(set);
// }
// return set;
// }
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package vazkii.botania.api;

import net.neoforged.neoforge.common.capabilities.Capability;
import net.neoforged.neoforge.common.capabilities.CapabilityManager;
import net.neoforged.neoforge.common.capabilities.CapabilityToken;

import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.capabilities.BlockCapability;
import net.neoforged.neoforge.capabilities.ItemCapability;
import org.jetbrains.annotations.NotNull;
import vazkii.botania.api.block.ExoflameHeatable;
import vazkii.botania.api.block.HornHarvestable;
import vazkii.botania.api.block.HourglassTrigger;
Expand All @@ -19,20 +20,40 @@
import vazkii.botania.api.mana.spark.SparkAttachable;

public final class BotaniaForgeCapabilities {
public static final Capability<AvatarWieldable> AVATAR_WIELDABLE = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<BlockProvider> BLOCK_PROVIDER = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<CoordBoundItem> COORD_BOUND_ITEM = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<ManaItem> MANA_ITEM = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<Relic> RELIC = CapabilityManager.get(new CapabilityToken<>() {});

public static final Capability<ExoflameHeatable> EXOFLAME_HEATABLE = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<HornHarvestable> HORN_HARVEST = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<HourglassTrigger> HOURGLASS_TRIGGER = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<ManaCollisionGhost> MANA_GHOST = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<ManaReceiver> MANA_RECEIVER = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<SparkAttachable> SPARK_ATTACHABLE = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<ManaTrigger> MANA_TRIGGER = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<Wandable> WANDABLE = CapabilityManager.get(new CapabilityToken<>() {});
public static final ItemCapability<AvatarWieldable, Void> AVATAR_WIELDABLE =
ItemCapability.createVoid(AvatarWieldable.ID, AvatarWieldable.class);

public static final ItemCapability<BlockProvider, Void> BLOCK_PROVIDER =
ItemCapability.createVoid(BlockProvider.ID, BlockProvider.class);
public static final ItemCapability<CoordBoundItem, Void> COORD_BOUND_ITEM =
ItemCapability.createVoid(CoordBoundItem.ID, CoordBoundItem.class);
public static final ItemCapability<ManaItem, Void> MANA_ITEM =
ItemCapability.createVoid(ManaItem.ID, ManaItem.class);
public static final ItemCapability<Relic, Void> RELIC =
ItemCapability.createVoid(Relic.ID, Relic.class);

public static final BlockCapability<ExoflameHeatable, Void> EXOFLAME_HEATABLE =
BlockCapability.createVoid(ExoflameHeatable.ID, ExoflameHeatable.class);

public static final BlockCapability<HornHarvestable, Void> HORN_HARVEST =
BlockCapability.createVoid(HornHarvestable.ID, HornHarvestable.class);
public static final BlockCapability<HourglassTrigger, Void> HOURGLASS_TRIGGER =
BlockCapability.createVoid(HourglassTrigger.ID, HourglassTrigger.class);
public static final BlockCapability<ManaCollisionGhost, Void> MANA_GHOST =
BlockCapability.createVoid(ManaCollisionGhost.ID, ManaCollisionGhost.class);
public static final BlockCapability<ManaReceiver, Direction> MANA_RECEIVER =
BlockCapability.createSided(ManaReceiver.ID, ManaReceiver.class);

public static final BlockCapability<SparkAttachable, Direction> SPARK_ATTACHABLE =
BlockCapability.createSided(SparkAttachable.ID, SparkAttachable.class);
public static final BlockCapability<ManaTrigger, Void> MANA_TRIGGER =
BlockCapability.createVoid(ManaTrigger.ID, ManaTrigger.class);
public static final BlockCapability<Wandable, Void> WANDABLE =
BlockCapability.createVoid(Wandable.ID, Wandable.class);

private static @NotNull ResourceLocation prefix(String path) {
return new ResourceLocation(BotaniaAPI.MODID, path);
}

private BotaniaForgeCapabilities() {}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package vazkii.botania.forge.internal_caps;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.item.ItemEntity;
Expand All @@ -10,23 +12,45 @@
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.common.capabilities.*;
import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.attachment.IAttachmentHolder;
import net.neoforged.neoforge.common.util.INBTSerializable;
import net.neoforged.neoforge.event.AttachCapabilitiesEvent;

import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import vazkii.botania.api.BotaniaAPI;
import vazkii.botania.common.internal_caps.*;
import vazkii.botania.common.lib.LibMisc;
import vazkii.botania.forge.CapabilityUtil;

import java.util.function.Supplier;

import static vazkii.botania.common.lib.ResourceLocationHelper.prefix;

public final class ForgeInternalEntityCapabilities {
public static final Capability<EthicalComponent> TNT_ETHICAL = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<SpectralRailComponent> GHOST_RAIL = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<ItemFlagsComponent> INTERNAL_ITEM = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<KeptItemsComponent> KEPT_ITEMS = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<LooniumComponent> LOONIUM_DROP = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<NarslimmusComponent> NARSLIMMUS = CapabilityManager.get(new CapabilityToken<>() {});
public static final Capability<TigerseyeComponent> TIGERSEYE = CapabilityManager.get(new CapabilityToken<>() {});
private static final DeferredRegister<AttachmentType<?>> ATTACHMENT_TYPES = DeferredRegister.create(NeoForgeRegistries.Keys.ATTACHMENT_TYPES, BotaniaAPI.MODID);
public static final Supplier<AttachmentType<ForgeEthicalComponent>> TNT_ETHICAL = ATTACHMENT_TYPES.register(
ForgeEthicalComponent.ID.getPath(),
AttachmentType.serializable(ForgeEthicalComponent::new)::build);
public static final Supplier<AttachmentType<ForgeSpectralRailComponent>> GHOST_RAIL =
registerComponentAttachmentType(ForgeSpectralRailComponent.ID, ForgeSpectralRailComponent::new);
public static final Supplier<AttachmentType<ForgeItemFlagsComponent>> INTERNAL_ITEM =
registerComponentAttachmentType(ForgeItemFlagsComponent.ID, ForgeItemFlagsComponent::new);
public static final Supplier<AttachmentType<ForgeKeptItemsComponent>> KEPT_ITEMS = ATTACHMENT_TYPES.register(
ForgeKeptItemsComponent.ID.getPath(),
AttachmentType.serializable(ForgeKeptItemsComponent::new)::build);
public static final Supplier<AttachmentType<ForgeLooniumComponent>> LOONIUM_DROP =
registerComponentAttachmentType(ForgeLooniumComponent.ID, ForgeLooniumComponent::new);
public static final Supplier<AttachmentType<ForgeNarslimmusComponent>> NARSLIMMUS =
registerComponentAttachmentType(ForgeNarslimmusComponent.ID, ForgeNarslimmusComponent::new);
public static final Supplier<AttachmentType<ForgeTigerseyeComponent>> TIGERSEYE =
registerComponentAttachmentType(ForgeTigerseyeComponent.ID, ForgeTigerseyeComponent::new);

private static <T extends SerializableComponent & INBTSerializable<CompoundTag>> DeferredHolder<AttachmentType<?>, AttachmentType<T>> registerComponentAttachmentType(ResourceLocation componentId, Supplier<T> componentSupplier) {
return ATTACHMENT_TYPES.register(componentId.getPath(), AttachmentType.serializable(componentSupplier)::build);
}

@Mod.EventBusSubscriber(modid = LibMisc.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public static class ModBusEvents {
Expand Down Expand Up @@ -73,4 +97,28 @@ public static void attachCapabilities(AttachCapabilitiesEvent<Entity> evt) {
}

private ForgeInternalEntityCapabilities() {}

public static class ForgeEthicalComponent extends EthicalComponent implements INBTSerializable<CompoundTag> {
public ForgeEthicalComponent(IAttachmentHolder entity) {
super((PrimedTnt) entity);
}
}

public static class ForgeSpectralRailComponent extends SpectralRailComponent implements INBTSerializable<CompoundTag> {
}

public static class ForgeItemFlagsComponent extends ItemFlagsComponent implements INBTSerializable<CompoundTag> {
}

public static class ForgeKeptItemsComponent extends KeptItemsComponent implements INBTSerializable<CompoundTag> {
}

public static class ForgeLooniumComponent extends LooniumComponent implements INBTSerializable<CompoundTag> {
}

public static class ForgeNarslimmusComponent extends NarslimmusComponent implements INBTSerializable<CompoundTag> {
}

public static class ForgeTigerseyeComponent extends TigerseyeComponent implements INBTSerializable<CompoundTag> {
}
}

This file was deleted.

Loading

0 comments on commit 30d5475

Please sign in to comment.