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                mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
071            }
072            if (mlmc == null)
073            {
074                FMLLog.severe("Attempted to register ModLoader ticking for invalid BaseMod %s",mod);
075                return;
076            }
077            BaseModTicker ticker = mlmc.getGameTickHandler();
078            EnumSet<TickType> ticks = ticker.ticks();
079            // If we're enabled we get render ticks
080            if (enable && !useClock) {
081                ticks.add(TickType.RENDER);
082            } else {
083                ticks.remove(TickType.RENDER);
084            }
085            // If we're enabled but we want clock ticks, or we're server side we get game ticks
086            if (enable && (useClock || FMLCommonHandler.instance().getSide().isServer())) {
087                ticks.add(TickType.CLIENT);
088                ticks.add(TickType.WORLDLOAD);
089            } else {
090                ticks.remove(TickType.CLIENT);
091                ticks.remove(TickType.WORLDLOAD);
092            }
093        }
094    
095        public static void updateGUITicks(BaseModProxy mod, boolean enable, boolean useClock)
096        {
097            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().getReversedModObjectList().get(mod);
098            if (mlmc==null)
099            {
100                mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
101            }
102            if (mlmc == null)
103            {
104                FMLLog.severe("Attempted to register ModLoader ticking for invalid BaseMod %s",mod);
105                return;
106            }
107            EnumSet<TickType> ticks = mlmc.getGUITickHandler().ticks();
108            // If we're enabled and we don't want clock ticks we get render ticks
109            if (enable && !useClock) {
110                ticks.add(TickType.RENDER);
111            } else {
112                ticks.remove(TickType.RENDER);
113            }
114            // If we're enabled but we want clock ticks, or we're server side we get world ticks
115            if (enable && useClock) {
116                ticks.add(TickType.CLIENT);
117                ticks.add(TickType.WORLDLOAD);
118            } else {
119                ticks.remove(TickType.CLIENT);
120                ticks.remove(TickType.WORLDLOAD);
121            }
122        }
123    
124        public static IPacketHandler buildPacketHandlerFor(BaseModProxy mod)
125        {
126            return new ModLoaderPacketHandler(mod);
127        }
128    
129        public static IWorldGenerator buildWorldGenHelper(BaseModProxy mod)
130        {
131            return new ModLoaderWorldGenerator(mod);
132        }
133    
134        public static IFuelHandler buildFuelHelper(BaseModProxy mod)
135        {
136            return new ModLoaderFuelHelper(mod);
137        }
138    
139        public static ICraftingHandler buildCraftingHelper(BaseModProxy mod)
140        {
141            return new ModLoaderCraftingHelper(mod);
142        }
143    
144        public static void finishModLoading(ModLoaderModContainer mc)
145        {
146            if (sidedHelper != null)
147            {
148                sidedHelper.finishModLoading(mc);
149            }
150        }
151    
152        public static IConnectionHandler buildConnectionHelper(BaseModProxy mod)
153        {
154            return new ModLoaderConnectionHandler(mod);
155        }
156    
157        public static IPickupNotifier buildPickupHelper(BaseModProxy mod)
158        {
159            return new ModLoaderPickupNotifier(mod);
160        }
161    
162        public static void buildGuiHelper(BaseModProxy mod, int id)
163        {
164            ModLoaderGuiHelper handler = new ModLoaderGuiHelper(mod, id);
165            guiHelpers.put(id, handler);
166            NetworkRegistry.instance().registerGuiHandler(mod, handler);
167        }
168    
169        public static void openGui(int id, EntityPlayer player, Container container, int x, int y, int z)
170        {
171            ModLoaderGuiHelper helper = guiHelpers.get(id);
172            helper.injectContainer(container);
173            player.openGui(helper.getMod(), id, player.worldObj, x, y, z);
174        }
175    
176        public static Object getClientSideGui(BaseModProxy mod, EntityPlayer player, int ID, int x, int y, int z)
177        {
178            if (sidedHelper != null)
179            {
180                return sidedHelper.getClientGui(mod, player, ID, x, y, z);
181            }
182            return null;
183        }
184    
185        public static IDispenserHandler buildDispenseHelper(BaseModProxy mod)
186        {
187            return new ModLoaderDispenseHelper(mod);
188        }
189    
190    
191        public static void buildEntityTracker(BaseModProxy mod, Class<? extends Entity> entityClass, int entityTypeId, int updateRange, int updateInterval,
192                boolean sendVelocityInfo)
193        {
194            EntityRegistration er = EntityRegistry.registerModLoaderEntity(mod, entityClass, entityTypeId, updateRange, updateInterval, sendVelocityInfo);
195            er.setCustomSpawning(new ModLoaderEntitySpawnCallback(mod, er), EntityDragon.class.isAssignableFrom(entityClass) || IAnimals.class.isAssignableFrom(entityClass));
196        }
197    
198        private static ModLoaderVillageTradeHandler[] tradeHelpers = new ModLoaderVillageTradeHandler[6];
199    
200        public static void registerTrade(int profession, TradeEntry entry)
201        {
202            assert profession < tradeHelpers.length : "The profession is out of bounds";
203            if (tradeHelpers[profession] == null)
204            {
205                tradeHelpers[profession] = new ModLoaderVillageTradeHandler();
206                VillagerRegistry.instance().registerVillageTradeHandler(profession, tradeHelpers[profession]);
207            }
208    
209            tradeHelpers[profession].addTrade(entry);
210        }
211    
212        public static void addCommand(ICommand command)
213        {
214            ModLoaderModContainer mlmc = (ModLoaderModContainer) Loader.instance().activeModContainer();
215            if (mlmc!=null)
216            {
217                mlmc.addServerCommand(command);
218            }
219        }
220    
221        public static IChatListener buildChatListener(BaseModProxy mod)
222        {
223            return new ModLoaderChatListener(mod);
224        }
225    }