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 }