Retexture spell HUD, add different textures for survival/creative mode, and tidy up the GUI code

This commit is contained in:
Electroblob
2018-06-24 19:14:48 +01:00
parent fde5935adc
commit f6a24038cc
4 changed files with 102 additions and 65 deletions
@@ -168,7 +168,10 @@ public final class Settings {
/** Set of constants for each of the four positions that the spell HUD can be in. */ /** Set of constants for each of the four positions that the spell HUD can be in. */
public enum GuiPosition { public enum GuiPosition {
BOTTOM_LEFT("Bottom left"), TOP_LEFT("Top left"), TOP_RIGHT("Top right"), BOTTOM_RIGHT("Bottom right"); BOTTOM_LEFT("Bottom left", false, false),
TOP_LEFT("Top left", false, true),
TOP_RIGHT("Top right", true, true),
BOTTOM_RIGHT("Bottom right", true, false);
/** Constant array storing the names of each of the constants, in the order they are declared. */ /** Constant array storing the names of each of the constants, in the order they are declared. */
public static final String[] names; public static final String[] names;
@@ -182,8 +185,10 @@ public final class Settings {
/** The readable name for this GUI position that will be displayed on the button in the config GUI. */ /** The readable name for this GUI position that will be displayed on the button in the config GUI. */
public final String name; public final String name;
public boolean flipX;
public boolean flipY;
GuiPosition(String name){ GuiPosition(String name, boolean flipX, boolean flipY){
this.name = name; this.name = name;
} }
@@ -2,7 +2,6 @@ package electroblob.wizardry.client.gui;
import java.util.List; import java.util.List;
import electroblob.wizardry.Settings.GuiPosition;
import electroblob.wizardry.SpellGlyphData; import electroblob.wizardry.SpellGlyphData;
import electroblob.wizardry.WizardData; import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
@@ -30,11 +29,22 @@ public class GuiSpellDisplay extends Gui {
private Minecraft mc; private Minecraft mc;
private static final ResourceLocation hudTexture = new ResourceLocation(Wizardry.MODID, "textures/gui/spell_hud.png"); private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/spell_hud.png");
public GuiSpellDisplay(Minecraft par1Minecraft){ // Measurements
/** Width of the used portion of the HUD texture */ private static final int HUD_WIDTH = 128;
/** Height of the used portion of the HUD texture */ private static final int HUD_HEIGHT = 64;
/** Distance (in x and y) of the spell icon from the screen edge */ private static final int SPELL_ICON_INSET = 2;
/** Line spacing for the spell name (when on two lines) */ private static final int TEXT_LINE_SPACING = 1;
/** Distance in x from the edge of the screen to the spell name */ private static final int TEXT_INSET_X = 42;
/** Distance in x of the cooldown bar from the screen edge */ private static final int COOLDOWN_BAR_INSET_X = 42;
/** Length of the cooldown bar portion of the HUD texture */ private static final int COOLDOWN_BAR_LENGTH = 79;
/** Height of the cooldown bar portion of the HUD texture */ private static final int COOLDOWN_BAR_HEIGHT = 5;
/** Width and height of the spell icon (very unlikely to change!) */private static final int SPELL_ICON_SIZE = 32;
public GuiSpellDisplay(Minecraft minecraft){
super(); super();
this.mc = par1Minecraft; this.mc = minecraft;
} }
@SubscribeEvent @SubscribeEvent
@@ -65,26 +75,8 @@ public class GuiSpellDisplay extends Gui {
cooldownMultiplier /= 2 + player.getActivePotionEffect(WizardryPotions.font_of_mana).getAmplifier(); cooldownMultiplier /= 2 + player.getActivePotionEffect(WizardryPotions.font_of_mana).getAmplifier();
} }
// Coordinates of the top left corner of the HUD. boolean flipX = Wizardry.settings.spellHUDPosition.flipX;
int left = 0; boolean flipY = Wizardry.settings.spellHUDPosition.flipY;
int top = 0;
boolean mirror = false;
if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_LEFT){
left = 0;
top = height - 36;
}else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_LEFT){
left = 0;
top = 0;
}else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_RIGHT){
left = width - 128;
top = 0;
mirror = true;
}else if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_RIGHT){
left = width - 128;
top = height - 36;
mirror = true;
}
boolean discovered = true; boolean discovered = true;
@@ -100,50 +92,70 @@ public class GuiSpellDisplay extends Gui {
String spellName = discovered ? spell.getDisplayName() : SpellGlyphData.getGlyphName(spell, player.world); String spellName = discovered ? spell.getDisplayName() : SpellGlyphData.getGlyphName(spell, player.world);
FontRenderer font = discovered ? this.mc.fontRenderer : this.mc.standardGalacticFontRenderer; FontRenderer font = discovered ? this.mc.fontRenderer : this.mc.standardGalacticFontRenderer;
int maxWidth = 90; int maxWidth = HUD_WIDTH - TEXT_INSET_X;
int stringWidth = font.getStringWidth(spellName);
int iconMidpoint = (SPELL_ICON_SIZE + 2*SPELL_ICON_INSET)/2; // Should be 18
if(font.getStringWidth(spellName) <= maxWidth){ // TODO: Make a 'scrolling' animation when changing spells, using the text alpha channel to fade it in
// and out.
if(stringWidth <= maxWidth){
//GL11.glPushMatrix();
//GL11.glEnable(GL11.GL_BLEND);
//OpenGlHelper.glBlendFunc(770, 771, 1, 0); // Taken from GuiInGame. TODO: Replace with OpenGL caps.
// Single line is rendered more centrally // Single line is rendered more centrally
font.drawStringWithShadow(colour + spellName, mirror ? left + 5 : left + 41, top + 13, 0xffffffff); font.drawStringWithShadow(colour + spellName, flipX ? width - TEXT_INSET_X - stringWidth : TEXT_INSET_X,
// The text is an odd number of pixels high so we need to subtract an extra 1 when at the bottom
flipY ? iconMidpoint - font.FONT_HEIGHT/2 : height - iconMidpoint - font.FONT_HEIGHT/2 - 1, 0xffffffff);
//GL11.glDisable(GL11.GL_BLEND);
//GL11.glPopMatrix();
}else{ }else{
int lineNumber = 0; int lineNumber = 0;
List<String> lines = font.listFormattedStringToWidth(spellName, maxWidth); List<String> lines = font.listFormattedStringToWidth(spellName, maxWidth);
for(Object line : lines){ for(String line : lines){
if(line instanceof String){ int lineWidth = font.getStringWidth((String)line);
font.drawStringWithShadow(colour + (String)line, mirror ? left + 5 : left + 41, top + 6 + 11 * lineNumber, 0xffffffff); font.drawStringWithShadow(colour + (String)line, flipX ? width - TEXT_INSET_X - lineWidth : TEXT_INSET_X,
} // This time there are two lines so we need to subtract the full line height, and an extra 1 for the spacing
(flipY ? iconMidpoint - font.FONT_HEIGHT - 1 : height - iconMidpoint - font.FONT_HEIGHT - 1)
// Note that there should only ever be two lines maximum
+ lineNumber*(font.FONT_HEIGHT + TEXT_LINE_SPACING), 0xffffffff);
lineNumber++; lineNumber++;
} }
} }
}else if(event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR){ }else if(event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR){
GlStateManager.pushMatrix();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
GlStateManager.color(1, 1, 1); GlStateManager.color(1, 1, 1);
this.mc.renderEngine.bindTexture(hudTexture); // Spell illustration - this is now done first so it is behind the HUD texture
// Background of spell hud
this.drawTexturedModalRect(left, top, 0, mirror ? 36 : 0, 128, 36);
// Cooldown bar
if(cooldown > 0){
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 128, 6, 82, 6);
int l = (int)(((double)(spell.cooldown * cooldownMultiplier - cooldown) / (double)(spell.cooldown * cooldownMultiplier)) * 82);
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 128, 0, l, 6);
}
// Spell illustration
this.mc.renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon()); this.mc.renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon());
WizardryUtilities.drawTexturedRect(mirror ? left + 94 : left + 2, top + 2, 0, 0, 32, 32, 32, 32); WizardryUtilities.drawTexturedRect(flipX ? width - SPELL_ICON_INSET - SPELL_ICON_SIZE : SPELL_ICON_INSET,
flipY ? SPELL_ICON_INSET : height - SPELL_ICON_INSET - SPELL_ICON_SIZE, 0, 0, 32, 32, 32, 32);
this.mc.renderEngine.bindTexture(texture);
// Background of spell hud
WizardryUtilities.drawTexturedFlippedRect(flipX ? width-HUD_WIDTH : 0, flipY ? 0 : height-HUD_HEIGHT,
// The 128 here is a uv value, not a dimension, and hence is left as a hardcoded number.
player.capabilities.isCreativeMode ? 128 : 0, 0, HUD_WIDTH, HUD_HEIGHT, 256, 256, flipX, flipY);
// Cooldown bar
if(!player.capabilities.isCreativeMode && cooldown > 0){
int l = (int)(((double)(spell.cooldown * cooldownMultiplier - cooldown)
/ (double)(spell.cooldown * cooldownMultiplier)) * COOLDOWN_BAR_LENGTH);
// Likewise, the 64 here is a uv value and therefore left as a hardcoded number.
WizardryUtilities.drawTexturedFlippedRect(flipX ? width - COOLDOWN_BAR_INSET_X - COOLDOWN_BAR_LENGTH : COOLDOWN_BAR_INSET_X,
flipY ? 1 : height-1-COOLDOWN_BAR_HEIGHT, 0, 64, l, COOLDOWN_BAR_HEIGHT, 256, 256, false, flipY);
}
GlStateManager.popMatrix();
// Blend needs to be left enabled here because otherwise the hotbar becomes opaque // Blend needs to be left enabled here because otherwise the hotbar becomes opaque
} }
@@ -716,28 +716,48 @@ public final class WizardryUtilities {
* @param textureHeight The height of the actual image. * @param textureHeight The height of the actual image.
*/ */
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight){
int textureHeight){ drawTexturedFlippedRect(x, y, u, v, width, height, textureWidth, textureHeight, false, false);
}
/**
* <b>[Client-side only]</b> Draws a textured rectangle, taking the size of the image and the bit needed into
* account, unlike {@link net.minecraft.client.gui.Gui#drawTexturedModalRect(int, int, int, int, int, int)
* Gui.drawTexturedModalRect(int, int, int, int, int, int)}, which is harcoded for only 256x256 textures. Also handy
* for custom potion icons. This version allows the texture to be flipped in x and/or y.
*
* @param x The x position of the rectangle
* @param y The y position of the rectangle
* @param u The x position of the top left corner of the section of the image wanted
* @param v The y position of the top left corner of the section of the image wanted
* @param width The width of the section
* @param height The height of the section
* @param textureWidth The width of the actual image.
* @param textureHeight The height of the actual image.
* @param flipX Whether to flip the texture in the x direction.
* @param flipY Whether to flip the texture in the y direction.
*/
@SideOnly(Side.CLIENT)
public static void drawTexturedFlippedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight, boolean flipX, boolean flipY){
float f = 1F / (float)textureWidth; float f = 1F / (float)textureWidth;
float f1 = 1F / (float)textureHeight; float f1 = 1F / (float)textureHeight;
int u1 = flipX ? u + width : u;
int u2 = flipX ? u : u + width;
int v1 = flipY ? v + height : v;
int v2 = flipY ? v : v + height;
// Essentially the same as getting the tessellator. For most code, you'll want the tessellator AND the // Essentially the same as getting the tessellator. For most code, you'll want the tessellator AND the
// vertexbuffer // vertexbuffer stored in local variables.
// stored in local variables. BufferBuilder buffer = net.minecraft.client.renderer.Tessellator.getInstance().getBuffer();
BufferBuilder buffer = net.minecraft.client.renderer.Tessellator.getInstance()
.getBuffer();
// Equivalent of tessellator.startDrawingQuads() // Equivalent of tessellator.startDrawingQuads()
buffer.begin(org.lwjgl.opengl.GL11.GL_QUADS, buffer.begin(org.lwjgl.opengl.GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
// Equivalent of tessellator.addVertex() // Equivalent of tessellator.addVertex()
buffer.pos((double)(x), (double)(y + height), 0) buffer.pos((double)(x), (double)(y + height), 0).tex((double)((float)(u1) * f), (double)((float)(v2) * f1)).endVertex();
.tex((double)((float)(u) * f), (double)((float)(v + height) * f1)).endVertex(); buffer.pos((double)(x + width), (double)(y + height), 0).tex((double)((float)(u2) * f), (double)((float)(v2) * f1)).endVertex();
buffer.pos((double)(x + width), (double)(y + height), 0) buffer.pos((double)(x + width), (double)(y), 0).tex((double)((float)(u2) * f), (double)((float)(v1) * f1)).endVertex();
.tex((double)((float)(u + width) * f), (double)((float)(v + height) * f1)).endVertex(); buffer.pos((double)(x), (double)(y), 0).tex((double)((float)(u1) * f), (double)((float)(v1) * f1)).endVertex();
buffer.pos((double)(x + width), (double)(y), 0).tex((double)((float)(u + width) * f), (double)((float)(v) * f1))
.endVertex();
buffer.pos((double)(x), (double)(y), 0).tex((double)((float)(u) * f), (double)((float)(v) * f1)).endVertex();
// Exactly the same as before. // Exactly the same as before.
net.minecraft.client.renderer.Tessellator.getInstance().draw(); net.minecraft.client.renderer.Tessellator.getInstance().draw();
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 20 KiB