diff options
-rw-r--r-- | gradle.properties | 2 | ||||
-rw-r--r-- | src/main/java/com/anthonyhilyard/iceberg/Loader.java | 3 | ||||
-rw-r--r-- | src/main/java/com/anthonyhilyard/iceberg/registry/AutoRegistry.java | 167 |
3 files changed, 168 insertions, 4 deletions
diff --git a/gradle.properties b/gradle.properties index 8cdea8b..193b1c2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ org.gradle.daemon=false name=Iceberg group=com.anthonyhilyard.iceberg author=anthonyhilyard -version=1.0.1 +version=1.0.3 mcVersion=1.16.5 forgeVersion=36.2.2
\ No newline at end of file diff --git a/src/main/java/com/anthonyhilyard/iceberg/Loader.java b/src/main/java/com/anthonyhilyard/iceberg/Loader.java index b41595f..b1ff65a 100644 --- a/src/main/java/com/anthonyhilyard/iceberg/Loader.java +++ b/src/main/java/com/anthonyhilyard/iceberg/Loader.java @@ -1,8 +1,5 @@ package com.anthonyhilyard.iceberg; -import com.anthonyhilyard.iceberg.events.CriterionEvent; -import com.anthonyhilyard.iceberg.events.EntityFluidEvent; - import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/src/main/java/com/anthonyhilyard/iceberg/registry/AutoRegistry.java b/src/main/java/com/anthonyhilyard/iceberg/registry/AutoRegistry.java new file mode 100644 index 0000000..dd7da65 --- /dev/null +++ b/src/main/java/com/anthonyhilyard/iceberg/registry/AutoRegistry.java @@ -0,0 +1,167 @@ +package com.anthonyhilyard.iceberg.registry; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.attributes.AttributeModifierMap; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.fml.client.registry.IRenderFactory; +import net.minecraftforge.fml.client.registry.RenderingRegistry; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.IForgeRegistryEntry; +import net.minecraftforge.event.entity.EntityAttributeCreationEvent; + +/** + * Extend this class to have all registerable fields be automatically registered in Forge. Easy. + */ +public abstract class AutoRegistry +{ + protected static String MODID = null; + + private static boolean entityCreationRegistered = false; + + private static Map<EntityType<?>, Supplier<AttributeModifierMap.MutableAttribute>> entityAttributes = new HashMap<>(); + + public static void init(String ModID) + { + MODID = ModID; + } + + @SuppressWarnings("unchecked") + protected AutoRegistry() + { + try + { + // Iterate through every built-in Forge registry... + for (Field field : ForgeRegistries.class.getDeclaredFields()) + { + Object fieldObj = field.get(null); + if (fieldObj instanceof IForgeRegistry) + { + // Grab the registry's supertype and add a generic listener for registry events. + Class<IForgeRegistryEntry<?>> clazz = (Class<IForgeRegistryEntry<?>>)((IForgeRegistry<?>)fieldObj).getRegistrySuperType(); + FMLJavaModLoadingContext.get().getModEventBus().addGenericListener(clazz, (Consumer<RegistryEvent.Register<? extends IForgeRegistryEntry<?>>>)(e) -> registerAllOfType(clazz, e) ); + } + } + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + @SuppressWarnings("unchecked") + private final <T extends IForgeRegistryEntry<T>> void registerAllOfType(Class<IForgeRegistryEntry<?>> type, RegistryEvent.Register<T> event) + { + try + { + // Loop through all fields we've declared and register them. + for (Field field : this.getClass().getDeclaredFields()) + { + // Grab the field and check if it is a Forge registry-compatible type. + Object obj = field.get(this); + if (type.isAssignableFrom(obj.getClass())) + { + // If this is an entity type field and we haven't already registered for the entity creation event, do so now. + if (obj instanceof EntityType && !entityCreationRegistered) + { + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onEntityCreation); + entityCreationRegistered = true; + } + + // If this field has a registry name, register it now. + T entry = (T)obj; + if (entry != null && entry.getRegistryName() != null) + { + event.getRegistry().register(entry); + } + } + } + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + protected static <T extends Entity> EntityType<T> registerEntity(String name, EntityType.Builder<T> builder, IRenderFactory<? super T> renderFactory) + { + return registerEntity(name, builder, renderFactory, null); + } + + @SuppressWarnings("unchecked") + protected static <T extends Entity> EntityType<T> registerEntity(String name, EntityType.Builder<T> builder, IRenderFactory<? super T> renderFactory, Supplier<AttributeModifierMap.MutableAttribute> attributes) + { + if (MODID == null) + { + throw new RuntimeException("AutoRegistry was not initialized with mod id!"); + } + + // Build the entity type. + ResourceLocation resourceLocation = new ResourceLocation(MODID, name); + EntityType<T> entityType = (EntityType<T>) builder.build(name).setRegistryName(resourceLocation); + + // Register the rendering handler. + RenderingRegistry.registerEntityRenderingHandler(entityType, renderFactory); + + // Store mob attributes if provided. These will be added in the attribute creation event below. + if (attributes != null) + { + entityAttributes.put(entityType, attributes); + } + + + return entityType; + } + + protected static SoundEvent registerSound(String name) + { + if (MODID == null) + { + throw new RuntimeException("AutoRegistry was not initialized with mod id!"); + } + + return new SoundEvent(new ResourceLocation(MODID, name)); + } + + @SuppressWarnings("unchecked") + private void onEntityCreation(EntityAttributeCreationEvent event) + { + for (Field field : this.getClass().getDeclaredFields()) + { + try + { + // Grab the field and check if it is a Forge registry-compatible type. + Object obj = field.get(this); + if (EntityType.class.isAssignableFrom(obj.getClass()) && entityAttributes.containsKey(obj)) + { + EntityType<? extends LivingEntity> entityType = (EntityType<? extends LivingEntity>) obj; + if (entityType != null) + { + event.put(entityType, entityAttributes.get(obj).get().build()); + } + } + } + catch (ClassCastException e) + { + // The class cast exception likely just means that we tried to convert an EntityType with generic type + // parameter of something other than a LivingEntity subclass. This is fine, so continue. + continue; + } + catch (IllegalAccessException e) + { + throw new RuntimeException(e); + } + } + } +}
\ No newline at end of file |