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.command.ICommand;
027 import net.minecraft.entity.Entity;
028 import net.minecraft.entity.passive.IAnimals;
029 import net.minecraft.entity.boss.EntityDragon;
030 import net.minecraft.entity.player.EntityPlayer;
031 import net.minecraft.inventory.Container;
032 import net.minecraft.src.BaseMod;
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 }