package dev.micle.xptools.config; import dev.micle.xptools.XpTools; import dev.micle.xptools.operation.GlobalOperationItem; import dev.micle.xptools.operation.OperationCache; import dev.micle.xptools.operation.OperationItem; import dev.micle.xptools.operation.OperationType; import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.config.ModConfigEvent; import org.apache.commons.lang3.tuple.Pair; import java.util.*; @Mod.EventBusSubscriber(modid = XpTools.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) public final class Config { public static final Client CLIENT; public static final ForgeConfigSpec CLIENT_SPEC; public static final Common COMMON; public static final ForgeConfigSpec COMMON_SPEC; public static final Server SERVER; public static final ForgeConfigSpec SERVER_SPEC; static { Pair clientSpecPair = new ForgeConfigSpec.Builder().configure(Client::new); CLIENT = clientSpecPair.getLeft(); CLIENT_SPEC = clientSpecPair.getRight(); Pair commonSpecPair = new ForgeConfigSpec.Builder().configure(Common::new); COMMON = commonSpecPair.getLeft(); COMMON_SPEC = commonSpecPair.getRight(); Pair serverSpecPair = new ForgeConfigSpec.Builder().configure(Server::new); SERVER = serverSpecPair.getLeft(); SERVER_SPEC = serverSpecPair.getRight(); } public static void register() { XpTools.getFMLJavaModLoadingContext().registerConfig(ModConfig.Type.CLIENT, CLIENT_SPEC); XpTools.getFMLJavaModLoadingContext().registerConfig(ModConfig.Type.COMMON, COMMON_SPEC); XpTools.getFMLJavaModLoadingContext().registerConfig(ModConfig.Type.SERVER, SERVER_SPEC); } @SubscribeEvent public static void onConfigReloadEvent(ModConfigEvent event) { if (event.getConfig().getSpec() == CLIENT_SPEC) { Client.onConfigReload(); } else if (event.getConfig().getSpec() == COMMON_SPEC) { Common.onConfigReload(); } else if (event.getConfig().getSpec() == SERVER_SPEC) { Server.onConfigReload(); } } public static class Client { Client(ForgeConfigSpec.Builder builder) {} private static void onConfigReload() {} } public static class Common { Common(ForgeConfigSpec.Builder builder) {} private static void onConfigReload() {} } public static class Server { public static ForgeConfigSpec.BooleanValue debugExtra; public static ForgeConfigSpec.BooleanValue optimizationUseCache; private static ForgeConfigSpec.ConfigValue> blockBreakGlobalOperationsRaw; public static List blockBreakGlobalOperationItems; private static ForgeConfigSpec.ConfigValue> blockBreakOperationsRaw; public static List blockBreakOperationItems; private static ForgeConfigSpec.ConfigValue> entityKillGlobalOperationsRaw; public static List entityKillGlobalOperationItems; private static ForgeConfigSpec.ConfigValue> entityKillOperationsRaw; public static List entityKillOperationItems; Server(ForgeConfigSpec.Builder builder) { builder.comment("Settings for debugging").push("debug"); debugExtra = builder .comment("Whether to log more extensive debug information.") .define("debugExtra", false); builder.pop(); builder.comment("Settings for optimizations").push("optimization"); optimizationUseCache = builder .comment("Allows saving lists of operations per unique id (block_id/entity_id etc.).") .comment("This will speed up getting the order of operations after the initial calculation.") .comment("The downside is that it uses more RAM of course (I don't know how much), while it shouldn't be a lot it might not be worth it if you don't have many operations.") .comment("The cache is not persistent and gets cleared whenever the config gets reloaded.") .define("optimizationUseCache", false); builder.pop(); builder.comment("Settings for block breaking").push("block_breaking"); builder.comment("Available operations: " + Arrays.toString(OperationType.values())); blockBreakGlobalOperationsRaw = builder .comment("List of global operations. Format: '[operation],[min],[max],[priority]'") .comment("Global operations are run before any unique operations.") .comment("Examples:") .comment("'set,0,0,0' - Sets the xp of all blocks to 0.") .define("blockBreakGlobalOperations", new ArrayList<>()); blockBreakOperationsRaw = builder .comment("List of unique operations. Format: '[block_id/tag_id],[operation],[min],[max],[priority],[is_last]'") .comment("Examples:") .comment("'minecraft:dirt,set,2,2,0,true' - Sets the xp drop of the dirt block to 2, takes highest priority and stops any additional operations.") .comment("'#forge:ores,multiply,1,2,1,false' - Multiplies xp drop of all blocks tagged forge:ores by 1-2, allows additional operations.") .define("blockBreakOperations", new ArrayList<>()); builder.pop(); builder.comment("Settings for entity killing").push("entity_killing"); builder.comment("Available operations: " + Arrays.toString(OperationType.values())); entityKillGlobalOperationsRaw = builder .comment("List of global operations. Format: '[operation],[min],[max],[priority]'") .comment("Global operations are run before any unique operations.") .comment("Examples:") .comment("'set,0,0,0' - Sets the xp of all entities to 0.") .define("entityKillGlobalOperations", new ArrayList<>()); entityKillOperationsRaw = builder .comment("List of unique operations. Format: '[entity_id/tag_id],[operation],[min],[max],[priority],[is_last]'") .comment("Examples:") .comment("'minecraft:creeper,set,2,2,0,true' - Sets the xp drop for killing creepers to 2, takes highest priority and stops any additional operations.") .comment("'#some_mod:some_tag,multiply,1,2,1,false' - Multiplies the xp drop for killing all entities tagged some_mod:some_tag by 1-2, allows additional operations.") .define("entityKillOperations", new ArrayList<>()); builder.pop(); } private static void onConfigReload() { // Clear cache OperationCache.blockBreakCache.clear(); OperationCache.entityKillCache.clear(); // Parse all block break global operations blockBreakGlobalOperationItems = new ArrayList<>(); for (String s : blockBreakGlobalOperationsRaw.get()) { blockBreakGlobalOperationItems.add(GlobalOperationItem.fromConfig(s)); } blockBreakGlobalOperationItems.sort(Comparator.comparingInt(OperationItem::getPriority)); // Parse all block break unique operations blockBreakOperationItems = new ArrayList<>(); for (String s : blockBreakOperationsRaw.get()) { blockBreakOperationItems.add(OperationItem.fromConfig(s)); } // Parse all entity kill global operations entityKillGlobalOperationItems = new ArrayList<>(); for (String s : entityKillGlobalOperationsRaw.get()) { entityKillGlobalOperationItems.add(GlobalOperationItem.fromConfig(s)); } entityKillGlobalOperationItems.sort(Comparator.comparingInt(OperationItem::getPriority)); // Parse all entity kill unique operations entityKillOperationItems = new ArrayList<>(); for (String s : entityKillOperationsRaw.get()) { entityKillOperationItems.add(OperationItem.fromConfig(s)); } } } }