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
015package cpw.mods.fml.common.modloader;
016
017import java.util.EnumSet;
018import java.util.HashMap;
019import java.util.Map;
020import java.util.concurrent.Callable;
021
022import com.google.common.collect.ArrayListMultimap;
023import com.google.common.collect.HashMultimap;
024import com.google.common.collect.ListMultimap;
025import com.google.common.collect.Maps;
026import com.google.common.collect.SetMultimap;
027
028import net.minecraft.command.ICommand;
029import net.minecraft.entity.Entity;
030import net.minecraft.entity.passive.IAnimals;
031import net.minecraft.entity.boss.EntityDragon;
032import net.minecraft.entity.player.EntityPlayer;
033import net.minecraft.inventory.Container;
034import net.minecraft.src.BaseMod;
035import net.minecraft.src.TradeEntry;
036import cpw.mods.fml.common.FMLCommonHandler;
037import cpw.mods.fml.common.FMLLog;
038import cpw.mods.fml.common.ICraftingHandler;
039import cpw.mods.fml.common.IDispenseHandler;
040import cpw.mods.fml.common.IDispenserHandler;
041import cpw.mods.fml.common.IFuelHandler;
042import cpw.mods.fml.common.IPickupNotifier;
043import cpw.mods.fml.common.IWorldGenerator;
044import cpw.mods.fml.common.Loader;
045import cpw.mods.fml.common.TickType;
046import cpw.mods.fml.common.network.IChatListener;
047import cpw.mods.fml.common.network.IConnectionHandler;
048import cpw.mods.fml.common.network.IGuiHandler;
049import cpw.mods.fml.common.network.IPacketHandler;
050import cpw.mods.fml.common.network.NetworkRegistry;
051import cpw.mods.fml.common.registry.EntityRegistry;
052import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
053import cpw.mods.fml.common.registry.VillagerRegistry.IVillageTradeHandler;
054import cpw.mods.fml.common.registry.VillagerRegistry;
055
056/**
057 * @author cpw
058 *
059 */
060@SuppressWarnings("deprecation")
061public 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}