    001    package cpw.mods.fml.common.registry;
    002
    003    import java.util.List;
    004    import java.util.Random;
    005    import java.util.Set;
    006    import java.util.logging.Level;
    007
    008    import net.minecraft.src.BiomeGenBase;
    009    import net.minecraft.src.CraftingManager;
    010    import net.minecraft.src.EntityItem;
    011    import net.minecraft.src.EntityPlayer;
    012    import net.minecraft.src.FurnaceRecipes;
    013    import net.minecraft.src.IChunkProvider;
    014    import net.minecraft.src.IInventory;
    015    import net.minecraft.src.IRecipe;
    016    import net.minecraft.src.ItemBlock;
    017    import net.minecraft.src.ItemStack;
    018    import net.minecraft.src.TileEntity;
    019    import net.minecraft.src.World;
    020    import net.minecraft.src.WorldType;
    021
    022    import com.google.common.collect.ArrayListMultimap;
    023    import com.google.common.collect.Lists;
    024    import com.google.common.collect.Multimap;
    025    import com.google.common.collect.Sets;
    026
    027    import cpw.mods.fml.common.FMLLog;
    028    import cpw.mods.fml.common.ICraftingHandler;
    029    import cpw.mods.fml.common.IDispenseHandler;
    030    import cpw.mods.fml.common.IDispenserHandler;
    031    import cpw.mods.fml.common.IFuelHandler;
    032    import cpw.mods.fml.common.IPickupNotifier;
    033    import cpw.mods.fml.common.IPlayerTracker;
    034    import cpw.mods.fml.common.IWorldGenerator;
    035    import cpw.mods.fml.common.Loader;
    036    import cpw.mods.fml.common.LoaderException;
    037    import cpw.mods.fml.common.LoaderState;
    038    import cpw.mods.fml.common.Mod.Block;
    039    import cpw.mods.fml.common.ModContainer;
    040
    041    public class GameRegistry
    042    {
    043        private static Multimap<ModContainer, BlockProxy> blockRegistry = ArrayListMultimap.create();
    044        private static Multimap<ModContainer, ItemProxy> itemRegistry = ArrayListMultimap.create();
    045        private static Set<IWorldGenerator> worldGenerators = Sets.newHashSet();
    046        private static List<IFuelHandler> fuelHandlers = Lists.newArrayList();
    047        private static List<ICraftingHandler> craftingHandlers = Lists.newArrayList();
    048        private static List<IDispenserHandler> dispenserHandlers = Lists.newArrayList();
    049        private static List<IPickupNotifier> pickupHandlers = Lists.newArrayList();
    050        private static List<IPlayerTracker> playerTrackers = Lists.newArrayList();
    051
    052        /**
    053         * Register a world generator - something that inserts new block types into the world
    054         *
    055         * @param generator
    056         */
    057        public static void registerWorldGenerator(IWorldGenerator generator)
    058        {
    059            worldGenerators.add(generator);
    060        }
    061
    062        /**
    063         * Callback hook for world gen - if your mod wishes to add extra mod related generation to the world
    064         * call this
    065         *
    066         * @param chunkX
    067         * @param chunkZ
    068         * @param world
    069         * @param chunkGenerator
    070         * @param chunkProvider
    071         */
    072        public static void generateWorld(int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
    073        {
    074            long worldSeed = world.getSeed();
    075            Random fmlRandom = new Random(worldSeed);
    076            long xSeed = fmlRandom.nextLong() >> 2 + 1L;
    077            long zSeed = fmlRandom.nextLong() >> 2 + 1L;
    078            fmlRandom.setSeed((xSeed * chunkX + zSeed * chunkZ) ^ worldSeed);
    079
    080            for (IWorldGenerator generator : worldGenerators)
    081            {
    082                generator.generate(fmlRandom, chunkX, chunkZ, world, chunkGenerator, chunkProvider);
    083            }
    084        }
    085
    086        public static void registerDispenserHandler(IDispenserHandler handler)
    087        {
    088            dispenserHandlers.add(handler);
    089        }
    090        /**
    091         * Register a handler for dispensers
    092         *
    093         * @param handler
    094         */
    095        @Deprecated
    096        public static void registerDispenserHandler(final IDispenseHandler handler)
    097        {
    098            registerDispenserHandler(new IDispenserHandler()
    099            {
    100
    101                @Override
    102                public int dispense(int x, int y, int z, int xVelocity, int zVelocity, World world, ItemStack item, Random random, double entX, double entY, double entZ)
    103                {
    104                    return handler.dispense(x, y, z, xVelocity, zVelocity, world, item, random, entX, entY, entZ);
    105                }
    106            });
    107        }
    108
    109
    110        /**
    111         * Callback hook for dispenser activities - if you add a block and want mods to be able
    112         * to extend their dispenser related activities to it call this
    113         *
    114         * @param world
    115         * @param x
    116         * @param y
    117         * @param z
    118         * @param xVelocity
    119         * @param zVelocity
    120         * @param item
    121         */
    122        public static int tryDispense(World world, int x, int y, int z, int xVelocity, int zVelocity, ItemStack item, Random random, double entX, double entY, double entZ)
    123        {
    124            for (IDispenserHandler handler : dispenserHandlers)
    125            {
    126                int dispensed = handler.dispense(x, y, z, xVelocity, zVelocity, world, item, random, entX, entY, entZ);
    127                if (dispensed>-1)
    128                {
    129                    return dispensed;
    130                }
    131            }
    132            return -1;
    133        }
    134        /**
    135         * Internal method for creating an @Block instance
    136         * @param container
    137         * @param type
    138         * @param annotation
    139         * @throws Exception
    140         */
    141        public static Object buildBlock(ModContainer container, Class<?> type, Block annotation) throws Exception
    142        {
    143            Object o = type.getConstructor(int.class).newInstance(findSpareBlockId());
    144            registerBlock((net.minecraft.src.Block) o);
    145            return o;
    146        }
    147
    148        /**
    149         * Private and not yet working properly
    150         *
    151         * @return
    152         */
    153        private static int findSpareBlockId()
    154        {
    155            return BlockTracker.nextBlockId();
    156        }
    157
    158        /**
    159         * Register a block with the world
    160         *
    161         */
    162        public static void registerBlock(net.minecraft.src.Block block)
    163        {
    164            registerBlock(block, ItemBlock.class);
    165        }
    166
    167        /**
    168         * Register a block with the world, with the specified item class
    169         *
    170         * @param block
    171         * @param itemclass
    172         */
    173        public static void registerBlock(net.minecraft.src.Block block, Class<? extends ItemBlock> itemclass)
    174        {
    175            if (Loader.instance().isInState(LoaderState.CONSTRUCTING))
    176            {
    177                FMLLog.warning("The mod %s is attempting to register a block whilst it it being constructed. This is bad modding practice - please use a proper mod lifecycle event.", Loader.instance().activeModContainer());
    178            }
    179            try
    180            {
    181                assert block != null : "registerBlock: block cannot be null";
    182                assert itemclass != null : "registerBlock: itemclass cannot be null";
    183                int blockItemId = block.blockID - 256;
    184                itemclass.getConstructor(int.class).newInstance(blockItemId);
    185            }
    186            catch (Exception e)
    187            {
    188                FMLLog.log(Level.SEVERE, e, "Caught an exception during block registration");
    189                throw new LoaderException(e);
    190            }
    191            blockRegistry.put(Loader.instance().activeModContainer(), (BlockProxy) block);
    192        }
    193
    194        public static void addRecipe(ItemStack output, Object... params)
    195        {
    196            CraftingManager.getInstance().addRecipe(output, params);
    197        }
    198
    199        public static void addShapelessRecipe(ItemStack output, Object... params)
    200        {
    201            CraftingManager.getInstance().addShapelessRecipe(output, params);
    202        }
    203
    204        public static void addRecipe(IRecipe recipe)
    205        {
    206            CraftingManager.getInstance().getRecipeList().add(recipe);
    207        }
    208
    209        public static void addSmelting(int input, ItemStack output, float xp)
    210        {
    211            FurnaceRecipes.smelting().addSmelting(input, output, xp);
    212        }
    213
    214        public static void registerTileEntity(Class<? extends TileEntity> tileEntityClass, String id)
    215        {
    216            TileEntity.addMapping(tileEntityClass, id);
    217        }
    218
    219        public static void addBiome(BiomeGenBase biome)
    220        {
    221            WorldType.DEFAULT.addNewBiome(biome);
    222        }
    223
    224        public static void removeBiome(BiomeGenBase biome)
    225        {
    226            WorldType.DEFAULT.removeBiome(biome);
    227        }
    228
    229        public static void registerFuelHandler(IFuelHandler handler)
    230        {
    231            fuelHandlers.add(handler);
    232        }
    233        public static int getFuelValue(ItemStack itemStack)
    234        {
    235            int fuelValue = 0;
    236            for (IFuelHandler handler : fuelHandlers)
    237            {
    238                fuelValue = Math.max(fuelValue, handler.getBurnTime(itemStack));
    239            }
    240            return fuelValue;
    241        }
    242
    243        public static void registerCraftingHandler(ICraftingHandler handler)
    244        {
    245            craftingHandlers.add(handler);
    246        }
    247
    248        public static void onItemCrafted(EntityPlayer player, ItemStack item, IInventory craftMatrix)
    249        {
    250            for (ICraftingHandler handler : craftingHandlers)
    251            {
    252                handler.onCrafting(player, item, craftMatrix);
    253            }
    254        }
    255
    256        public static void onItemSmelted(EntityPlayer player, ItemStack item)
    257        {
    258            for (ICraftingHandler handler : craftingHandlers)
    259            {
    260                handler.onSmelting(player, item);
    261            }
    262        }
    263
    264        public static void registerPickupHandler(IPickupNotifier handler)
    265        {
    266            pickupHandlers.add(handler);
    267        }
    268
    269        public static void onPickupNotification(EntityPlayer player, EntityItem item)
    270        {
    271            for (IPickupNotifier notify : pickupHandlers)
    272            {
    273                notify.notifyPickup(item, player);
    274            }
    275        }
    276
    277        public static void registerPlayerTracker(IPlayerTracker tracker)
    278        {
    279            playerTrackers.add(tracker);
    280        }
    281
    282        public static void onPlayerLogin(EntityPlayer player)
    283        {
    284            for(IPlayerTracker tracker : playerTrackers)
    285                tracker.onPlayerLogin(player);
    286        }
    287
    288        public static void onPlayerLogout(EntityPlayer player)
    289        {
    290            for(IPlayerTracker tracker : playerTrackers)
    291                tracker.onPlayerLogout(player);
    292        }
    293
    294        public static void onPlayerChangedDimension(EntityPlayer player)
    295        {
    296            for(IPlayerTracker tracker : playerTrackers)
    297                tracker.onPlayerChangedDimension(player);
    298        }
    299
    300        public static void onPlayerRespawn(EntityPlayer player)
    301        {
    302            for(IPlayerTracker tracker : playerTrackers)
    303                tracker.onPlayerRespawn(player);
    304        }
    305    }