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}