001/* 002 * Forge Mod Loader 003 * Copyright (c) 2012-2013 cpw. 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser Public License v2.1 006 * which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 008 * 009 * Contributors: 010 * cpw - implementation 011 */ 012 013package cpw.mods.fml.common.registry; 014 015import java.util.ArrayList; 016import java.util.List; 017import java.util.Map; 018import java.util.Random; 019import java.util.Collection; 020import java.util.Collections; 021 022import net.minecraft.entity.passive.EntityVillager; 023import net.minecraft.item.Item; 024import net.minecraft.util.Tuple; 025import net.minecraft.village.MerchantRecipeList; 026import net.minecraft.world.gen.structure.ComponentVillageStartPiece; 027import net.minecraft.world.gen.structure.StructureVillagePieceWeight; 028 029import com.google.common.collect.ArrayListMultimap; 030import com.google.common.collect.Lists; 031import com.google.common.collect.Maps; 032import com.google.common.collect.Multimap; 033 034import cpw.mods.fml.common.FMLLog; 035 036/** 037 * Registry for villager trading control 038 * 039 * @author cpw 040 * 041 */ 042public class VillagerRegistry 043{ 044 private static final VillagerRegistry INSTANCE = new VillagerRegistry(); 045 046 private Multimap<Integer, IVillageTradeHandler> tradeHandlers = ArrayListMultimap.create(); 047 private Map<Class<?>, IVillageCreationHandler> villageCreationHandlers = Maps.newHashMap(); 048 private Map<Integer, String> newVillagers = Maps.newHashMap(); 049 private List<Integer> newVillagerIds = Lists.newArrayList(); 050 051 /** 052 * Allow access to the {@link net.minecraft.world.gen.structure.StructureVillagePieces} array controlling new village 053 * creation so you can insert your own new village pieces 054 * 055 * @author cpw 056 * 057 */ 058 public interface IVillageCreationHandler 059 { 060 /** 061 * Called when {@link net.minecraft.world.gen.structure.MapGenVillage} is creating a new village 062 * 063 * @param random 064 * @param i 065 */ 066 StructureVillagePieceWeight getVillagePieceWeight(Random random, int i); 067 068 /** 069 * The class of the root structure component to add to the village 070 */ 071 Class<?> getComponentClass(); 072 073 074 /** 075 * Build an instance of the village component {@link net.minecraft.world.gen.structure.StructureVillagePieces} 076 * @param villagePiece 077 * @param startPiece 078 * @param pieces 079 * @param random 080 * @param p1 081 * @param p2 082 * @param p3 083 * @param p4 084 * @param p5 085 */ 086 Object buildComponent(StructureVillagePieceWeight villagePiece, ComponentVillageStartPiece startPiece, List pieces, Random random, int p1, 087 int p2, int p3, int p4, int p5); 088 } 089 090 /** 091 * Allow access to the {@link MerchantRecipeList} for a villager type for manipulation 092 * 093 * @author cpw 094 * 095 */ 096 public interface IVillageTradeHandler 097 { 098 /** 099 * Called to allow changing the content of the {@link MerchantRecipeList} for the villager 100 * supplied during creation 101 * 102 * @param villager 103 * @param recipeList 104 */ 105 void manipulateTradesForVillager(EntityVillager villager, MerchantRecipeList recipeList, Random random); 106 } 107 108 public static VillagerRegistry instance() 109 { 110 return INSTANCE; 111 } 112 113 /** 114 * Register a new skin for a villager type 115 * 116 * @param villagerId 117 * @param villagerSkin 118 */ 119 public void registerVillagerType(int villagerId, String villagerSkin) 120 { 121 if (newVillagers.containsKey(villagerId)) 122 { 123 FMLLog.severe("Attempt to register duplicate villager id %d", villagerId); 124 throw new RuntimeException(); 125 } 126 newVillagers.put(villagerId, villagerSkin); 127 newVillagerIds.add(villagerId); 128 } 129 130 /** 131 * Register a new village creation handler 132 * 133 * @param handler 134 */ 135 public void registerVillageCreationHandler(IVillageCreationHandler handler) 136 { 137 villageCreationHandlers.put(handler.getComponentClass(), handler); 138 } 139 140 /** 141 * Register a new villager trading handler for the specified villager type 142 * 143 * @param villagerId 144 * @param handler 145 */ 146 public void registerVillageTradeHandler(int villagerId, IVillageTradeHandler handler) 147 { 148 tradeHandlers.put(villagerId, handler); 149 } 150 151 /** 152 * Callback to setup new villager types 153 * 154 * @param villagerType 155 * @param defaultSkin 156 */ 157 public static String getVillagerSkin(int villagerType, String defaultSkin) 158 { 159 if (instance().newVillagers.containsKey(villagerType)) 160 { 161 return instance().newVillagers.get(villagerType); 162 } 163 return defaultSkin; 164 } 165 166 /** 167 * Returns a list of all added villager types 168 * 169 * @return newVillagerIds 170 */ 171 public static Collection<Integer> getRegisteredVillagers() 172 { 173 return Collections.unmodifiableCollection(instance().newVillagerIds); 174 } 175 /** 176 * Callback to handle trade setup for villagers 177 * 178 * @param recipeList 179 * @param villager 180 * @param villagerType 181 * @param random 182 */ 183 public static void manageVillagerTrades(MerchantRecipeList recipeList, EntityVillager villager, int villagerType, Random random) 184 { 185 for (IVillageTradeHandler handler : instance().tradeHandlers.get(villagerType)) 186 { 187 handler.manipulateTradesForVillager(villager, recipeList, random); 188 } 189 } 190 191 public static void addExtraVillageComponents(ArrayList components, Random random, int i) 192 { 193 List<StructureVillagePieceWeight> parts = components; 194 for (IVillageCreationHandler handler : instance().villageCreationHandlers.values()) 195 { 196 parts.add(handler.getVillagePieceWeight(random, i)); 197 } 198 } 199 200 public static Object getVillageComponent(StructureVillagePieceWeight villagePiece, ComponentVillageStartPiece startPiece, List pieces, Random random, 201 int p1, int p2, int p3, int p4, int p5) 202 { 203 return instance().villageCreationHandlers.get(villagePiece.villagePieceClass).buildComponent(villagePiece, startPiece, pieces, random, p1, p2, p3, p4, p5); 204 } 205 206 207 public static void addEmeraldBuyRecipe(EntityVillager villager, MerchantRecipeList list, Random random, Item item, float chance, int min, int max) 208 { 209 if (min > 0 && max > 0) 210 { 211 EntityVillager.villagerStockList.put(item.itemID, new Tuple(min, max)); 212 } 213 villager.addMerchantItem(list, item.getMaxDamage(), random, chance); 214 } 215 216 public static void addEmeraldSellRecipe(EntityVillager villager, MerchantRecipeList list, Random random, Item item, float chance, int min, int max) 217 { 218 if (min > 0 && max > 0) 219 { 220 EntityVillager.blacksmithSellingList.put(item.itemID, new Tuple(min, max)); 221 } 222 villager.addBlacksmithItem(list, item.getMaxDamage(), random, chance); 223 } 224 225 public static void applyRandomTrade(EntityVillager villager, Random rand) 226 { 227 int extra = instance().newVillagerIds.size(); 228 int trade = rand.nextInt(5 + extra); 229 villager.setProfession(trade < 5 ? trade : instance().newVillagerIds.get(trade - 5)); 230 } 231}