/*
* This file is part of Matter Overdrive
* Copyright (c) 2015., Simeon Radivoev, All rights reserved.
*
* Matter Overdrive is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Matter Overdrive is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Matter Overdrive. If not, see <http://www.gnu.org/licenses>.
*/
package matteroverdrive.gui;
import cpw.mods.fml.common.eventhandler.EventPriority;
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 matteroverdrive.MatterOverdrive;
import matteroverdrive.Reference;
import matteroverdrive.animation.AnimationSegmentText;
import matteroverdrive.animation.AnimationTextTyping;
import matteroverdrive.api.android.IBionicStat;
import matteroverdrive.api.weapon.IWeapon;
import matteroverdrive.client.data.Color;
import matteroverdrive.client.render.HoloIcon;
import matteroverdrive.entity.player.AndroidPlayer;
import matteroverdrive.gui.android.*;
import matteroverdrive.gui.config.EnumConfigProperty;
import matteroverdrive.handler.ConfigurationHandler;
import matteroverdrive.init.MatterOverdriveBioticStats;
import matteroverdrive.proxy.ClientProxy;
import matteroverdrive.util.IConfigSubscriber;
import matteroverdrive.util.MOStringHelper;
import matteroverdrive.util.RenderUtils;
import matteroverdrive.util.math.MOMathHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.shader.ShaderGroup;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.common.config.Property;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import static org.lwjgl.opengl.GL11.*;
/**
* Created by Simeon on 5/26/2015.
*/
@SideOnly(Side.CLIENT)
public class GuiAndroidHud extends Gui implements IConfigSubscriber
{
public static final ResourceLocation glitch_tex = new ResourceLocation(Reference.PATH_GUI + "glitch.png");
public static final ResourceLocation spinner_tex = new ResourceLocation(Reference.PATH_ELEMENTS + "spinner.png");
public static final ResourceLocation top_element_bg = new ResourceLocation(Reference.PATH_ELEMENTS + "android_bg_element.png");
public static final ResourceLocation cloak_overlay = new ResourceLocation(Reference.PATH_ELEMENTS + "cloak_overlay.png");
private AnimationTextTyping textTyping;
private Minecraft mc;
private Random random;
private ShaderGroup hurtShader;
private List<IBionicStat> stats = new ArrayList<>();
public static boolean showRadial = false;
public static double radialDeltaX,radialDeltaY,radialAngle;
private static double radialAnimationTime;
private HoloIcon crosshairIcon;
private List<IAndroidHudElement> hudElements;
public final AndroidHudMinimap hudMinimap;
public final AndroidHudStats hudStats;
public final AndroidHudBionicStats bionicStats;
public Color baseGuiColor;
public float opacity;
public float opacityBackground;
public boolean hideVanillaHudElements;
public boolean hudMovement;
public GuiAndroidHud(Minecraft mc)
{
super();
this.mc = mc;
random = new Random();
textTyping = new AnimationTextTyping(false,AndroidPlayer.TRANSFORM_TIME);
String info;
for (int i = 0;i < 5;i++)
{
info = MOStringHelper.translateToLocal("gui.android_hud.transforming.line." + i);
textTyping.addSegmentSequential(new AnimationSegmentText(info,0,1).setLengthPerCharacter(2));
textTyping.addSegmentSequential(new AnimationSegmentText(info,0,0).setLengthPerCharacter(2));
}
info = MOStringHelper.translateToLocal("gui.android_hud.transforming.line.final");
textTyping.addSegmentSequential(new AnimationSegmentText(info, 0, 1).setLengthPerCharacter(2));
textTyping.addSegmentSequential(new AnimationSegmentText(info, AndroidPlayer.TRANSFORM_TIME, 0));
hudElements = new ArrayList<>();
hudMinimap = new AndroidHudMinimap(AndroidHudPosition.BOTTOM_LEFT,"android_minimap");
hudStats = new AndroidHudStats(AndroidHudPosition.TOP_LEFT,"android_stats");
bionicStats = new AndroidHudBionicStats(AndroidHudPosition.TOP_RIGHT,"android_biotic_stats");
hudElements.add(hudMinimap);
hudElements.add(hudStats);
hudElements.add(bionicStats);
baseGuiColor = Reference.COLOR_HOLO.multiplyWithoutAlpha(0.5f);
}
@SubscribeEvent
public void renderTick(TickEvent.RenderTickEvent event)
{
if (showRadial)
{
Mouse.getDX();
Mouse.getDY();
mc.mouseHelper.deltaX = mc.mouseHelper.deltaY = 0;
}
}
@SubscribeEvent(priority = EventPriority.NORMAL)
public void onRenderExperienceBar(RenderGameOverlayEvent event)
{
AndroidPlayer android = AndroidPlayer.get(mc.thePlayer);
if ((mc.currentScreen instanceof GuiDialog || mc.currentScreen instanceof GuiStarMap) && !event.type.equals(RenderGameOverlayEvent.ElementType.ALL) && event.isCancelable())
{
event.setCanceled(true);
return;
}
if ((android.isAndroid() && (event.type == RenderGameOverlayEvent.ElementType.FOOD || event.type == RenderGameOverlayEvent.ElementType.AIR || event.type == RenderGameOverlayEvent.ElementType.HEALTH) && event.isCancelable()))
{
event.setCanceled(hideVanillaHudElements);
return;
}
if ((android.isAndroid() || (mc.thePlayer.getHeldItem() != null && mc.thePlayer.getHeldItem().getItem() instanceof IWeapon)) && event.isCancelable() && event.type == RenderGameOverlayEvent.ElementType.CROSSHAIRS)
{
event.setCanceled(true);
if (!showRadial)
{
renderCrosshair(event);
}
mc.getTextureManager().bindTexture(Gui.icons);
}
else if (event.type == RenderGameOverlayEvent.ElementType.ALL && !(mc.currentScreen instanceof GuiStarMap))
{
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
renderHud(event);
//System.out.println(showRadial);
if (android.isAndroid())
{
if (showRadial)
{
GuiAndroidHud.radialAnimationTime = Math.min(1,GuiAndroidHud.radialAnimationTime+event.partialTicks*0.2);
}else
{
GuiAndroidHud.radialAnimationTime = Math.max(0,GuiAndroidHud.radialAnimationTime-event.partialTicks*0.2);
}
if (GuiAndroidHud.radialAnimationTime > 0)
{
renderRadialMenu(event);
}
}
glPopAttrib();
}
}
public void renderCrosshair(RenderGameOverlayEvent event)
{
glPushAttrib(GL_COLOR_BUFFER_BIT);
glPushMatrix();
float scale = 6 + ClientProxy.instance().getClientWeaponHandler().getEquippedWeaponAccuracyPercent(Minecraft.getMinecraft().thePlayer)*256;
glEnable(GL_BLEND);
OpenGlHelper.glBlendFunc(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ONE_MINUS_SRC_COLOR, 1, 0);
glEnable(GL_ALPHA_TEST);
//RenderUtils.applyColorWithMultipy(Reference.COLOR_HOLO,0.5f);
glColor3d(1, 1, 1);
crosshairIcon = ClientProxy.holoIcons.getIcon("crosshair");
glTranslated(event.resolution.getScaledWidth() / 2, event.resolution.getScaledHeight() / 2, 0);
glPushMatrix();
ClientProxy.holoIcons.bindSheet();
glRotated(90, 0, 0, 1);
ClientProxy.holoIcons.renderIcon(crosshairIcon,-1,-scale);
glRotated(90, 0, 0, 1);
ClientProxy.holoIcons.renderIcon(crosshairIcon,-2,-scale);
glRotated(90,0,0,1);
ClientProxy.holoIcons.renderIcon(crosshairIcon,-1.8,-scale+1);
glRotated(90,0,0,1);
ClientProxy.holoIcons.renderIcon(crosshairIcon,-1,-scale+1);
glPopMatrix();
glPopMatrix();
glPopAttrib();
}
public void renderRadialMenu(RenderGameOverlayEvent event)
{
glPushMatrix();
glTranslated(event.resolution.getScaledWidth() / 2, event.resolution.getScaledHeight() / 2, 0);
double scale = MOMathHelper.easeIn(GuiAndroidHud.radialAnimationTime,0,1,1);
glScaled(scale, scale, scale);
ClientProxy.holoIcons.bindSheet();
AndroidPlayer androidPlayer = AndroidPlayer.get(Minecraft.getMinecraft().thePlayer);
stats.clear();
for (IBionicStat stat : MatterOverdrive.statRegistry.getStats())
{
if (stat.showOnWheel(androidPlayer, androidPlayer.getUnlockedLevel(stat)) && androidPlayer.isUnlocked(stat,0))
{
stats.add(stat);
}
}
glColor3f(1, 1, 1);
glDepthMask(false);
//glDisable(GL_DEPTH_TEST);
//glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glPushMatrix();
glRotated(radialAngle, 0, 0, -1);
RenderUtils.applyColorWithMultipy(baseGuiColor, 0.4f);
ClientProxy.holoIcons.renderIcon("up_arrow_large", -9, -50);
glPopMatrix();
int i = 0;
for (IBionicStat stat : stats)
{
double angleSeg = (Math.PI*2/stats.size());
double angle,x,y,radiusMin,radiusMax,angleAb,angleCircle;
double radius = 80;
angle = angleSeg * i;
angle += Math.toRadians(180D);
radiusMin = radius - 16;
radiusMax = radius + 16;
glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (androidPlayer.getActiveStat() != null && androidPlayer.getActiveStat().equals(stat))
{
radiusMax = radius + 20;
radiusMin = radius - 16;
glColor4d(0, 0, 0, 0.6);
}else
{
glColor4d(0, 0, 0, 0.4);
}
Tessellator.instance.startDrawingQuads();
for (int c = 0;c < 32;c++)
{
angleAb = ((angleSeg)/32d);
angleCircle = c * angleAb + angle - angleSeg/2;
Tessellator.instance.addVertex(Math.sin(angleCircle) * radiusMax,Math.cos(angleCircle) * radiusMax,-1);
Tessellator.instance.addVertex(Math.sin(angleCircle + angleAb) * radiusMax,Math.cos(angleCircle + angleAb) * radiusMax,-1);
Tessellator.instance.addVertex(Math.sin(angleCircle + angleAb) * radiusMin,Math.cos(angleCircle + angleAb) * radiusMin,-1);
Tessellator.instance.addVertex(Math.sin(angleCircle) * radiusMin,Math.cos(angleCircle) * radiusMin,-1);
}
Tessellator.instance.draw();
radiusMax = radius - 20;
radiusMin = radius - 25;
Tessellator.instance.startDrawingQuads();
glColor4d(0, 0, 0, 0.2);
for (int c = 0;c < 32;c++)
{
angleAb = ((Math.PI*2)/32d);
angleCircle = c * angleAb;
Tessellator.instance.addVertex(Math.sin(angleCircle) * radiusMax,Math.cos(angleCircle) * radiusMax,-1);
Tessellator.instance.addVertex(Math.sin(angleCircle + angleAb) * radiusMax,Math.cos(angleCircle + angleAb) * radiusMax,-1);
Tessellator.instance.addVertex(Math.sin(angleCircle + angleAb) * radiusMin,Math.cos(angleCircle + angleAb) * radiusMin,-1);
Tessellator.instance.addVertex(Math.sin(angleCircle) * radiusMin,Math.cos(angleCircle) * radiusMin,-1);
}
Tessellator.instance.draw();
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glDepthMask(false);
ClientProxy.holoIcons.bindSheet();
if (androidPlayer.getActiveStat() != null)
{
if (androidPlayer.getActiveStat().equals(stat))
{
RenderUtils.applyColorWithMultipy(baseGuiColor, 1);
x = Math.sin(angle) * radius;
y = Math.cos(angle) * radius;
ClientProxy.holoIcons.renderIcon(stat.getIcon(0),-12 + x, -12 + y);
String statName = stat.getDisplayName(androidPlayer, androidPlayer.getUnlockedLevel(stat));
int statNameWidth = Minecraft.getMinecraft().fontRenderer.getStringWidth(statName);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Minecraft.getMinecraft().fontRenderer.drawString(statName, -statNameWidth / 2, -5, baseGuiColor.getColor());
}
else
{
x = Math.sin(angle) * radius;
y = Math.cos(angle) * radius;
RenderUtils.applyColorWithMultipy(baseGuiColor, 0.2f);
ClientProxy.holoIcons.renderIcon(stat.getIcon(0),-12 + x, -12 + y);
}
}
i++;
}
glPopMatrix();
}
public static float hudRotationYawSmooth;
public static float hudRotationPitchSmooth;
public void renderHud(RenderGameOverlayEvent event)
{
AndroidPlayer android = AndroidPlayer.get(mc.thePlayer);
if (android != null) {
if (android.isAndroid()) {
glPushMatrix();
if (MatterOverdriveBioticStats.cloak.isActive(android,0))
{
glBlendFunc(GL_DST_COLOR, GL_ZERO);
glColor3f(1,1,1);
mc.renderEngine.bindTexture(cloak_overlay);
RenderUtils.drawPlane(0,0,-100,event.resolution.getScaledWidth(),event.resolution.getScaledHeight());
}
if (hudMovement)
{
hudRotationYawSmooth = hudRotationYawSmooth * 0.4f + mc.thePlayer.rotationYaw * 0.6f;
hudRotationPitchSmooth = hudRotationPitchSmooth * 0.4f + mc.thePlayer.rotationPitch * 0.6f;
glTranslated((hudRotationYawSmooth - mc.thePlayer.rotationYaw) * 6, (hudRotationPitchSmooth - mc.thePlayer.rotationPitch) * 6, 0);
}
for (IAndroidHudElement element : hudElements)
{
if (element.isVisible(android))
{
glPushMatrix();
int elementWidth = (int)(element.getWidth(event.resolution,android) * element.getPosition().x);
glTranslated(element.getPosition().x * event.resolution.getScaledWidth_double() - elementWidth, element.getPosition().y * event.resolution.getScaledHeight_double() - element.getHeight(event.resolution,android) * element.getPosition().y, 0);
element.setBaseColor(baseGuiColor);
element.setBackgroundAlpha(opacityBackground);
element.drawElement(android, event.mouseX, event.mouseY, event.resolution, event.partialTicks);
glPopMatrix();
}
}
glPopMatrix();
renderHurt(android, event);
}else
{
if (android.isTurning())
{
renderTransformAnimation(android,event);
}
}
}
}
private void renderTransformAnimation(AndroidPlayer player,RenderGameOverlayEvent event)
{
int centerX = event.resolution.getScaledWidth() / 2;
int centerY = event.resolution.getScaledHeight() / 2;
int maxTime = AndroidPlayer.TRANSFORM_TIME;
int time = maxTime - player.getEffects().getInteger(AndroidPlayer.EFFECT_KEY_TURNING);
textTyping.setTime(time);
if (time % 40 > 0 && time % 40 < 3)
{
renderGlitch(player,event);
}
String info = textTyping.getString();
int width = mc.fontRenderer.getStringWidth(info);
mc.fontRenderer.drawString(info,centerX - width / 2,centerY - 28,Reference.COLOR_HOLO.getColor());
mc.renderEngine.bindTexture(spinner_tex);
glPushMatrix();
glTranslated(centerX, centerY,0);
glRotated(mc.theWorld.getWorldTime() * 10,0,0,-1);
glTranslated(-16,-16,0);
func_146110_a(0, 0, 0, 0, 32, 32, 32, 32);
glPopMatrix();
mc.fontRenderer.drawString(Math.round(textTyping.getPercent() * 100) + "%",centerX - 6,centerY - 3,Reference.COLOR_HOLO.getColor());
}
public void renderHurt(AndroidPlayer player,RenderGameOverlayEvent event)
{
if (player.getEffects().getInteger("GlitchTime") > 0)
{
renderGlitch(player,event);
}
}
public void renderGlitch(AndroidPlayer player,RenderGameOverlayEvent event) {
glBlendFunc(GL_ONE, GL_ONE);
glColor3d(1, 1, 1);
mc.renderEngine.bindTexture(glitch_tex);
RenderUtils.drawPlaneWithUV(0,0,-100,event.resolution.getScaledWidth(),event.resolution.getScaledHeight(),random.nextGaussian(),random.nextGaussian(),1,1);
}
@Override
public void onConfigChanged(ConfigurationHandler config)
{
Property prop = config.config.get(ConfigurationHandler.CATEGORY_ANDROID_HUD,hudMinimap.getName()+".position",hudMinimap.getDefaultPosition().ordinal());
prop.setConfigEntryClass(EnumConfigProperty.class);
prop.setValidValues(AndroidHudPosition.getNames());
prop.setLanguageKey("config.android_hud.minimap.position");
hudMinimap.setHudPosition(AndroidHudPosition.values()[prop.getInt()]);
prop = config.config.get(ConfigurationHandler.CATEGORY_ANDROID_HUD,hudStats.getName()+".position",hudStats.getDefaultPosition().ordinal());
prop.setConfigEntryClass(EnumConfigProperty.class);
prop.setValidValues(AndroidHudPosition.getNames());
prop.setLanguageKey("config.android_hud.stats.position");
hudStats.setHudPosition(AndroidHudPosition.values()[prop.getInt()]);
prop = config.config.get(ConfigurationHandler.CATEGORY_ANDROID_HUD,bionicStats.getName()+".position",bionicStats.getDefaultPosition().ordinal());
prop.setConfigEntryClass(EnumConfigProperty.class);
prop.setValidValues(AndroidHudPosition.getNames());
prop.setLanguageKey("config.android_hud.bionicStats.position");
bionicStats.setHudPosition(AndroidHudPosition.values()[prop.getInt()]);
Color color = Reference.COLOR_HOLO;
prop = config.config.get(ConfigurationHandler.CATEGORY_ANDROID_HUD,"hud_color",Integer.toHexString(color.getColor()));
prop.setLanguageKey("config.android_hud.color");
try {
baseGuiColor = new Color(Integer.parseInt(prop.getString(),16));
}
catch (Exception e)
{
baseGuiColor = Reference.COLOR_HOLO;
}
prop = config.config.get(ConfigurationHandler.CATEGORY_ANDROID_HUD,"hud_opacity",0.5f,"The Opacity of the HUD in %",0,1);
prop.setLanguageKey("config.android_hud.opacity");
baseGuiColor = new Color(baseGuiColor.getIntR(),baseGuiColor.getIntG(),baseGuiColor.getIntB(),(int)(255 * prop.getDouble()));
prop = config.config.get(ConfigurationHandler.CATEGORY_ANDROID_HUD,"hud_background_opacity",0F,"The opacity of the black background for each HUD element");
prop.setLanguageKey("config.android_hud.opacity_background");
opacityBackground = (float) prop.getDouble();
prop = config.config.get(ConfigurationHandler.CATEGORY_ANDROID_HUD,"hide_vanilla_hud_elements",true,"Should the health bar and food bar be hidden");
prop.setLanguageKey("config.android_hud.hide_vanilla");
hideVanillaHudElements = prop.getBoolean();
prop = config.config.get(ConfigurationHandler.CATEGORY_ANDROID_HUD,"hud_movement",true,"Should the Android HUD move when the player turns his head.");
prop.setLanguageKey("config.android_hud.hud_movement");
hudMovement = prop.getBoolean();
}
}