/* * Minecraft Forge * Copyright (c) 2016-2020. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package net.minecraftforge.event; import java.util.Collection; import java.util.stream.Collectors; import net.minecraftforge.fml.event.lifecycle.IModBusEvent; import org.apache.commons.lang3.Validate; import com.google.common.collect.ImmutableList; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.eventbus.api.GenericEvent; import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.IForgeRegistryEntry; /** * RegistryEvent supertype. */ public class RegistryEvent> extends GenericEvent implements IModBusEvent { RegistryEvent(Class clazz) { super(clazz); } /** * Register new registries when you receive this event, through the {@link RecipeBuilder} */ public static class NewRegistry extends net.minecraftforge.eventbus.api.Event implements IModBusEvent { public NewRegistry(ModContainer mc) {} @Override public String toString() { return "RegistryEvent.NewRegistry"; } } /** * Register your objects for the appropriate registry type when you receive this event. * * event.getRegistry().register(...) * * The registries will be visited in alphabetic order of their name, except blocks and items, * which will be visited FIRST and SECOND respectively. * * ObjectHolders will reload between Blocks and Items, and after all registries have been visited. * @param The registry top level type */ public static class Register> extends RegistryEvent { private final IForgeRegistry registry; private final ResourceLocation name; public Register(ResourceLocation name, IForgeRegistry registry) { super(registry.getRegistrySuperType()); this.name = name; this.registry = registry; } public IForgeRegistry getRegistry() { return registry; } public ResourceLocation getName() { return name; } @Override public String toString() { return "RegistryEvent.Register<"+getName()+">"; } } public static class MissingMappings> extends RegistryEvent { private final IForgeRegistry registry; private final ResourceLocation name; private final ImmutableList> mappings; private ModContainer activeMod; public MissingMappings(ResourceLocation name, IForgeRegistry registry, Collection> missed) { super(registry.getRegistrySuperType()); this.registry = registry; this.name = name; this.mappings = ImmutableList.copyOf(missed); } public void setModContainer(ModContainer mod) { this.activeMod = mod; } public ResourceLocation getName() { return this.name; } public IForgeRegistry getRegistry() { return this.registry; } /* * This used to be fired on the Mod specific bus, and we could tell which mod was asking for mappings. * It no longer is, so this method is useless and just returns getAllMappings. * TODO: Ask cpw how if he wants to re-enable the ModBus rethrow. */ @Deprecated public ImmutableList> getMappings() { return this.activeMod == null ? getAllMappings() : getMappings(this.activeMod.getModId()); } public ImmutableList> getMappings(String modid) { return ImmutableList.copyOf(this.mappings.stream().filter(e -> e.key.getNamespace().equals(modid)).collect(Collectors.toList())); } public ImmutableList> getAllMappings() { return this.mappings; } /** * Actions you can take with this missing mapping. *
    *
  • {@link #IGNORE} means this missing mapping will be ignored. *
  • {@link #WARN} means this missing mapping will generate a warning. *
  • {@link #FAIL} means this missing mapping will prevent the world from loading. *
*/ public enum Action { /** * Take the default action */ DEFAULT, /** * Ignore this missing mapping. This means the mapping will be abandoned */ IGNORE, /** * Generate a warning but allow loading to continue */ WARN, /** * Fail to load */ FAIL, /** * Remap this name to a new name (add a migration mapping) */ REMAP } public static class Mapping> implements Comparable> { public final IForgeRegistry registry; private final IForgeRegistry pool; public final ResourceLocation key; public final int id; private Action action = Action.DEFAULT; private T target; public Mapping(IForgeRegistry registry, IForgeRegistry pool, ResourceLocation key, int id) { this.registry = registry; this.pool = pool; this.key = key; this.id = id; } /** * Ignore the missing item. */ public void ignore() { action = Action.IGNORE; } /** * Warn the user about the missing item. */ public void warn() { action = Action.WARN; } /** * Prevent the world from loading due to the missing item. */ public void fail() { action = Action.FAIL; } /** * Remap the missing entry to the specified object. * * Use this if you have renamed an entry. * Existing references using the old name will point to the new one. * * @param target Entry to remap to. */ public void remap(T target) { Validate.notNull(target, "Remap target can not be null"); Validate.isTrue(pool.getKey(target) != null, String.format("The specified entry %s hasn't been registered in registry yet.", target)); action = Action.REMAP; this.target = target; } // internal public Action getAction() { return this.action; } public T getTarget() { return target; } @Override public int compareTo(Mapping o) { int ret = this.registry.getRegistryName().compareNamespaced(o.registry.getRegistryName()); if (ret ==0) ret = this.key.compareNamespaced(o.key); return ret; } } } }