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.HashMultimap;
024    import com.google.common.collect.ListMultimap;
025    import com.google.common.collect.Maps;
026    import com.google.common.collect.SetMultimap;
027    
028    import net.minecraft.command.ICommand;
029    import net.minecraft.entity.Entity;
030    import net.minecraft.entity.passive.IAnimals;
031    import net.minecraft.entity.boss.EntityDragon;
032    import net.minecraft.entity.player.EntityPlayer;
033    import net.minecraft.inventory.Container;
034    import net.minecraft.src.BaseMod;
035    import net.minecraft.src.TradeEntry;
036    import cpw.mods.fml.common.FMLCommonHandler;
037    import cpw.mods.fml.common.FMLLog;
038    import cpw.mods.fml.common.ICraftingHandler;
039    import cpw.mods.fml.common.IDispenseHandler;
040    import cpw.mods.fml.common.IDispenserHandler;
041    import cpw.mods.fml.common.IFuelHandler;
042    import cpw.mods.fml.common.IPickupNotifier;
043    import cpw.mods.fml.common.IWorldGenerator;
044    import cpw.mods.fml.common.Loader;
045    import cpw.mods.fml.common.TickType;
046    import cpw.mods.fml.common.network.IChatListener;
047    import cpw.mods.fml.common.network.IConnectionHandler;
048    import cpw.mods.fml.common.network.IGuiHandler;
049    import cpw.mods.fml.common.network.IPacketHandler;
050    import cpw.mods.fml.common.network.NetworkRegistry;
051    import cpw.mods.fml.common.registry.EntityRegistry;
052    import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
053    import cpw.mods.fml.common.registry.VillagerRegistry.IVillageTradeHandler;
054    import cpw.mods.fml.common.registry.VillagerRegistry;
055    
056    /**
057     * @author cpw
058     *
059     */
060    @SuppressWarnings("deprecation")
061    public class ModLoaderHelper
062    {
063        public static IModLoaderSidedHelper sidedHelper;
064    
065        private static Map<BaseModProxy, ModLoaderGuiHelper> guiHelpers = Maps.newHashMap();
066        private static Map<Integer, ModLoaderGuiHelper> guiIDs = Maps.newHashMap();
067    
068        public static void updateStandardTicks(BaseModProxy mod, boolean enable, boolean useClock)
069        {
070            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().getReversedModObjectList().get(mod);
071            if (mlmc==null)
072            {
073                mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
074            }
075            if (mlmc == null)
076            {
077                FMLLog.severe("Attempted to register ModLoader ticking for invalid BaseMod %s",mod);
078                return;
079            }
080            BaseModTicker ticker = mlmc.getGameTickHandler();
081            EnumSet<TickType> ticks = ticker.ticks();
082            // If we're enabled we get render ticks
083            if (enable && !useClock) {
084                ticks.add(TickType.RENDER);
085            } else {
086                ticks.remove(TickType.RENDER);
087            }
088            // If we're enabled but we want clock ticks, or we're server side we get game ticks
089            if (enable && (useClock || FMLCommonHandler.instance().getSide().isServer())) {
090                ticks.add(TickType.CLIENT);
091                ticks.add(TickType.WORLDLOAD);
092            } else {
093                ticks.remove(TickType.CLIENT);
094                ticks.remove(TickType.WORLDLOAD);
095            }
096        }
097    
098        public static void updateGUITicks(BaseModProxy mod, boolean enable, boolean useClock)
099        {
100            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().getReversedModObjectList().get(mod);
101            if (mlmc==null)
102            {
103                mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
104            }
105            if (mlmc == null)
106            {
107                FMLLog.severe("Attempted to register ModLoader ticking for invalid BaseMod %s",mod);
108                return;
109            }
110            EnumSet<TickType> ticks = mlmc.getGUITickHandler().ticks();
111            // If we're enabled and we don't want clock ticks we get render ticks
112            if (enable && !useClock) {
113                ticks.add(TickType.RENDER);
114            } else {
115                ticks.remove(TickType.RENDER);
116            }
117            // If we're enabled but we want clock ticks, or we're server side we get world ticks
118            if (enable && useClock) {
119                ticks.add(TickType.CLIENT);
120                ticks.add(TickType.WORLDLOAD);
121            } else {
122                ticks.remove(TickType.CLIENT);
123                ticks.remove(TickType.WORLDLOAD);
124            }
125        }
126    
127        public static IPacketHandler buildPacketHandlerFor(BaseModProxy mod)
128        {
129            return new ModLoaderPacketHandler(mod);
130        }
131    
132        public static IWorldGenerator buildWorldGenHelper(BaseModProxy mod)
133        {
134            return new ModLoaderWorldGenerator(mod);
135        }
136    
137        public static IFuelHandler buildFuelHelper(BaseModProxy mod)
138        {
139            return new ModLoaderFuelHelper(mod);
140        }
141    
142        public static ICraftingHandler buildCraftingHelper(BaseModProxy mod)
143        {
144            return new ModLoaderCraftingHelper(mod);
145        }
146    
147        public static void finishModLoading(ModLoaderModContainer mc)
148        {
149            if (sidedHelper != null)
150            {
151                sidedHelper.finishModLoading(mc);
152            }
153        }
154    
155        public static IConnectionHandler buildConnectionHelper(BaseModProxy mod)
156        {
157            return new ModLoaderConnectionHandler(mod);
158        }
159    
160        public static IPickupNotifier buildPickupHelper(BaseModProxy mod)
161        {
162            return new ModLoaderPickupNotifier(mod);
163        }
164    
165        public static void buildGuiHelper(BaseModProxy mod, int id)
166        {
167            ModLoaderGuiHelper handler = guiHelpers.get(mod);
168            if (handler == null)
169            {
170                handler = new ModLoaderGuiHelper(mod);
171                guiHelpers.put(mod,handler);
172                NetworkRegistry.instance().registerGuiHandler(mod, handler);
173            }
174            handler.associateId(id);
175            guiIDs.put(id, handler);
176        }
177    
178        public static void openGui(int id, EntityPlayer player, Container container, int x, int y, int z)
179        {
180            ModLoaderGuiHelper helper = guiIDs.get(id);
181            helper.injectContainerAndID(container, id);
182            player.openGui(helper.getMod(), id, player.worldObj, x, y, z);
183        }
184    
185        public static Object getClientSideGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
186        {
187            if (sidedHelper != null)
188            {
189                return sidedHelper.getClientGui(mod, player, ID, x, y, z);
190            }
191            return null;
192        }
193    
194        public static IDispenserHandler buildDispenseHelper(BaseModProxy mod)
195        {
196            return new ModLoaderDispenseHelper(mod);
197        }
198    
199    
200        public static void buildEntityTracker(BaseModProxy mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval,
201                boolean sendVelocityInfo)
202        {
203            EntityRegistration er = EntityRegistry.registerModLoaderEntity(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo);
204            er.setCustomSpawning(new ModLoaderEntitySpawnCallback(mod, er), EntityDragon.class.isAssignableFrom(entityClass) || IAnimals.class.isAssignableFrom(entityClass));
205        }
206    
207        private static ModLoaderVillageTradeHandler[] tradeHelpers = new ModLoaderVillageTradeHandler[6];
208    
209        public static void registerTrade(int profession, TradeEntry entry)
210        {
211            assert profession < tradeHelpers.length : "The profession is out of bounds";
212            if (tradeHelpers[profession] == null)
213            {
214                tradeHelpers[profession] = new ModLoaderVillageTradeHandler();
215                VillagerRegistry.instance().registerVillageTradeHandler(profession, tradeHelpers[profession]);
216            }
217    
218            tradeHelpers[profession].addTrade(entry);
219        }
220    
221        public static void addCommand(ICommand command)
222        {
223            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
224            if (mlmc!=null)
225            {
226                mlmc.addServerCommand(command);
227            }
228        }
229    
230        public static IChatListener buildChatListener(BaseModProxy mod)
231        {
232            return new ModLoaderChatListener(mod);
233        }
234    }