/* * Forge Mod Loader * Copyright (c) 2012-2013 cpw. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * cpw - implementation */ package cpw.mods.fml.common.registry; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Random; import net.minecraft.entity.passive.EntityVillager; import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Tuple; import net.minecraft.village.MerchantRecipeList; import net.minecraft.world.gen.structure.StructureVillagePieces; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; /** * Registry for villager trading control * * @author cpw * */ public class VillagerRegistry { private static final VillagerRegistry INSTANCE = new VillagerRegistry(); private Multimap<Integer, IVillageTradeHandler> tradeHandlers = ArrayListMultimap.create(); private Map<Class<?>, IVillageCreationHandler> villageCreationHandlers = Maps.newHashMap(); private List<Integer> newVillagerIds = Lists.newArrayList(); @SideOnly(Side.CLIENT) private Map<Integer, ResourceLocation> newVillagers; /** * Allow access to the {@link net.minecraft.world.gen.structure.StructureVillagePieces} array controlling new village * creation so you can insert your own new village pieces * * @author cpw * */ public interface IVillageCreationHandler { /** * Called when {@link net.minecraft.world.gen.structure.MapGenVillage} is creating a new village * * @param random * @param i */ StructureVillagePieces.PieceWeight getVillagePieceWeight(Random random, int i); /** * The class of the root structure component to add to the village */ Class<?> getComponentClass(); /** * Build an instance of the village component {@link net.minecraft.world.gen.structure.StructureVillagePieces} * @param villagePiece * @param startPiece * @param pieces * @param random * @param p1 * @param p2 * @param p3 * @param p4 * @param p5 */ Object buildComponent(StructureVillagePieces.PieceWeight villagePiece, StructureVillagePieces.Start startPiece, @SuppressWarnings("rawtypes") List pieces, Random random, int p1, int p2, int p3, int p4, int p5); } /** * Allow access to the {@link MerchantRecipeList} for a villager type for manipulation * * @author cpw * */ public interface IVillageTradeHandler { /** * Called to allow changing the content of the {@link MerchantRecipeList} for the villager * supplied during creation * * @param villager * @param recipeList */ void manipulateTradesForVillager(EntityVillager villager, MerchantRecipeList recipeList, Random random); } public static VillagerRegistry instance() { return INSTANCE; } /** * Register your villager id * @param id */ public void registerVillagerId(int id) { if (newVillagerIds.contains(id)) { FMLLog.severe("Attempt to register duplicate villager id %d", id); throw new RuntimeException(); } newVillagerIds.add(id); } /** * Register a new skin for a villager type * * @param villagerId * @param villagerSkin */ @SideOnly(Side.CLIENT) public void registerVillagerSkin(int villagerId, ResourceLocation villagerSkin) { if (newVillagers == null) { newVillagers = Maps.newHashMap(); } newVillagers.put(villagerId, villagerSkin); } /** * Register a new village creation handler * * @param handler */ public void registerVillageCreationHandler(IVillageCreationHandler handler) { villageCreationHandlers.put(handler.getComponentClass(), handler); } /** * Register a new villager trading handler for the specified villager type * * @param villagerId * @param handler */ public void registerVillageTradeHandler(int villagerId, IVillageTradeHandler handler) { tradeHandlers.put(villagerId, handler); } /** * Callback to setup new villager types * * @param villagerType * @param defaultSkin */ @SideOnly(Side.CLIENT) public static ResourceLocation getVillagerSkin(int villagerType, ResourceLocation defaultSkin) { if (instance().newVillagers != null && instance().newVillagers.containsKey(villagerType)) { return instance().newVillagers.get(villagerType); } return defaultSkin; } /** * Returns a list of all added villager types * * @return newVillagerIds */ public static Collection<Integer> getRegisteredVillagers() { return Collections.unmodifiableCollection(instance().newVillagerIds); } /** * Callback to handle trade setup for villagers * * @param recipeList * @param villager * @param villagerType * @param random */ public static void manageVillagerTrades(MerchantRecipeList recipeList, EntityVillager villager, int villagerType, Random random) { for (IVillageTradeHandler handler : instance().tradeHandlers.get(villagerType)) { handler.manipulateTradesForVillager(villager, recipeList, random); } } public static void addExtraVillageComponents(@SuppressWarnings("rawtypes") ArrayList components, Random random, int i) { @SuppressWarnings("unchecked") List<StructureVillagePieces.PieceWeight> parts = components; for (IVillageCreationHandler handler : instance().villageCreationHandlers.values()) { parts.add(handler.getVillagePieceWeight(random, i)); } } public static Object getVillageComponent(StructureVillagePieces.PieceWeight villagePiece, StructureVillagePieces.Start startPiece, @SuppressWarnings("rawtypes") List pieces, Random random, int p1, int p2, int p3, int p4, int p5) { return instance().villageCreationHandlers.get(villagePiece.villagePieceClass).buildComponent(villagePiece, startPiece, pieces, random, p1, p2, p3, p4, p5); } @SuppressWarnings("unchecked") public static void addEmeraldBuyRecipe(EntityVillager villager, MerchantRecipeList list, Random random, Item item, float chance, int min, int max) { if (min > 0 && max > 0) { EntityVillager.villagersSellingList.put(item, new Tuple(min, max)); } EntityVillager.func_146091_a(list, item, random, chance); } @SuppressWarnings("unchecked") public static void addEmeraldSellRecipe(EntityVillager villager, MerchantRecipeList list, Random random, Item item, float chance, int min, int max) { if (min > 0 && max > 0) { EntityVillager.blacksmithSellingList.put(item, new Tuple(min, max)); } EntityVillager.func_146089_b(list, item, random, chance); } public static void applyRandomTrade(EntityVillager villager, Random rand) { int extra = instance().newVillagerIds.size(); int trade = rand.nextInt(5 + extra); villager.setProfession(trade < 5 ? trade : instance().newVillagerIds.get(trade - 5)); } }