mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-27 13:27:55 +01:00
Suddenly: mod compat
- Config fields default to "default" and can be either disabled or force enabled via the vanillin config file - Alternatively, mods can set custom properties to disable specific visuals - Emit a warning when a visual is disabled due to mod intervention - Emit a warning when a visual is force enabled despite mod intervention
This commit is contained in:
parent
6d2aab7716
commit
94d99af4b0
11 changed files with 413 additions and 133 deletions
|
@ -1,82 +0,0 @@
|
|||
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<BlockEntityType<?>, ConfiguredBlockEntity<?>> blockEntities = new HashMap<>();
|
||||
public final Map<EntityType<?>, ConfiguredEntity<?>> entities = new HashMap<>();
|
||||
|
||||
public <T extends BlockEntity> void register(BlockEntityType<T> type, BlockEntityVisualizer<? super T> visualizer, boolean enabledByDefault) {
|
||||
blockEntities.put(type, new ConfiguredBlockEntity<>(type, visualizer, enabledByDefault));
|
||||
}
|
||||
|
||||
public <T extends Entity> void register(EntityType<T> type, EntityVisualizer<? super T> visualizer, boolean enabledByDefault) {
|
||||
entities.put(type, new ConfiguredEntity<>(type, visualizer, enabledByDefault));
|
||||
}
|
||||
|
||||
public static class ConfiguredBlockEntity<T extends BlockEntity> {
|
||||
public final BlockEntityType<T> type;
|
||||
public final BlockEntityVisualizer<? super T> visualizer;
|
||||
private final boolean enabledByDefault;
|
||||
|
||||
private ConfiguredBlockEntity(BlockEntityType<T> type, BlockEntityVisualizer<? super T> 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<T extends Entity> {
|
||||
public final EntityType<T> type;
|
||||
public final EntityVisualizer<? super T> visualizer;
|
||||
private final boolean enabledByDefault;
|
||||
|
||||
private ConfiguredEntity(EntityType<T> type, EntityVisualizer<? super T> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
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.SignVisual;
|
||||
import dev.engine_room.vanillin.visuals.TntMinecartVisual;
|
||||
import dev.engine_room.vanillin.config.BlockEntityVisualizerBuilder;
|
||||
import dev.engine_room.vanillin.config.Configurator;
|
||||
import dev.engine_room.vanillin.config.EntityVisualizerBuilder;
|
||||
import dev.engine_room.vanillin.visuals.*;
|
||||
import net.minecraft.client.model.geom.ModelLayers;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package dev.engine_room.vanillin;
|
||||
package dev.engine_room.vanillin.config;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
|
@ -0,0 +1,154 @@
|
|||
package dev.engine_room.vanillin.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
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 dev.engine_room.vanillin.Vanillin;
|
||||
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<BlockEntityType<?>, ConfiguredBlockEntity<?>> blockEntities = new HashMap<>();
|
||||
public final Map<EntityType<?>, ConfiguredEntity<?>> entities = new HashMap<>();
|
||||
|
||||
public <T extends BlockEntity> void register(BlockEntityType<T> type, BlockEntityVisualizer<? super T> visualizer, boolean enabledByDefault) {
|
||||
blockEntities.put(type, new ConfiguredBlockEntity<>(type, visualizer, enabledByDefault));
|
||||
}
|
||||
|
||||
public <T extends Entity> void register(EntityType<T> type, EntityVisualizer<? super T> visualizer, boolean enabledByDefault) {
|
||||
entities.put(type, new ConfiguredEntity<>(type, visualizer, enabledByDefault));
|
||||
}
|
||||
|
||||
public static abstract class ConfiguredVisual {
|
||||
private final boolean enabledByDefault;
|
||||
|
||||
protected ConfiguredVisual(boolean enabledByDefault) {
|
||||
this.enabledByDefault = enabledByDefault;
|
||||
}
|
||||
|
||||
public void set(VisualConfigValue configValue, @Nullable List<VisualOverride> overrides) {
|
||||
if (configValue == VisualConfigValue.DISABLE) {
|
||||
disable();
|
||||
} else if (configValue == VisualConfigValue.FORCE_ENABLE) {
|
||||
enable();
|
||||
maybeWarnEnabledDespiteOverrides(overrides);
|
||||
} else if (configValue == VisualConfigValue.DEFAULT) {
|
||||
if (disableAndWarnDueToOverrides(overrides)) {
|
||||
disable();
|
||||
} else {
|
||||
if (enabledByDefault) {
|
||||
enable();
|
||||
} else {
|
||||
disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean disableAndWarnDueToOverrides(@Nullable List<VisualOverride> overrides) {
|
||||
if (overrides == null || overrides.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var modIds = disablingModIds(overrides);
|
||||
|
||||
if (modIds.isEmpty()) {
|
||||
return false;
|
||||
} else {
|
||||
Vanillin.CONFIG_LOGGER.warn("Disabling {} visual due to overrides from mods: {}", configKey(), String.join(", ", modIds));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeWarnEnabledDespiteOverrides(@Nullable List<VisualOverride> overrides) {
|
||||
if (overrides == null || overrides.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var modIds = disablingModIds(overrides);
|
||||
|
||||
if (!modIds.isEmpty()) {
|
||||
Vanillin.CONFIG_LOGGER.warn("Enabling {} visual despite overrides from mods: {}", configKey(), String.join(", ", modIds));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract String configKey();
|
||||
|
||||
protected abstract void enable();
|
||||
|
||||
protected abstract void disable();
|
||||
|
||||
private static List<String> disablingModIds(List<VisualOverride> overrides) {
|
||||
List<String> out = new ArrayList<>();
|
||||
|
||||
for (VisualOverride override : overrides) {
|
||||
if (override.value() == VisualOverrideValue.DISABLE) {
|
||||
out.add(override.modId());
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConfiguredBlockEntity<T extends BlockEntity> extends ConfiguredVisual {
|
||||
public final BlockEntityType<T> type;
|
||||
public final BlockEntityVisualizer<? super T> visualizer;
|
||||
|
||||
private ConfiguredBlockEntity(BlockEntityType<T> type, BlockEntityVisualizer<? super T> visualizer, boolean enabledByDefault) {
|
||||
super(enabledByDefault);
|
||||
this.type = type;
|
||||
this.visualizer = visualizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String configKey() {
|
||||
return BuiltInRegistries.BLOCK_ENTITY_TYPE.getKey(type).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enable() {
|
||||
VisualizerRegistry.setVisualizer(type, visualizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disable() {
|
||||
VisualizerRegistry.setVisualizer(type, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConfiguredEntity<T extends Entity> extends ConfiguredVisual {
|
||||
public final EntityType<T> type;
|
||||
public final EntityVisualizer<? super T> visualizer;
|
||||
|
||||
private ConfiguredEntity(EntityType<T> type, EntityVisualizer<? super T> visualizer, boolean enabledByDefault) {
|
||||
super(enabledByDefault);
|
||||
this.type = type;
|
||||
this.visualizer = visualizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String configKey() {
|
||||
return BuiltInRegistries.ENTITY_TYPE.getKey(type).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enable() {
|
||||
VisualizerRegistry.setVisualizer(type, visualizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disable() {
|
||||
VisualizerRegistry.setVisualizer(type, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.engine_room.vanillin;
|
||||
package dev.engine_room.vanillin.config;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
|
@ -0,0 +1,15 @@
|
|||
package dev.engine_room.vanillin.config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public record ModOverrides(Map<String, List<VisualOverride>> blockEntities, Map<String, List<VisualOverride>> entities) {
|
||||
public ModOverrides(List<VisualOverride> blockEntities, List<VisualOverride> entities) {
|
||||
this(sort(blockEntities), sort(entities));
|
||||
}
|
||||
|
||||
public static Map<String, List<VisualOverride>> sort(List<VisualOverride> list) {
|
||||
return list.stream().collect(Collectors.groupingBy(VisualOverride::name));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package dev.engine_room.vanillin.config;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public enum VisualConfigValue {
|
||||
@SerializedName("default")
|
||||
DEFAULT,
|
||||
@SerializedName("disable")
|
||||
DISABLE,
|
||||
@SerializedName("force_enable")
|
||||
FORCE_ENABLE,
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package dev.engine_room.vanillin.config;
|
||||
|
||||
public record VisualOverride(String name, String modId, VisualOverrideValue value) {
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package dev.engine_room.vanillin.config;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public enum VisualOverrideValue {
|
||||
DEFAULT,
|
||||
DISABLE,
|
||||
;
|
||||
|
||||
@Nullable
|
||||
public static VisualOverrideValue parse(String string) {
|
||||
if (string.equals("default")) {
|
||||
return DEFAULT;
|
||||
} else if (string.equals("disable")) {
|
||||
return DISABLE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -4,14 +4,24 @@ import java.io.File;
|
|||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import dev.engine_room.vanillin.config.Configurator;
|
||||
import dev.engine_room.vanillin.config.ModOverrides;
|
||||
import dev.engine_room.vanillin.config.VisualConfigValue;
|
||||
import dev.engine_room.vanillin.config.VisualOverride;
|
||||
import dev.engine_room.vanillin.config.VisualOverrideValue;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.fabricmc.loader.api.metadata.CustomValue;
|
||||
import net.fabricmc.loader.api.metadata.ModMetadata;
|
||||
|
||||
public class FabricVanillinConfig {
|
||||
public static final Path PATH = FabricLoader.getInstance()
|
||||
|
@ -21,10 +31,12 @@ public class FabricVanillinConfig {
|
|||
public static final FabricVanillinConfig INSTANCE = new FabricVanillinConfig(PATH.toFile());
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
public static final String VANILLIN_OVERRIDES = "vanillin:overrides";
|
||||
|
||||
private final File file;
|
||||
|
||||
private Config config;
|
||||
private ModOverrides overrides;
|
||||
private Config config = new Config();
|
||||
|
||||
public FabricVanillinConfig(File file) {
|
||||
this.file = file;
|
||||
|
@ -36,23 +48,34 @@ public class FabricVanillinConfig {
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
||||
overrides = modOverrides();
|
||||
}
|
||||
|
||||
public void apply(Configurator configurator) {
|
||||
for (Configurator.ConfiguredBlockEntity<?> configuredBlockEntity : configurator.blockEntities.values()) {
|
||||
boolean enabled = config.blockEntities.computeIfAbsent(configuredBlockEntity.configKey(), $ -> configuredBlockEntity.enabledByDefault());
|
||||
configuredBlockEntity.set(enabled);
|
||||
var blockEntities = config.blockEntities;
|
||||
var blockEntityOverrides = this.overrides.blockEntities();
|
||||
|
||||
for (Configurator.ConfiguredVisual configured : configurator.blockEntities.values()) {
|
||||
apply(configured, blockEntities, blockEntityOverrides);
|
||||
}
|
||||
|
||||
for (Configurator.ConfiguredEntity<?> configured : configurator.entities.values()) {
|
||||
boolean enabled = config.entities.computeIfAbsent(configured.configKey(), $ -> configured.defaultEnabled());
|
||||
configured.set(enabled);
|
||||
var entities = config.entities;
|
||||
var entityOverrides = this.overrides.entities();
|
||||
for (Configurator.ConfiguredVisual configured : configurator.entities.values()) {
|
||||
apply(configured, entities, entityOverrides);
|
||||
}
|
||||
}
|
||||
|
||||
private static void apply(Configurator.ConfiguredVisual configured, Map<String, VisualConfigValue> config, Map<String, List<VisualOverride>> overrides) {
|
||||
var key = configured.configKey();
|
||||
var enabled = config.computeIfAbsent(key, $ -> VisualConfigValue.DEFAULT);
|
||||
|
||||
configured.set(enabled, overrides.get(key));
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
GSON.toJson(config, writer);
|
||||
|
@ -61,16 +84,75 @@ public class FabricVanillinConfig {
|
|||
}
|
||||
}
|
||||
|
||||
public static ModOverrides modOverrides() {
|
||||
var blockEntities = new ArrayList<VisualOverride>();
|
||||
var entities = new ArrayList<VisualOverride>();
|
||||
|
||||
for (ModContainer container : FabricLoader.getInstance().getAllMods()) {
|
||||
ModMetadata meta = container.getMetadata();
|
||||
var modid = meta.getId();
|
||||
|
||||
if (meta.containsCustomValue(VANILLIN_OVERRIDES)) {
|
||||
CustomValue overridesValue = meta.getCustomValue(VANILLIN_OVERRIDES);
|
||||
|
||||
if (overridesValue.getType() != CustomValue.CvType.OBJECT) {
|
||||
Vanillin.CONFIG_LOGGER.warn("Mod '{}' attempted to override options with an invalid value, ignoring", modid);
|
||||
continue;
|
||||
}
|
||||
|
||||
var overrides = overridesValue.getAsObject();
|
||||
|
||||
readSection(blockEntities, modid, overrides, "block_entities", "block entity");
|
||||
readSection(entities, modid, overrides, "entities", "entity");
|
||||
}
|
||||
}
|
||||
|
||||
return new ModOverrides(blockEntities, entities);
|
||||
}
|
||||
|
||||
private static void readSection(List<VisualOverride> dst, String modid, CustomValue.CvObject overrides, String sectionName, String singular) {
|
||||
if (!overrides.containsKey(sectionName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var section = overrides.get(sectionName);
|
||||
|
||||
if (section.getType() != CustomValue.CvType.OBJECT) {
|
||||
Vanillin.CONFIG_LOGGER.warn("Mod '{}' attempted to override {} with an invalid value, ignoring", modid, sectionName);
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<String, CustomValue> entry : section.getAsObject()) {
|
||||
var value = entry.getValue();
|
||||
var key = entry.getKey();
|
||||
if (value.getType() != CustomValue.CvType.STRING) {
|
||||
Vanillin.CONFIG_LOGGER.warn("Mod '{}' attempted to override {} '{}' with an invalid value, ignoring", modid, singular, key);
|
||||
continue;
|
||||
}
|
||||
|
||||
var valueString = value.getAsString();
|
||||
|
||||
var parsed = VisualOverrideValue.parse(valueString);
|
||||
|
||||
if (parsed == null) {
|
||||
Vanillin.CONFIG_LOGGER.warn("Mod '{}' attempted to override {} '{}' with an invalid value '{}', ignoring", modid, singular, key, valueString);
|
||||
continue;
|
||||
}
|
||||
|
||||
dst.add(new VisualOverride(key, modid, parsed));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Config {
|
||||
@SerializedName("block_entities")
|
||||
public Map<String, Boolean> blockEntities;
|
||||
public Map<String, Boolean> entities;
|
||||
public Map<String, VisualConfigValue> blockEntities;
|
||||
public Map<String, VisualConfigValue> entities;
|
||||
|
||||
public Config() {
|
||||
this(new HashMap<>(), new HashMap<>());
|
||||
}
|
||||
|
||||
public Config(Map<String, Boolean> blockEntities, Map<String, Boolean> entities) {
|
||||
public Config(Map<String, VisualConfigValue> blockEntities, Map<String, VisualConfigValue> entities) {
|
||||
this.blockEntities = blockEntities;
|
||||
this.entities = entities;
|
||||
}
|
||||
|
|
|
@ -1,62 +1,140 @@
|
|||
package dev.engine_room.vanillin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.electronwill.nightconfig.core.Config;
|
||||
|
||||
import dev.engine_room.vanillin.config.Configurator;
|
||||
import dev.engine_room.vanillin.config.ModOverrides;
|
||||
import dev.engine_room.vanillin.config.VisualConfigValue;
|
||||
import dev.engine_room.vanillin.config.VisualOverride;
|
||||
import dev.engine_room.vanillin.config.VisualOverrideValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
|
||||
public class ForgeVanillinConfig {
|
||||
public static final ForgeVanillinConfig INSTANCE = new ForgeVanillinConfig(VanillaVisuals.CONFIGURATOR);
|
||||
|
||||
public final Map<String, ForgeConfigSpec.BooleanValue> blockEntities = new HashMap<>();
|
||||
public final Map<String, ForgeConfigSpec.BooleanValue> entities = new HashMap<>();
|
||||
|
||||
private final Configurator configurator;
|
||||
private final ForgeConfigSpec clientSpec;
|
||||
|
||||
private final ConfigSection blockEntities;
|
||||
private final ConfigSection entities;
|
||||
|
||||
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);
|
||||
}
|
||||
var blockEntities = setup(builder, configurator.blockEntities.values(), "block_entities");
|
||||
var entities = setup(builder, configurator.entities.values(), "entities");
|
||||
clientSpec = builder.build();
|
||||
|
||||
var modOverrides = modOverrides();
|
||||
|
||||
this.blockEntities = new ConfigSection(blockEntities, modOverrides.blockEntities());
|
||||
this.entities = new ConfigSection(entities, modOverrides.entities());
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
blockEntities.apply(configurator.blockEntities.values());
|
||||
entities.apply(configurator.entities.values());
|
||||
}
|
||||
|
||||
public void registerSpecs(ModLoadingContext context) {
|
||||
context.registerConfig(ModConfig.Type.CLIENT, clientSpec);
|
||||
}
|
||||
|
||||
private static ModOverrides modOverrides() {
|
||||
var blockEntities = new ArrayList<VisualOverride>();
|
||||
var entities = new ArrayList<VisualOverride>();
|
||||
|
||||
ModList.get()
|
||||
.forEachModFile(file -> {
|
||||
var info = file.getModFileInfo();
|
||||
for (IModInfo mod : info.getMods()) {
|
||||
var modId = mod.getModId();
|
||||
var modProperties = mod.getModProperties()
|
||||
.get("vanillin:overrides");
|
||||
|
||||
if (modProperties == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// There's no well-defined API for custom properties like in fabric.
|
||||
// It just returns an object, but internally it's represented with nightconfig.
|
||||
if (modProperties instanceof Config config) {
|
||||
readSection(blockEntities, modId, config, "block_entities", "block entity");
|
||||
readSection(entities, modId, config, "entities", "entity");
|
||||
} else {
|
||||
Vanillin.CONFIG_LOGGER.warn("Mod '{}' attempted to override options with an invalid value, ignoring", modId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return new ModOverrides(blockEntities, entities);
|
||||
}
|
||||
|
||||
private static void readSection(List<VisualOverride> dst, String modId, Config config, String section, String singular) {
|
||||
if (!config.contains(section)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var sectionObject = config.getRaw(section);
|
||||
|
||||
if (sectionObject instanceof Config sectionConfig) {
|
||||
for (var entry : sectionConfig.entrySet()) {
|
||||
var key = entry.getKey();
|
||||
var value = entry.getValue();
|
||||
|
||||
if (value instanceof String valueString) {
|
||||
var parsed = VisualOverrideValue.parse(valueString);
|
||||
|
||||
if (parsed != null) {
|
||||
dst.add(new VisualOverride(key, modId, parsed));
|
||||
} else {
|
||||
Vanillin.CONFIG_LOGGER.warn("Mod '{}' attempted to override {} '{}' with an invalid value '{}', ignoring", modId, singular, key, valueString);
|
||||
}
|
||||
} else {
|
||||
Vanillin.CONFIG_LOGGER.warn("Mod '{}' attempted to override {} '{}' with an invalid value, ignoring", modId, singular, key);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Vanillin.CONFIG_LOGGER.warn("Mod '{}' attempted to override {} with an invalid value, ignoring", modId, section);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, ForgeConfigSpec.EnumValue<VisualConfigValue>> setup(ForgeConfigSpec.Builder builder, Collection<? extends Configurator.ConfiguredVisual> configuredVisuals, String push) {
|
||||
var out = new HashMap<String, ForgeConfigSpec.EnumValue<VisualConfigValue>>();
|
||||
builder.push(push);
|
||||
|
||||
for (var configured : configuredVisuals) {
|
||||
var name = configured.configKey();
|
||||
var config = builder.defineEnum(name, VisualConfigValue.DEFAULT);
|
||||
out.put(name, config);
|
||||
}
|
||||
|
||||
builder.pop();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private record ConfigSection(Map<String, ForgeConfigSpec.EnumValue<VisualConfigValue>> config, Map<String, List<VisualOverride>> overrides) {
|
||||
void apply(Collection<? extends Configurator.ConfiguredVisual> values) {
|
||||
for (var configured : values) {
|
||||
var key = configured.configKey();
|
||||
var value = config.get(key);
|
||||
if (value != null) {
|
||||
configured.set(value.get(), overrides.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue