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