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