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