001    /*
002     * The FML Forge Mod Loader suite.
003     * Copyright (C) 2012 cpw
004     *
005     * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or any later version.
007     *
008     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
009     * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
010     *
011     * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51
012     * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
013     */
014    
015    package cpw.mods.fml.common.modloader;
016    
017    import java.util.EnumSet;
018    import java.util.HashMap;
019    import java.util.Map;
020    import java.util.concurrent.Callable;
021    
022    import com.google.common.collect.ArrayListMultimap;
023    import com.google.common.collect.ListMultimap;
024    import com.google.common.collect.Maps;
025    
026    import net.minecraft.src.BaseMod;
027    import net.minecraft.src.Container;
028    import net.minecraft.src.Entity;
029    import net.minecraft.src.EntityDragon;
030    import net.minecraft.src.EntityPlayer;
031    import net.minecraft.src.IAnimals;
032    import net.minecraft.src.ICommand;
033    import net.minecraft.src.TradeEntry;
034    import cpw.mods.fml.common.FMLCommonHandler;
035    import cpw.mods.fml.common.FMLLog;
036    import cpw.mods.fml.common.ICraftingHandler;
037    import cpw.mods.fml.common.IDispenseHandler;
038    import cpw.mods.fml.common.IDispenserHandler;
039    import cpw.mods.fml.common.IFuelHandler;
040    import cpw.mods.fml.common.IPickupNotifier;
041    import cpw.mods.fml.common.IWorldGenerator;
042    import cpw.mods.fml.common.Loader;
043    import cpw.mods.fml.common.TickType;
044    import cpw.mods.fml.common.network.IChatListener;
045    import cpw.mods.fml.common.network.IConnectionHandler;
046    import cpw.mods.fml.common.network.IGuiHandler;
047    import cpw.mods.fml.common.network.IPacketHandler;
048    import cpw.mods.fml.common.network.NetworkRegistry;
049    import cpw.mods.fml.common.registry.EntityRegistry;
050    import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
051    import cpw.mods.fml.common.registry.VillagerRegistry.IVillageTradeHandler;
052    import cpw.mods.fml.common.registry.VillagerRegistry;
053    
054    /**
055     * @author cpw
056     *
057     */
058    @SuppressWarnings("deprecation")
059    public class ModLoaderHelper
060    {
061        public static IModLoaderSidedHelper sidedHelper;
062    
063        private static Map<Integer, ModLoaderGuiHelper> guiHelpers = Maps.newHashMap();
064    
065        public static void updateStandardTicks(BaseModProxy mod, boolean enable, boolean useClock)
066        {
067            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().getReversedModObjectList().get(mod);
068            if (mlmc==null)
069            {
070                FMLLog.severe("Attempted to register ModLoader ticking for invalid BaseMod %s",mod);
071                return;
072            }
073            BaseModTicker ticker = mlmc.getGameTickHandler();
074            EnumSet<TickType> ticks = ticker.ticks();
075            // If we're enabled we get render ticks
076            if (enable && !useClock) {
077                ticks.add(TickType.RENDER);
078            } else {
079                ticks.remove(TickType.RENDER);
080            }
081            // If we're enabled but we want clock ticks, or we're server side we get game ticks
082            if (enable && (useClock || FMLCommonHandler.instance().getSide().isServer())) {
083                ticks.add(TickType.CLIENT);
084                ticks.add(TickType.WORLDLOAD);
085            } else {
086                ticks.remove(TickType.CLIENT);
087                ticks.remove(TickType.WORLDLOAD);
088            }
089        }
090    
091        public static void updateGUITicks(BaseModProxy mod, boolean enable, boolean useClock)
092        {
093            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().getReversedModObjectList().get(mod);
094            if (mlmc==null)
095            {
096                FMLLog.severe("Attempted to register ModLoader ticking for invalid BaseMod %s",mod);
097                return;
098            }
099            EnumSet<TickType> ticks = mlmc.getGUITickHandler().ticks();
100            // If we're enabled and we don't want clock ticks we get render ticks
101            if (enable && !useClock) {
102                ticks.add(TickType.RENDER);
103            } else {
104                ticks.remove(TickType.RENDER);
105            }
106            // If we're enabled but we want clock ticks, or we're server side we get world ticks
107            if (enable && useClock) {
108                ticks.add(TickType.CLIENT);
109                ticks.add(TickType.WORLDLOAD);
110            } else {
111                ticks.remove(TickType.CLIENT);
112                ticks.remove(TickType.WORLDLOAD);
113            }
114        }
115    
116        public static IPacketHandler buildPacketHandlerFor(BaseModProxy mod)
117        {
118            return new ModLoaderPacketHandler(mod);
119        }
120    
121        public static IWorldGenerator buildWorldGenHelper(BaseModProxy mod)
122        {
123            return new ModLoaderWorldGenerator(mod);
124        }
125    
126        public static IFuelHandler buildFuelHelper(BaseModProxy mod)
127        {
128            return new ModLoaderFuelHelper(mod);
129        }
130    
131        public static ICraftingHandler buildCraftingHelper(BaseModProxy mod)
132        {
133            return new ModLoaderCraftingHelper(mod);
134        }
135    
136        public static void finishModLoading(ModLoaderModContainer mc)
137        {
138            if (sidedHelper != null)
139            {
140                sidedHelper.finishModLoading(mc);
141            }
142        }
143    
144        public static IConnectionHandler buildConnectionHelper(BaseModProxy mod)
145        {
146            return new ModLoaderConnectionHandler(mod);
147        }
148    
149        public static IPickupNotifier buildPickupHelper(BaseModProxy mod)
150        {
151            return new ModLoaderPickupNotifier(mod);
152        }
153    
154        public static void buildGuiHelper(BaseModProxy mod, int id)
155        {
156            ModLoaderGuiHelper handler = new ModLoaderGuiHelper(mod, id);
157            guiHelpers.put(id, handler);
158            NetworkRegistry.instance().registerGuiHandler(mod, handler);
159        }
160    
161        public static void openGui(int id, EntityPlayer player, Container container, int x, int y, int z)
162        {
163            ModLoaderGuiHelper helper = guiHelpers.get(id);
164            helper.injectContainer(container);
165            player.openGui(helper.getMod(), id, player.worldObj, x, y, z);
166        }
167    
168        public static Object getClientSideGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
169        {
170            if (sidedHelper != null)
171            {
172                return sidedHelper.getClientGui(mod, player, ID, x, y, z);
173            }
174            return null;
175        }
176    
177        public static IDispenserHandler buildDispenseHelper(BaseModProxy mod)
178        {
179            return new ModLoaderDispenseHelper(mod);
180        }
181    
182    
183        public static void buildEntityTracker(BaseModProxy mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval,
184                boolean sendVelocityInfo)
185        {
186            EntityRegistration er = EntityRegistry.registerModLoaderEntity(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo);
187            er.setCustomSpawning(new ModLoaderEntitySpawnCallback(mod, er), EntityDragon.class.isAssignableFrom(entityClass) || IAnimals.class.isAssignableFrom(entityClass));
188        }
189    
190        private static ModLoaderVillageTradeHandler[] tradeHelpers = new ModLoaderVillageTradeHandler[6];
191    
192        public static void registerTrade(int profession, TradeEntry entry)
193        {
194            assert profession < tradeHelpers.length : "The profession is out of bounds";
195            if (tradeHelpers[profession] == null)
196            {
197                tradeHelpers[profession] = new ModLoaderVillageTradeHandler();
198                VillagerRegistry.instance().registerVillageTradeHandler(profession, tradeHelpers[profession]);
199            }
200    
201            tradeHelpers[profession].addTrade(entry);
202        }
203    
204        public static void addCommand(ICommand command)
205        {
206            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
207            if (mlmc!=null)
208            {
209                mlmc.addServerCommand(command);
210            }
211        }
212    
213        public static IChatListener buildChatListener(BaseModProxy mod)
214        {
215            return new ModLoaderChatListener(mod);
216        }
217    }