package makamys.neodymium; import static makamys.neodymium.Constants.LOGGER; import static makamys.neodymium.Constants.MODID; import static makamys.neodymium.Constants.VERSION; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import cpw.mods.fml.client.event.ConfigChangedEvent; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.FMLConstructionEvent; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLServerAboutToStartEvent; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.TickEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import makamys.mclib.core.MCLib; import makamys.mclib.core.MCLibModules; import makamys.neodymium.command.NeodymiumCommand; import makamys.neodymium.config.Config; import makamys.neodymium.renderer.NeoRenderer; import makamys.neodymium.util.ChatUtil; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; import net.minecraftforge.client.event.EntityViewRenderEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.WorldEvent; @Mod(modid = MODID, version = VERSION, guiFactory = "makamys.neodymium.config.GuiFactory") public class Neodymium { private static final Config.ReloadInfo CONFIG_RELOAD_INFO = new Config.ReloadInfo(); private boolean renderDebugText = false; public static NeoRenderer renderer; private static World rendererWorld; @EventHandler public void preInit(FMLConstructionEvent event) { MCLib.init(); Compat.applyCompatibilityTweaks(); } @EventHandler public void preInit(FMLPreInitializationEvent event) { MCLibModules.updateCheckAPI.submitModTask(MODID, "@UPDATE_URL@"); if(VERSION.equals("@VERSION@")) { // Allow using config GUI in dev env event.getModMetadata().autogenerated = false; } } @EventHandler public void init(FMLInitializationEvent event) { FMLCommonHandler.instance().bus().register(this); MinecraftForge.EVENT_BUS.register(this); NeodymiumCommand.init(); } @SubscribeEvent public void onConfigChanged(ConfigChangedEvent event) { if(event.modID.equals(MODID)) { Config.flush(); } } @EventHandler public void onServerAboutToStart(FMLServerAboutToStartEvent event) { Config.reloadConfig(); ChatUtil.resetShownChatMessages(); Compat.reset(); } private void onPlayerWorldChanged(World newWorld) { if(getRendererWorld() == null && newWorld != null) { Config.reloadConfig(); } if(renderer != null) { destroyRenderer(); } if(Config.enabled && newWorld != null) { Pair, List> warnsAndCriticalWarns = checkCompat(); List warns = warnsAndCriticalWarns.getLeft(); List criticalWarns = warnsAndCriticalWarns.getRight(); if(criticalWarns.isEmpty() || Config.ignoreIncompatibilities) { renderer = new NeoRenderer(newWorld); renderer.hasIncompatibilities = !warns.isEmpty() || !criticalWarns.isEmpty(); } } rendererWorld = newWorld; } @SubscribeEvent @SideOnly(Side.CLIENT) public void onWorldUnload(WorldEvent.Unload event) { if(!Config.enabled) return; if(event.world == getRendererWorld()) { onPlayerWorldChanged(null); } } public static boolean isActive() { return renderer != null && renderer.hasInited && !renderer.destroyPending; } private World getRendererWorld() { return rendererWorld; } @SubscribeEvent public void onClientTick(TickEvent.ClientTickEvent event) { if(!Config.enabled) return; if(event.phase == TickEvent.Phase.START && isActive()) { if(Config.hotswap) { if(Config.reloadIfChanged(CONFIG_RELOAD_INFO)) { if(CONFIG_RELOAD_INFO.needReload) { Minecraft.getMinecraft().renderGlobal.loadRenderers(); } else if(renderer != null) { renderer.reloadShader(); } } } } if(event.phase == TickEvent.Phase.START) { if(Compat.hasChanged()) { Pair, List> warns = checkCompat(); if(renderer != null) { renderer.hasIncompatibilities = !warns.getLeft().isEmpty() || !warns.getRight().isEmpty(); } } } } @SubscribeEvent public void onRenderTick(TickEvent.RenderTickEvent event) { if(!Config.enabled) return; if(event.phase == TickEvent.Phase.START) { EntityPlayer player = Minecraft.getMinecraft().thePlayer; World world = player != null ? player.worldObj : null; if(world != getRendererWorld()) { onPlayerWorldChanged(world); } if(isActive()) { renderer.forceRenderFog = true; } } else if(event.phase == TickEvent.Phase.END) { if(renderer != null) { renderer.onRenderTickEnd(); } } } @SubscribeEvent public void onRenderOverlay(RenderGameOverlayEvent.Pre event) { if (Config.showDebugInfo && isActive()) { if (event.type.equals(RenderGameOverlayEvent.ElementType.DEBUG)) { renderDebugText = true; } else if (renderDebugText && (event instanceof RenderGameOverlayEvent.Text) && event.type.equals(RenderGameOverlayEvent.ElementType.TEXT)) { renderDebugText = false; RenderGameOverlayEvent.Text text = (RenderGameOverlayEvent.Text) event; text.right.add(null); text.right.addAll(renderer.getDebugText()); } } } @SubscribeEvent public void onRenderFog(EntityViewRenderEvent.RenderFogEvent event) { if(isActive()) { renderer.forceRenderFog = false; } } public static boolean shouldRenderVanillaWorld() { return !isActive() || (isActive() && renderer.renderWorld && !renderer.rendererActive); } public static String modifySplash(String splash) { if(splash.equals("OpenGL 1.2!")) { return "OpenGL 3.3 (if supported)!"; } else { return splash; } } public static void destroyRenderer() { if(renderer != null) { renderer.destroy(); renderer = null; } rendererWorld = null; } public static Pair, List> checkCompat() { List warns = new ArrayList<>(); List criticalWarns = new ArrayList<>(); Compat.getCompatibilityWarnings(warns, criticalWarns); if(!criticalWarns.isEmpty()) { criticalWarns.add("Neodymium has been disabled due to a critical incompatibility."); } for(String warn : warns) { LOGGER.warn(warn); } for(String criticalWarn : criticalWarns) { LOGGER.warn("Critical: " + criticalWarn); } return Pair.of(warns, criticalWarns); } }