package eu.abdelbaki.cmmodular; import java.util.List; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.repository.PackSource; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.ModList; import net.neoforged.fml.common.Mod; import net.neoforged.neoforge.event.AddPackFindersEvent; /** * Adds the materials of Create, Mekanism, Ice and Fire, Immersive Engineering, * Iron's Spells and the Create aerospace addons to Truly Modular. * *

Almost all of this mod is data. The one thing data cannot do is load * conditionally: MIAPI reads materials with its own loader, which honours * neither {@code neoforge:conditions} nor anything else that could switch a * file off, and a material whose ingredient item does not exist fails to parse * outright. So each source mod's materials live in their own built-in datapack * and only get registered when that mod is actually installed. * *

Where two mods add the same metal - steel, lead and uranium are in both * Mekanism and Immersive Engineering, silver in both Ice and Fire and Immersive * Engineering, titanium in both aerospace addons - one of them is simply picked * as the provider rather than the material accepting either. That keeps one * entry per metal in the crafting screen. */ @Mod(CMModular.MOD_ID) public class CMModular { public static final String MOD_ID = "cmmodular"; /** A built-in datapack - materials or modules - and the mod it needs. */ private record MaterialPack(String id, String name, String requires) { boolean present() { return ModList.get().isLoaded(requires); } } private static final List PACKS = List.of( new MaterialPack("mekanism", "Mekanism Materials", "mekanism"), new MaterialPack("create", "Create Materials", "create"), new MaterialPack("iceandfire", "Ice and Fire Materials", "iceandfire"), new MaterialPack("immersiveengineering", "Immersive Engineering Materials", "immersiveengineering"), new MaterialPack("irons_spellbooks", "Iron's Spells Materials", "irons_spellbooks"), new MaterialPack("interstellar", "Interstellar Expansion Materials", "vsie"), new MaterialPack("air_war", "Create: The Air War Materials", "create_the_air_wars"), new MaterialPack("cosmonautics", "Create: Cosmonautics Materials", "rocketnautics"), new MaterialPack("enderio", "Ender IO Materials", "enderio"), new MaterialPack("ae2", "Applied Energistics Materials", "ae2"), new MaterialPack("ars_nouveau", "Ars Nouveau Materials", "ars_nouveau"), new MaterialPack("occultism", "Occultism Materials", "occultism"), new MaterialPack("industrialforegoing", "Industrial Foregoing Materials", "industrialforegoing"), new MaterialPack("nautec", "NauTec Materials", "nautec"), new MaterialPack("superbwarfare", "Superb Warfare Materials", "superbwarfare"), new MaterialPack("steampunkdimension", "Steampunk Dimension Materials", "steampunkdimension"), new MaterialPack("rftoolsbase", "RFTools Materials", "rftoolsbase"), new MaterialPack("createdeco", "Create Deco Materials", "createdeco"), new MaterialPack("crystal_chronicles", "Crystal Chronicles Materials", "crystal_chronicles"), new MaterialPack("pastel", "Pastel Materials", "pastel"), new MaterialPack("createpropulsion", "Create Propulsion Materials", "createpropulsion"), new MaterialPack("aeroengineering", "AeroEngine Materials", "aeroengineering"), new MaterialPack("create_wizardry", "Create Wizardry Materials", "create_wizardry"), // Modules, not materials, and gated for the same reason: they name // slots - and inherit modules - that only exist with these installed. new MaterialPack("arsenal", "Arsenal Modules", "tm_arsenal"), new MaterialPack("armory", "Armory Modules", "tm_armory")); public CMModular(IEventBus modBus) { FireImmunity.register(modBus); VacuumSeal.register(modBus); modBus.addListener(this::addMaterialPacks); } private void addMaterialPacks(AddPackFindersEvent event) { if (event.getPackType() != PackType.SERVER_DATA) { return; } for (MaterialPack pack : PACKS) { if (!pack.present()) { continue; } event.addPackFinders( ResourceLocation.fromNamespaceAndPath(MOD_ID, "packs/" + pack.id()), PackType.SERVER_DATA, Component.literal(pack.name()), PackSource.BUILT_IN, // Always on and above the base pack, so a material extension // lands on top of the material it extends. true, Pack.Position.TOP); } } }