diff --git a/src/main/java/fathertoast/specialmobs/common/bestiary/SpecialMob.java b/src/main/java/fathertoast/specialmobs/common/bestiary/SpecialMob.java index 85f5d91..bb5f61d 100644 --- a/src/main/java/fathertoast/specialmobs/common/bestiary/SpecialMob.java +++ b/src/main/java/fathertoast/specialmobs/common/bestiary/SpecialMob.java @@ -135,6 +135,18 @@ public @interface SpecialMob { @Retention( RetentionPolicy.RUNTIME ) @Target( ElementType.METHOD ) @interface LootTableProvider { } + + /** + * OPTIONAL-OVERRIDABLE. This is called during data generation to add the mob's entity type to any + * desired entity type tags. + *

+ * The annotated method must have a signature that follows the pattern: + *

+ * {@code public static List> METHOD_NAME( )} + */ + @Retention( RetentionPolicy.RUNTIME ) + @Target( ElementType.METHOD ) + @interface EntityTagProvider { } /** * REQUIRED. This is called during registration to build the mob 'factory'. This will essentially just return the diff --git a/src/main/java/fathertoast/specialmobs/common/entity/projectile/BugSpitEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/projectile/BugSpitEntity.java index 8b448ad..efa980e 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/projectile/BugSpitEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/projectile/BugSpitEntity.java @@ -68,7 +68,7 @@ public class BugSpitEntity extends ProjectileEntity { final double dH = MathHelper.sqrt( dX * dX + dZ * dZ ); shoot( dX, dY + dH * 0.2, dZ, 1.2F, spread ); } - + /** Called from the Entity.class constructor to define data watcher variables. */ @Override protected void defineSynchedData() { entityData.define( COLOR, 0xFFFFFF ); } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/skeleton/_SpecialSkeletonEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/skeleton/_SpecialSkeletonEntity.java index a19ff33..a1a4909 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/skeleton/_SpecialSkeletonEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/skeleton/_SpecialSkeletonEntity.java @@ -36,6 +36,8 @@ import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.pathfinding.PathNodeType; import net.minecraft.potion.EffectInstance; +import net.minecraft.tags.EntityTypeTags; +import net.minecraft.tags.ITag; import net.minecraft.util.DamageSource; import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvents; @@ -46,6 +48,8 @@ import net.minecraft.world.IServerWorld; import net.minecraft.world.World; import javax.annotation.Nullable; +import java.util.Collections; +import java.util.List; @SpecialMob public class _SpecialSkeletonEntity extends AbstractSkeletonEntity implements ISpecialMob<_SpecialSkeletonEntity> { @@ -93,6 +97,11 @@ public class _SpecialSkeletonEntity extends AbstractSkeletonEntity implements IS public static void addBaseLoot( LootTableBuilder loot ) { loot.addLootTable( "main", EntityType.SKELETON.getDefaultLootTable() ); } + + @SpecialMob.EntityTagProvider + public static List>> getEntityTags() { + return Collections.singletonList(EntityTypeTags.SKELETONS); + } @SpecialMob.Factory public static EntityType.IFactory<_SpecialSkeletonEntity> getFactory() { return _SpecialSkeletonEntity::new; } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/witch/_SpecialWitchEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/witch/_SpecialWitchEntity.java index 5338656..e7449b7 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/witch/_SpecialWitchEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/witch/_SpecialWitchEntity.java @@ -32,7 +32,9 @@ import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.pathfinding.PathNodeType; import net.minecraft.potion.*; +import net.minecraft.tags.EntityTypeTags; import net.minecraft.tags.FluidTags; +import net.minecraft.tags.ITag; import net.minecraft.util.DamageSource; import net.minecraft.util.IItemProvider; import net.minecraft.util.SoundEvents; @@ -44,6 +46,7 @@ import net.minecraft.world.World; import javax.annotation.Nullable; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.UUID; @@ -82,6 +85,11 @@ public class _SpecialWitchEntity extends WitchEntity implements ISpecialMob<_Spe public static void addBaseLoot( LootTableBuilder loot ) { loot.addLootTable( "main", EntityType.WITCH.getDefaultLootTable() ); } + + @SpecialMob.EntityTagProvider + public static List>> getEntityTags() { + return Collections.singletonList(EntityTypeTags.RAIDERS); + } @SpecialMob.Factory public static EntityType.IFactory<_SpecialWitchEntity> getFactory() { return _SpecialWitchEntity::new; } diff --git a/src/main/java/fathertoast/specialmobs/common/entity/witherskeleton/_SpecialWitherSkeletonEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/witherskeleton/_SpecialWitherSkeletonEntity.java index c2156f8..c0d7802 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/witherskeleton/_SpecialWitherSkeletonEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/witherskeleton/_SpecialWitherSkeletonEntity.java @@ -34,6 +34,8 @@ import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.pathfinding.PathNodeType; import net.minecraft.potion.EffectInstance; +import net.minecraft.tags.EntityTypeTags; +import net.minecraft.tags.ITag; import net.minecraft.util.DamageSource; import net.minecraft.util.SoundEvents; import net.minecraft.util.math.MathHelper; @@ -43,6 +45,8 @@ import net.minecraft.world.IServerWorld; import net.minecraft.world.World; import javax.annotation.Nullable; +import java.util.Collections; +import java.util.List; @SpecialMob public class _SpecialWitherSkeletonEntity extends WitherSkeletonEntity implements ISpecialMob<_SpecialWitherSkeletonEntity> { @@ -92,6 +96,11 @@ public class _SpecialWitherSkeletonEntity extends WitherSkeletonEntity implement public static void addBaseLoot( LootTableBuilder loot ) { loot.addLootTable( "main", EntityType.WITHER_SKELETON.getDefaultLootTable() ); } + + @SpecialMob.EntityTagProvider + public static List>> getEntityTags() { + return Collections.singletonList(EntityTypeTags.SKELETONS); + } @SpecialMob.Factory public static EntityType.IFactory<_SpecialWitherSkeletonEntity> getFactory() { return _SpecialWitherSkeletonEntity::new; } diff --git a/src/main/java/fathertoast/specialmobs/common/util/AnnotationHelper.java b/src/main/java/fathertoast/specialmobs/common/util/AnnotationHelper.java index f5a32ff..faf8703 100644 --- a/src/main/java/fathertoast/specialmobs/common/util/AnnotationHelper.java +++ b/src/main/java/fathertoast/specialmobs/common/util/AnnotationHelper.java @@ -10,6 +10,7 @@ import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.ai.attributes.AttributeModifierMap; import net.minecraft.item.Item; +import net.minecraft.tags.ITag; import net.minecraftforge.registries.ForgeRegistryEntry; import javax.annotation.Nullable; @@ -18,6 +19,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.List; /** * Provides helper methods to handle annotation processing through reflection. @@ -133,6 +135,26 @@ public final class AnnotationHelper { throw new RuntimeException( "Entity class for " + species.name + " has invalid loot table builder method", ex ); } } + + @SuppressWarnings("unchecked") + @Nullable + public static List>> getEntityTags( Class entityClass ) { + try { + Method method = getMethodOrSuperOptional( entityClass, SpecialMob.EntityTagProvider.class ); + + if (method != null) { + Object ret = method.invoke( null ); + + if (ret != null) + return (List>>) ret; + } + return null; + } + catch (InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + return null; + } + } /** Creates an entity factory from a special mob species. Throws an exception if anything goes wrong. */ public static EntityType.IFactory getEntityFactory( MobFamily.Species species ) { diff --git a/src/main/java/fathertoast/specialmobs/datagen/DataGatherListener.java b/src/main/java/fathertoast/specialmobs/datagen/DataGatherListener.java index 587851b..62237d9 100644 --- a/src/main/java/fathertoast/specialmobs/datagen/DataGatherListener.java +++ b/src/main/java/fathertoast/specialmobs/datagen/DataGatherListener.java @@ -2,6 +2,7 @@ package fathertoast.specialmobs.datagen; import fathertoast.specialmobs.common.core.SpecialMobs; import net.minecraft.data.DataGenerator; +import net.minecraftforge.common.data.ExistingFileHelper; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.GatherDataEvent; @@ -14,16 +15,18 @@ public class DataGatherListener { @SubscribeEvent public static void onGatherData( GatherDataEvent event ) { DataGenerator generator = event.getGenerator(); + ExistingFileHelper fileHelper = event.getExistingFileHelper(); if( event.includeClient() ) { - generator.addProvider( new SMBlockStateAndModelProvider( generator, event.getExistingFileHelper() ) ); - generator.addProvider( new SMItemModelProvider( generator, event.getExistingFileHelper() ) ); + generator.addProvider( new SMBlockStateAndModelProvider( generator, fileHelper ) ); + generator.addProvider( new SMItemModelProvider( generator, fileHelper ) ); for( Map.Entry entry : SMLanguageProvider.LANG_CODE_MAP.entrySet() ) { generator.addProvider( new SMLanguageProvider( generator, entry.getKey(), entry.getValue() ) ); } } if( event.includeServer() ) { generator.addProvider( new SMLootTableProvider( generator ) ); + generator.addProvider( new SMEntityTagProvider( generator, fileHelper ) ); } } } \ No newline at end of file diff --git a/src/main/java/fathertoast/specialmobs/datagen/SMEntityTagProvider.java b/src/main/java/fathertoast/specialmobs/datagen/SMEntityTagProvider.java new file mode 100644 index 0000000..e3e9717 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/datagen/SMEntityTagProvider.java @@ -0,0 +1,41 @@ +package fathertoast.specialmobs.datagen; + +import fathertoast.specialmobs.common.bestiary.MobFamily; +import fathertoast.specialmobs.common.core.SpecialMobs; +import fathertoast.specialmobs.common.core.register.SMEntities; +import fathertoast.specialmobs.common.util.AnnotationHelper; +import net.minecraft.data.DataGenerator; +import net.minecraft.data.EntityTypeTagsProvider; +import net.minecraft.entity.EntityType; +import net.minecraft.tags.EntityTypeTags; +import net.minecraft.tags.ITag; +import net.minecraftforge.common.data.ExistingFileHelper; + +import javax.annotation.Nullable; +import java.util.List; + +public class SMEntityTagProvider extends EntityTypeTagsProvider { + + public SMEntityTagProvider(DataGenerator generator, @Nullable ExistingFileHelper fileHelper) { + super(generator, SpecialMobs.MOD_ID, fileHelper); + } + + @Override + protected void addTags() { + for( MobFamily.Species species : MobFamily.getAllSpecies( ) ) { + List>> tags = AnnotationHelper.getEntityTags( species.entityClass ); + + if ( tags != null && !tags.isEmpty() ) { + for ( ITag.INamedTag> tag : tags ) { + tag( tag ).add( species.entityType.get() ); + } + } + } + + // Manually added + tag(EntityTypeTags.IMPACT_PROJECTILES).add( + SMEntities.BONE_SHRAPNEL.get(), + SMEntities.BUG_SPIT.get() + ); + } +}