    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}