From dbd766a5c427994781a900085c003e5884dbcebe Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Wed, 22 Jan 2025 14:41:54 -0600 Subject: [PATCH] Fancy config groundwork - Add missing @Nullable annotations to visualizer registry - Build out common-side configuration infrastructure - Add fabric config json for vanillin - Add equivalent forge config json - Want to allow for toggling specific visualizers/updating config with a command --- .../flywheel/api/internal/FlwApiLink.java | 4 +- .../api/visualization/VisualizerRegistry.java | 4 +- .../flywheel/impl/FlwApiLinkImpl.java | 4 +- .../visualization/VisualizerRegistryImpl.java | 4 +- .../BlockEntityVisualizerBuilder.java | 74 +++++++++++++++++ .../engine_room/vanillin/Configurator.java | 82 +++++++++++++++++++ .../vanillin/EntityVisualizerBuilder.java | 79 ++++++++++++++++++ .../{visuals => }/VanillaVisuals.java | 46 +++++++---- .../dev/engine_room/vanillin/Vanillin.java | 12 +++ .../vanillin/FabricVanillinConfig.java | 78 ++++++++++++++++++ .../engine_room/vanillin/VanillinFabric.java | 4 +- .../vanillin/ForgeVanillinConfig.java | 62 ++++++++++++++ .../engine_room/vanillin/VanillinForge.java | 13 ++- 13 files changed, 440 insertions(+), 26 deletions(-) create mode 100644 common/src/vanillin/java/dev/engine_room/vanillin/BlockEntityVisualizerBuilder.java create mode 100644 common/src/vanillin/java/dev/engine_room/vanillin/Configurator.java create mode 100644 common/src/vanillin/java/dev/engine_room/vanillin/EntityVisualizerBuilder.java rename common/src/vanillin/java/dev/engine_room/vanillin/{visuals => }/VanillaVisuals.java (65%) create mode 100644 vanillinFabric/src/main/java/dev/engine_room/vanillin/FabricVanillinConfig.java create mode 100644 vanillinForge/src/main/java/dev/engine_room/vanillin/ForgeVanillinConfig.java diff --git a/common/src/api/java/dev/engine_room/flywheel/api/internal/FlwApiLink.java b/common/src/api/java/dev/engine_room/flywheel/api/internal/FlwApiLink.java index 53301b0aa..13e752154 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/internal/FlwApiLink.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/internal/FlwApiLink.java @@ -42,7 +42,7 @@ public interface FlwApiLink { @Nullable EntityVisualizer getVisualizer(EntityType type); - void setVisualizer(BlockEntityType type, BlockEntityVisualizer visualizer); + void setVisualizer(BlockEntityType type, @Nullable BlockEntityVisualizer visualizer); - void setVisualizer(EntityType type, EntityVisualizer visualizer); + void setVisualizer(EntityType type, @Nullable EntityVisualizer visualizer); } diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizerRegistry.java b/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizerRegistry.java index e9dd43370..eda95a7e7 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizerRegistry.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizerRegistry.java @@ -43,7 +43,7 @@ public final class VisualizerRegistry { * @param visualizer The visualizer to set. * @param The type of the block entity. */ - public static void setVisualizer(BlockEntityType type, BlockEntityVisualizer visualizer) { + public static void setVisualizer(BlockEntityType type, @Nullable BlockEntityVisualizer visualizer) { FlwApiLink.INSTANCE.setVisualizer(type, visualizer); } @@ -53,7 +53,7 @@ public final class VisualizerRegistry { * @param visualizer The visualizer to set. * @param The type of the entity. */ - public static void setVisualizer(EntityType type, EntityVisualizer visualizer) { + public static void setVisualizer(EntityType type, @Nullable EntityVisualizer visualizer) { FlwApiLink.INSTANCE.setVisualizer(type, visualizer); } } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java index c60df1239..6f03a7dab 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java @@ -79,12 +79,12 @@ public class FlwApiLinkImpl implements FlwApiLink { } @Override - public void setVisualizer(BlockEntityType type, BlockEntityVisualizer visualizer) { + public void setVisualizer(BlockEntityType type, @Nullable BlockEntityVisualizer visualizer) { VisualizerRegistryImpl.setVisualizer(type, visualizer); } @Override - public void setVisualizer(EntityType type, EntityVisualizer visualizer) { + public void setVisualizer(EntityType type, @Nullable EntityVisualizer visualizer) { VisualizerRegistryImpl.setVisualizer(type, visualizer); } } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java index 40522c89d..43d605ed0 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java @@ -23,11 +23,11 @@ public final class VisualizerRegistryImpl { return ((EntityTypeExtension) type).flywheel$getVisualizer(); } - public static void setVisualizer(BlockEntityType type, BlockEntityVisualizer visualizer) { + public static void setVisualizer(BlockEntityType type, @Nullable BlockEntityVisualizer visualizer) { ((BlockEntityTypeExtension) type).flywheel$setVisualizer(visualizer); } - public static void setVisualizer(EntityType type, EntityVisualizer visualizer) { + public static void setVisualizer(EntityType type, @Nullable EntityVisualizer visualizer) { ((EntityTypeExtension) type).flywheel$setVisualizer(visualizer); } diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/BlockEntityVisualizerBuilder.java b/common/src/vanillin/java/dev/engine_room/vanillin/BlockEntityVisualizerBuilder.java new file mode 100644 index 000000000..8cc1e6611 --- /dev/null +++ b/common/src/vanillin/java/dev/engine_room/vanillin/BlockEntityVisualizerBuilder.java @@ -0,0 +1,74 @@ +package dev.engine_room.vanillin; + +import java.util.Objects; +import java.util.function.Predicate; + +import org.jetbrains.annotations.Nullable; + +import dev.engine_room.flywheel.lib.visualization.SimpleBlockEntityVisualizer; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +public class BlockEntityVisualizerBuilder { + private final Configurator configurator; + private final BlockEntityType type; + @Nullable + private SimpleBlockEntityVisualizer.Factory visualFactory; + @Nullable + private Predicate skipVanillaRender; + + public BlockEntityVisualizerBuilder(Configurator configurator, BlockEntityType type) { + this.configurator = configurator; + this.type = type; + } + + /** + * Sets the visual factory for the block entity. + * + * @param visualFactory The visual factory. + * @return {@code this} + */ + public BlockEntityVisualizerBuilder factory(SimpleBlockEntityVisualizer.Factory visualFactory) { + this.visualFactory = visualFactory; + return this; + } + + /** + * Sets a predicate to determine whether to skip rendering with the vanilla {@link BlockEntityRenderer}. + * + * @param skipVanillaRender The predicate. + * @return {@code this} + */ + public BlockEntityVisualizerBuilder skipVanillaRender(Predicate skipVanillaRender) { + this.skipVanillaRender = skipVanillaRender; + return this; + } + + /** + * Sets a predicate to never skip rendering with the vanilla {@link BlockEntityRenderer}. + * + * @return {@code this} + */ + public BlockEntityVisualizerBuilder neverSkipVanillaRender() { + this.skipVanillaRender = blockEntity -> false; + return this; + } + + /** + * Constructs the block entity visualizer and sets it for the block entity type. + * + * @return The block entity visualizer. + */ + public SimpleBlockEntityVisualizer apply(boolean enabledByDefault) { + Objects.requireNonNull(visualFactory, "Visual factory cannot be null!"); + if (skipVanillaRender == null) { + skipVanillaRender = blockEntity -> true; + } + + SimpleBlockEntityVisualizer visualizer = new SimpleBlockEntityVisualizer<>(visualFactory, skipVanillaRender); + configurator.register(type, visualizer, enabledByDefault); + + return visualizer; + } +} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/Configurator.java b/common/src/vanillin/java/dev/engine_room/vanillin/Configurator.java new file mode 100644 index 000000000..027b60a4d --- /dev/null +++ b/common/src/vanillin/java/dev/engine_room/vanillin/Configurator.java @@ -0,0 +1,82 @@ +package dev.engine_room.vanillin; + +import java.util.HashMap; +import java.util.Map; + +import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer; +import dev.engine_room.flywheel.api.visualization.EntityVisualizer; +import dev.engine_room.flywheel.api.visualization.VisualizerRegistry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +public class Configurator { + public final Map, ConfiguredBlockEntity> blockEntities = new HashMap<>(); + public final Map, ConfiguredEntity> entities = new HashMap<>(); + + public void register(BlockEntityType type, BlockEntityVisualizer visualizer, boolean enabledByDefault) { + blockEntities.put(type, new ConfiguredBlockEntity<>(type, visualizer, enabledByDefault)); + } + + public void register(EntityType type, EntityVisualizer visualizer, boolean enabledByDefault) { + entities.put(type, new ConfiguredEntity<>(type, visualizer, enabledByDefault)); + } + + public static class ConfiguredBlockEntity { + public final BlockEntityType type; + public final BlockEntityVisualizer visualizer; + private final boolean enabledByDefault; + + private ConfiguredBlockEntity(BlockEntityType type, BlockEntityVisualizer visualizer, boolean enabledByDefault) { + this.type = type; + this.visualizer = visualizer; + this.enabledByDefault = enabledByDefault; + } + + public String configKey() { + return BuiltInRegistries.BLOCK_ENTITY_TYPE.getKey(type).toString(); + } + + public boolean enabledByDefault() { + return enabledByDefault; + } + + public void set(boolean enabled) { + if (enabled) { + VisualizerRegistry.setVisualizer(type, visualizer); + } else { + VisualizerRegistry.setVisualizer(type, null); + } + } + } + + public static class ConfiguredEntity { + public final EntityType type; + public final EntityVisualizer visualizer; + private final boolean enabledByDefault; + + private ConfiguredEntity(EntityType type, EntityVisualizer visualizer, boolean enabledByDefault) { + this.type = type; + this.visualizer = visualizer; + this.enabledByDefault = enabledByDefault; + } + + public String configKey() { + return BuiltInRegistries.ENTITY_TYPE.getKey(type).toString(); + } + + public boolean defaultEnabled() { + return enabledByDefault; + } + + public void set(boolean enabled) { + if (enabled) { + VisualizerRegistry.setVisualizer(type, visualizer); + } else { + VisualizerRegistry.setVisualizer(type, null); + } + } + } +} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/EntityVisualizerBuilder.java b/common/src/vanillin/java/dev/engine_room/vanillin/EntityVisualizerBuilder.java new file mode 100644 index 000000000..1d3bb81a1 --- /dev/null +++ b/common/src/vanillin/java/dev/engine_room/vanillin/EntityVisualizerBuilder.java @@ -0,0 +1,79 @@ +package dev.engine_room.vanillin; + +import java.util.Objects; +import java.util.function.Predicate; + +import org.jetbrains.annotations.Nullable; + +import dev.engine_room.flywheel.lib.visualization.SimpleEntityVisualizer; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; + +/** + * An object to configure the visualizer for an entity. + * + * @param The type of the entity. + */ +public final class EntityVisualizerBuilder { + private final Configurator configurator; + private final EntityType type; + @Nullable + private SimpleEntityVisualizer.Factory visualFactory; + @Nullable + private Predicate skipVanillaRender; + + public EntityVisualizerBuilder(Configurator configurator, EntityType type) { + this.configurator = configurator; + this.type = type; + } + + /** + * Sets the visual factory for the entity. + * + * @param visualFactory The visual factory. + * @return {@code this} + */ + public EntityVisualizerBuilder factory(SimpleEntityVisualizer.Factory visualFactory) { + this.visualFactory = visualFactory; + return this; + } + + /** + * Sets a predicate to determine whether to skip rendering with the vanilla {@link EntityRenderer}. + * + * @param skipVanillaRender The predicate. + * @return {@code this} + */ + public EntityVisualizerBuilder skipVanillaRender(Predicate skipVanillaRender) { + this.skipVanillaRender = skipVanillaRender; + return this; + } + + /** + * Sets a predicate to always skip rendering with the vanilla {@link EntityRenderer}. + * + * @return {@code this} + */ + public EntityVisualizerBuilder neverSkipVanillaRender() { + this.skipVanillaRender = entity -> false; + return this; + } + + /** + * Constructs the entity visualizer and sets it for the entity type. + * + * @return The entity visualizer. + */ + public SimpleEntityVisualizer apply(boolean enabledByDefault) { + Objects.requireNonNull(visualFactory, "Visual factory cannot be null!"); + if (skipVanillaRender == null) { + skipVanillaRender = entity -> true; + } + + SimpleEntityVisualizer visualizer = new SimpleEntityVisualizer<>(visualFactory, skipVanillaRender); + configurator.register(type, visualizer, enabledByDefault); + + return visualizer; + } +} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/VanillaVisuals.java b/common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java similarity index 65% rename from common/src/vanillin/java/dev/engine_room/vanillin/visuals/VanillaVisuals.java rename to common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java index eae31e8f2..93c98ef8b 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/VanillaVisuals.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java @@ -1,59 +1,73 @@ -package dev.engine_room.vanillin.visuals; - -import static dev.engine_room.flywheel.lib.visualization.SimpleBlockEntityVisualizer.builder; -import static dev.engine_room.flywheel.lib.visualization.SimpleEntityVisualizer.builder; +package dev.engine_room.vanillin; +import dev.engine_room.vanillin.visuals.BellVisual; +import dev.engine_room.vanillin.visuals.ChestVisual; +import dev.engine_room.vanillin.visuals.MinecartVisual; +import dev.engine_room.vanillin.visuals.ShulkerBoxVisual; +import dev.engine_room.vanillin.visuals.TntMinecartVisual; import net.minecraft.client.model.geom.ModelLayers; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; public class VanillaVisuals { + public static final Configurator CONFIGURATOR = new Configurator(); + public static void init() { builder(BlockEntityType.CHEST) .factory(ChestVisual::new) - .apply(); + .apply(true); builder(BlockEntityType.ENDER_CHEST) .factory(ChestVisual::new) - .apply(); + .apply(true); builder(BlockEntityType.TRAPPED_CHEST) .factory(ChestVisual::new) - .apply(); + .apply(true); builder(BlockEntityType.BELL) .factory(BellVisual::new) - .apply(); + .apply(true); builder(BlockEntityType.SHULKER_BOX) .factory(ShulkerBoxVisual::new) - .apply(); + .apply(true); builder(EntityType.CHEST_MINECART) .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.CHEST_MINECART)) .skipVanillaRender(MinecartVisual::shouldSkipRender) - .apply(); + .apply(true); builder(EntityType.COMMAND_BLOCK_MINECART) .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.COMMAND_BLOCK_MINECART)) .skipVanillaRender(MinecartVisual::shouldSkipRender) - .apply(); + .apply(true); builder(EntityType.FURNACE_MINECART) .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.FURNACE_MINECART)) .skipVanillaRender(MinecartVisual::shouldSkipRender) - .apply(); + .apply(true); builder(EntityType.HOPPER_MINECART) .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.HOPPER_MINECART)) .skipVanillaRender(MinecartVisual::shouldSkipRender) - .apply(); + .apply(true); builder(EntityType.MINECART) .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.MINECART)) .skipVanillaRender(MinecartVisual::shouldSkipRender) - .apply(); + .apply(true); builder(EntityType.SPAWNER_MINECART) .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, ModelLayers.SPAWNER_MINECART)) .skipVanillaRender(MinecartVisual::shouldSkipRender) - .apply(); + .apply(true); builder(EntityType.TNT_MINECART) .factory(TntMinecartVisual::new) .skipVanillaRender(MinecartVisual::shouldSkipRender) - .apply(); + .apply(true); + } + + public static BlockEntityVisualizerBuilder builder(BlockEntityType type) { + return new BlockEntityVisualizerBuilder<>(CONFIGURATOR, type); + } + + public static EntityVisualizerBuilder builder(EntityType type) { + return new EntityVisualizerBuilder<>(CONFIGURATOR, type); } } diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java b/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java index 2b4fd2efb..8eefa0c6f 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java @@ -1,5 +1,17 @@ package dev.engine_room.vanillin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.minecraft.resources.ResourceLocation; + public class Vanillin { public static final String ID = "vanillin"; + + public static final Logger LOGGER = LoggerFactory.getLogger(ID); + public static final Logger CONFIG_LOGGER = LoggerFactory.getLogger(ID + "/config"); + + public static ResourceLocation rl(String path) { + return new ResourceLocation(ID, path); + } } diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/FabricVanillinConfig.java b/vanillinFabric/src/main/java/dev/engine_room/vanillin/FabricVanillinConfig.java new file mode 100644 index 000000000..46c3a55ab --- /dev/null +++ b/vanillinFabric/src/main/java/dev/engine_room/vanillin/FabricVanillinConfig.java @@ -0,0 +1,78 @@ +package dev.engine_room.vanillin; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.SerializedName; + +import net.fabricmc.loader.api.FabricLoader; + +public class FabricVanillinConfig { + public static final Path PATH = FabricLoader.getInstance() + .getConfigDir() + .resolve("vanillin.json"); + + public static final FabricVanillinConfig INSTANCE = new FabricVanillinConfig(PATH.toFile()); + + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + private final File file; + + private Config config; + + public FabricVanillinConfig(File file) { + this.file = file; + } + + public void load() { + if (file.exists()) { + try (FileReader reader = new FileReader(file)) { + config = GSON.fromJson(reader, Config.class); + } catch (Exception e) { + Vanillin.CONFIG_LOGGER.warn("Could not load config from file '{}'", file.getAbsolutePath(), e); + config = new Config(); + } + } + } + + public void apply(Configurator configurator) { + for (Configurator.ConfiguredBlockEntity configuredBlockEntity : configurator.blockEntities.values()) { + boolean enabled = config.blockEntities.computeIfAbsent(configuredBlockEntity.configKey(), $ -> configuredBlockEntity.enabledByDefault()); + configuredBlockEntity.set(enabled); + } + + for (Configurator.ConfiguredEntity configured : configurator.entities.values()) { + boolean enabled = config.entities.computeIfAbsent(configured.configKey(), $ -> configured.defaultEnabled()); + configured.set(enabled); + } + } + + public void save() { + try (FileWriter writer = new FileWriter(file)) { + GSON.toJson(config, writer); + } catch (Exception e) { + Vanillin.CONFIG_LOGGER.warn("Could not save config to file '{}'", file.getAbsolutePath(), e); + } + } + + public static class Config { + @SerializedName("block_entities") + public Map blockEntities; + public Map entities; + + public Config() { + this(new HashMap<>(), new HashMap<>()); + } + + public Config(Map blockEntities, Map entities) { + this.blockEntities = blockEntities; + this.entities = entities; + } + } +} diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java b/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java index 8b01ad009..245614932 100644 --- a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java +++ b/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java @@ -1,11 +1,13 @@ package dev.engine_room.vanillin; -import dev.engine_room.vanillin.visuals.VanillaVisuals; import net.fabricmc.api.ClientModInitializer; public class VanillinFabric implements ClientModInitializer { @Override public void onInitializeClient() { VanillaVisuals.init(); + FabricVanillinConfig.INSTANCE.load(); + FabricVanillinConfig.INSTANCE.apply(VanillaVisuals.CONFIGURATOR); + FabricVanillinConfig.INSTANCE.save(); } } diff --git a/vanillinForge/src/main/java/dev/engine_room/vanillin/ForgeVanillinConfig.java b/vanillinForge/src/main/java/dev/engine_room/vanillin/ForgeVanillinConfig.java new file mode 100644 index 000000000..e3567e41c --- /dev/null +++ b/vanillinForge/src/main/java/dev/engine_room/vanillin/ForgeVanillinConfig.java @@ -0,0 +1,62 @@ +package dev.engine_room.vanillin; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.config.ModConfig; + +public class ForgeVanillinConfig { + public static final ForgeVanillinConfig INSTANCE = new ForgeVanillinConfig(VanillaVisuals.CONFIGURATOR); + + public final Map blockEntities = new HashMap<>(); + public final Map entities = new HashMap<>(); + + private final Configurator configurator; + private final ForgeConfigSpec clientSpec; + + private ForgeVanillinConfig(Configurator configurator) { + this.configurator = configurator; + var builder = new ForgeConfigSpec.Builder(); + + builder.push("block_entities"); + + // Seems like we need to register all field ahead of time so this constructor must run after VanillaVisuals#init + for (var configured : configurator.blockEntities.values()) { + var name = configured.configKey(); + var config = builder.define(name, configured.enabledByDefault()); + blockEntities.put(name, config); + } + + builder.pop(); + builder.push("entities"); + + for (var configured : configurator.entities.values()) { + var name = configured.configKey(); + var config = builder.define(name, configured.defaultEnabled()); + entities.put(name, config); + } + clientSpec = builder.build(); + } + + public void apply() { + for (var configured : configurator.blockEntities.values()) { + var value = blockEntities.get(configured.configKey()); + if (value != null) { + configured.set(value.get()); + } + } + + for (var configured : configurator.entities.values()) { + var value = entities.get(configured.configKey()); + if (value != null) { + configured.set(value.get()); + } + } + } + + public void registerSpecs(ModLoadingContext context) { + context.registerConfig(ModConfig.Type.CLIENT, clientSpec); + } +} diff --git a/vanillinForge/src/main/java/dev/engine_room/vanillin/VanillinForge.java b/vanillinForge/src/main/java/dev/engine_room/vanillin/VanillinForge.java index 7bbe0651b..bffbf0235 100644 --- a/vanillinForge/src/main/java/dev/engine_room/vanillin/VanillinForge.java +++ b/vanillinForge/src/main/java/dev/engine_room/vanillin/VanillinForge.java @@ -1,11 +1,12 @@ package dev.engine_room.vanillin; -import dev.engine_room.vanillin.visuals.VanillaVisuals; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.config.ModConfigEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; @Mod(Vanillin.ID) @@ -14,10 +15,20 @@ public class VanillinForge { IEventBus forgeEventBus = MinecraftForge.EVENT_BUS; IEventBus modEventBus = FMLJavaModLoadingContext.get() .getModEventBus(); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> clientInit(forgeEventBus, modEventBus)); } private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) { VanillaVisuals.init(); + ForgeVanillinConfig.INSTANCE.registerSpecs(ModLoadingContext.get()); + + modEventBus.addListener(event -> { + if (event.getConfig() + .getModId() + .equals(Vanillin.ID)) { + ForgeVanillinConfig.INSTANCE.apply(); + } + }); } }