Initial work on DemonWillGauge

Includes the PacketHandler as well as the base system for HUDElements. Still need a replacement for the GuiConfig.
This commit is contained in:
WayofTime 2020-11-11 21:15:58 -05:00
parent 648b96601d
commit b6931a3116
17 changed files with 858 additions and 33 deletions

View file

@ -0,0 +1,45 @@
package wayoftime.bloodmagic.client.hud;
import net.minecraft.util.math.vector.Vector2f;
public class ElementInfo
{
public static final ElementInfo DUMMY = new ElementInfo(new Vector2f(0F, 0F), ElementRegistry.getRandomColor());
private final Vector2f defaultPosition;
private final int boxColor;
private Vector2f currentPosition;
public ElementInfo(Vector2f defaultPosition, int boxColor)
{
this.defaultPosition = defaultPosition;
this.boxColor = boxColor;
this.currentPosition = defaultPosition;
}
public Vector2f getDefaultPosition()
{
return defaultPosition;
}
public int getBoxColor()
{
return boxColor;
}
public ElementInfo setPosition(Vector2f position)
{
this.currentPosition = position;
return this;
}
public Vector2f getPosition()
{
return currentPosition;
}
public void resetPosition()
{
this.currentPosition = defaultPosition;
}
}

View file

@ -0,0 +1,185 @@
package wayoftime.bloodmagic.client.hud;
import java.awt.Color;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.List;
import java.util.Map;
import java.util.Random;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.Vector2f;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.loading.FMLPaths;
import wayoftime.bloodmagic.BloodMagic;
import wayoftime.bloodmagic.client.hud.element.HUDElement;
@Mod.EventBusSubscriber(modid = BloodMagic.MODID, value = Dist.CLIENT)
public class ElementRegistry
{
// private static final File CORNFIG = new File(Loader.instance().getConfigDir(), BloodMagic.MODID + "/hud_elements.json");
private static final File CONFIG = FMLPaths.CONFIGDIR.get().resolve(BloodMagic.MODID).resolve("hud_elements.json").toFile();
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Map<ResourceLocation, HUDElement> HUD_ELEMENTS = Maps.newLinkedHashMap();
private static final Map<HUDElement, ResourceLocation> REVERSE = Maps.newHashMap();
private static final Map<ResourceLocation, ElementInfo> ELEMENT_INFO = Maps.newHashMap();
public static void registerHandler(ResourceLocation key, HUDElement element, Vector2f defaultPosition)
{
HUD_ELEMENTS.put(key, element);
REVERSE.put(element, key);
ELEMENT_INFO.put(key, new ElementInfo(defaultPosition, getRandomColor()));
}
public static void resetPos()
{
ELEMENT_INFO.values().forEach(ElementInfo::resetPosition);
}
public static List<HUDElement> getElements()
{
return ImmutableList.copyOf(HUD_ELEMENTS.values());
}
public static ResourceLocation getKey(HUDElement element)
{
return REVERSE.get(element);
}
public static int getColor(ResourceLocation element)
{
return ELEMENT_INFO.getOrDefault(element, ElementInfo.DUMMY).getBoxColor();
}
public static Vector2f getPosition(ResourceLocation element)
{
return ELEMENT_INFO.get(element).getPosition();
}
public static void setPosition(ResourceLocation element, Vector2f point)
{
ELEMENT_INFO.compute(element, (resourceLocation, elementInfo) -> {
if (elementInfo == null)
return new ElementInfo(point, getRandomColor());
elementInfo.setPosition(point);
return elementInfo;
});
}
public static void save(Map<ResourceLocation, Vector2f> newLocations)
{
newLocations.forEach((k, v) -> {
ElementInfo info = ELEMENT_INFO.get(k);
if (info != null)
info.setPosition(v);
});
Map<String, Vector2f> toWrite = Maps.newHashMap();
for (Map.Entry<ResourceLocation, ElementInfo> entry : ELEMENT_INFO.entrySet())
toWrite.put(entry.getKey().toString(), entry.getValue().getPosition());
String json = GSON.toJson(toWrite);
try (FileWriter writer = new FileWriter(CONFIG))
{
writer.write(json);
} catch (Exception e)
{
e.printStackTrace();
}
}
public static void readConfig()
{
if (!CONFIG.exists())
return;
try (FileReader reader = new FileReader(CONFIG))
{
Map<String, Vector2f> toLoad = GSON.fromJson(reader, new TypeToken<Map<String, Vector2f>>()
{
}.getType());
for (Map.Entry<String, Vector2f> entry : toLoad.entrySet())
{
ElementInfo info = ELEMENT_INFO.get(new ResourceLocation(entry.getKey()));
if (info != null)
info.setPosition(entry.getValue());
}
} catch (Exception e)
{
e.printStackTrace();
}
}
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void onRenderOverlay(RenderGameOverlayEvent.Pre event)
{
if (event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR)
{
MainWindow window = event.getWindow();
for (HUDElement element : HUD_ELEMENTS.values())
{
if (!element.shouldRender(Minecraft.getInstance()))
continue;
// Vector2f position = ELEMENT_INFO.get(getKey(element)).getPosition();
// int xPos = (int) (resolution.getScaledWidth_double() * position.x);
// if (xPos - element.getWidth() < 0)
// xPos *= 2;
// if (xPos + element.getWidth() > resolution.getScaledWidth())
// xPos -= element.getWidth();
//
// int yPos = (int) (resolution.getScaledHeight_double() * position.y);
// if (yPos - element.getHeight() < 0)
// yPos *= 2;
// if (yPos + element.getHeight() > resolution.getScaledHeight())
// yPos -= element.getHeight();
//
// element.draw(event.getResolution(), event.getPartialTicks(), xPos, yPos);
Vector2f position = ELEMENT_INFO.get(getKey(element)).getPosition();
int xPos = (int) (window.getScaledWidth() * position.x);
if (xPos - element.getWidth() < 0)
xPos *= 2;
if (xPos + element.getWidth() > window.getScaledWidth())
xPos -= element.getWidth();
int yPos = (int) (window.getScaledHeight() * position.y);
if (yPos - element.getHeight() < 0)
yPos *= 2;
if (yPos + element.getHeight() > window.getScaledHeight())
yPos -= element.getHeight();
element.draw(event.getMatrixStack(), event.getPartialTicks(), xPos, yPos);
}
}
}
public static int getRandomColor()
{
Random rand = new Random();
float r = rand.nextFloat() / 2F + 0.5F;
float g = rand.nextFloat() / 2F + 0.5F;
float b = rand.nextFloat() / 2F + 0.5F;
float a = 0.5F;
return new Color(r, g, b, a).getRGB();
}
}

View file

@ -0,0 +1,14 @@
package wayoftime.bloodmagic.client.hud;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.Vector2f;
import wayoftime.bloodmagic.BloodMagic;
import wayoftime.bloodmagic.client.hud.element.ElementDemonAura;
public class Elements
{
public static void registerElements()
{
ElementRegistry.registerHandler(new ResourceLocation(BloodMagic.MODID, "demon_will_aura"), new ElementDemonAura(), new Vector2f(0.01F, 0.01F));
}
}

View file

@ -0,0 +1,239 @@
package wayoftime.bloodmagic.client.hud;
import java.awt.Point;
import java.util.Map;
import javax.annotation.Nullable;
import com.google.common.collect.Maps;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.Vector2f;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import wayoftime.bloodmagic.client.hud.element.HUDElement;
public class GuiEditHUD extends Screen
{
private static final int LINE_COLOR = 0x2D2D2D;
private final Screen parent;
private final Map<ResourceLocation, Vector2f> currentOverrides = Maps.newHashMap();
private HUDElement dragged;
public boolean changes;
public GuiEditHUD(Screen parent)
{
super(new StringTextComponent("Testing GuiEditHUD"));
this.parent = parent;
}
@Override
public void init()
{
super.init();
addButton(new Button(width / 2 - 155, height - 30, 70, 20, new TranslationTextComponent("gui.bloodmagic.toggle"), b -> {
Minecraft.getInstance().displayGuiScreen(parent);
})
{
{
active = false;
}
});
addButton(new Button(width / 2 - 75, height - 30, 70, 20, new TranslationTextComponent("gui.bloodmagic.default"), b -> {
currentOverrides.clear();
ElementRegistry.resetPos();
changes = false;
}));
addButton(new Button(width / 2 + 5, height - 30, 70, 20, new TranslationTextComponent("gui.bloodmagic.save"), b -> {
ElementRegistry.save(currentOverrides);
Minecraft.getInstance().displayGuiScreen(parent);
}));
addButton(new Button(width / 2 + 90, height - 30, 70, 20, new TranslationTextComponent("gui.bloodmagic.cancel"), b -> {
currentOverrides.clear();
Minecraft.getInstance().displayGuiScreen(parent);
}));
}
@Override
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks)
{
this.renderBackground(matrixStack);
super.render(matrixStack, mouseX, mouseY, partialTicks);
// ScaledResolution resolution = new ScaledResolution(Minecraft.getInstance());
MainWindow window = Minecraft.getInstance().getMainWindow();
for (HUDElement element : ElementRegistry.getElements())
{
if (dragged == element)
continue;
ResourceLocation key = ElementRegistry.getKey(element);
Vector2f position = currentOverrides.getOrDefault(key, ElementRegistry.getPosition(key));
int xPos = (int) (window.getScaledWidth() * position.x);
int yPos = (int) (window.getScaledHeight() * position.y);
drawWithBox(matrixStack, element, partialTicks, xPos, yPos);
}
if (dragged != null)
{
Point bounded = getBoundedDrag(window, mouseX, mouseY);
drawWithBox(matrixStack, dragged, partialTicks, bounded.x, bounded.y);
}
}
@Override
public boolean isPauseScreen()
{
return true;
}
@Override
// protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick)
public boolean mouseDragged(double mouseX, double mouseY, int button, double dragX, double dragY)
{
if (dragged == null)
{
HUDElement element = getHoveredElement(mouseX, mouseY);
if (element != null)
{
if (button == 0)
dragged = element;
}
}
return super.mouseDragged(mouseX, mouseY, button, dragX, dragY);
// if (dragged != null)
// return false;
//
// HUDElement element = getHoveredElement(mouseX, mouseY);
// if (element == null)
// return false;
//
// if (button == 0)
// dragged = element;
//
// return super.mouseDragged(mouseX, mouseY, button, dragX, dragY);
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int state)
{
if (dragged != null)
{
MainWindow window = Minecraft.getInstance().getMainWindow();
Point bounded = getBoundedDrag(window, mouseX, mouseY);
float xPos = (float) ((bounded.x) / window.getScaledWidth());
float yPos = (float) ((bounded.y) / window.getScaledHeight());
currentOverrides.put(ElementRegistry.getKey(dragged), new Vector2f(xPos, yPos));
changes = true;
dragged = null;
// return super;
}
return super.mouseReleased(mouseX, mouseY, state);
}
// @Override
// protected void actionPerformed(Button button)
// {
// switch (button.id)
// {
// case 0:
// {
// Minecraft.getInstance().displayGuiScreen(parent);
// break;
// }
// case 1:
// {
// currentOverrides.clear();
// ElementRegistry.resetPos();
// changes = false;
// break;
// }
// case 2:
// {
// ElementRegistry.save(currentOverrides);
// Minecraft.getInstance().displayGuiScreen(parent);
// break;
// }
// case 3:
// {
// currentOverrides.clear();
// Minecraft.getInstance().displayGuiScreen(parent);
// break;
// }
// }
// }
@Nullable
public HUDElement getHoveredElement(double mouseX, double mouseY)
{
MainWindow window = Minecraft.getInstance().getMainWindow();
for (HUDElement element : ElementRegistry.getElements())
{
ResourceLocation key = ElementRegistry.getKey(element);
Vector2f position = currentOverrides.getOrDefault(key, ElementRegistry.getPosition(key));
int xPos = (int) (window.getScaledWidth() * position.x);
int yPos = (int) (window.getScaledHeight() * position.y);
if (mouseX < xPos || mouseX > xPos + element.getWidth())
continue;
if (mouseY < yPos || mouseY > yPos + element.getHeight())
continue;
return element;
}
return null;
}
protected Point getBoundedDrag(MainWindow window, double mouseX, double mouseY)
{
int drawX = (int) (mouseX - dragged.getWidth() / 2);
if (drawX + dragged.getWidth() >= window.getScaledWidth())
drawX = window.getScaledWidth() - dragged.getWidth();
if (drawX < 0)
drawX = 0;
int drawY = (int) (mouseY - dragged.getHeight() / 2);
if (drawY + dragged.getHeight() >= window.getScaledHeight())
drawY = window.getScaledHeight() - dragged.getHeight();
if (drawY < 0)
drawY = 0;
return new Point(drawX, drawY);
}
protected void drawWithBox(MatrixStack matrixStack, HUDElement element, float partialTicks, int drawX, int drawY)
{
int color = ElementRegistry.getColor(ElementRegistry.getKey(element));
matrixStack.push();
// GlStateManager.enableAlpha();
// GlStateManager.enableBlend();
// GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
this.vLine(matrixStack, drawX, drawY, drawY + element.getHeight() - 1, color);
this.vLine(matrixStack, drawX + element.getWidth() - 1, drawY, drawY + element.getHeight() - 1, color);
this.hLine(matrixStack, drawX, drawX + element.getWidth() - 1, drawY, color);
this.hLine(matrixStack, drawX, drawX + element.getWidth() - 1, drawY + element.getHeight() - 1, color);
// GlStateManager.disableBlend();
// GlStateManager.disableAlpha();
matrixStack.pop();
// GlStateManager.color(1.0F, 1.0F, 1.0F);
// GlStateManager.enableTexture2D();
element.draw(matrixStack, partialTicks, drawX, drawY);
// GlStateManager.disableTexture2D();
}
}

View file

@ -0,0 +1,83 @@
package wayoftime.bloodmagic.client.hud.element;
import java.util.List;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ResourceLocation;
import wayoftime.bloodmagic.BloodMagic;
import wayoftime.bloodmagic.util.Utils;
import wayoftime.bloodmagic.util.handler.event.ClientHandler;
import wayoftime.bloodmagic.will.EnumDemonWillType;
public class ElementDemonAura extends HUDElement
{
private static final ResourceLocation BAR_LOCATION = new ResourceLocation(BloodMagic.MODID, "textures/hud/bars.png");
private final List<EnumDemonWillType> orderedTypes = Lists.newArrayList(EnumDemonWillType.DEFAULT, EnumDemonWillType.CORROSIVE, EnumDemonWillType.STEADFAST, EnumDemonWillType.DESTRUCTIVE, EnumDemonWillType.VENGEFUL);
public ElementDemonAura()
{
super(80, 46);
}
@Override
public void draw(MatrixStack matrixStack, float partialTicks, int drawX, int drawY)
{
Minecraft minecraft = Minecraft.getInstance();
PlayerEntity player = minecraft.player;
minecraft.getTextureManager().bindTexture(BAR_LOCATION);
// GlStateManager.color(1.0F, 1.0F, 1.0F);
this.blit(matrixStack, drawX, drawY, 0, 210, 80, 46);
double maxAmount = Utils.getDemonWillResolution(player);
int i = 0;
for (EnumDemonWillType type : orderedTypes)
{
i++;
// GlStateManager.color(1.0F, 1.0F, 1.0F);
minecraft.getTextureManager().bindTexture(BAR_LOCATION);
int textureXOffset = (i > 3) ? (i - 3) : (3 - i);
int maxBarSize = 30 - 2 * textureXOffset;
double amount = ClientHandler.currentAura == null ? 0 : ClientHandler.currentAura.getWill(type);
double ratio = Math.max(Math.min(amount / maxAmount, 1), 0);
// double amount = 50;
// double ratio = 0.5;
double width = maxBarSize * ratio * 2;
double height = 2;
double x = drawX + 2 * textureXOffset + 10;
double y = drawY + 4 * i + 10;
double textureX = 2 * textureXOffset + 2 * 42;
double textureY = 4 * i + 220;
this.blit(matrixStack, (int) x, (int) y, (int) textureX, (int) textureY, (int) width, (int) height);
if (player.isSneaking())
{
matrixStack.push();
matrixStack.translate(x - 2 * textureXOffset + 70, (y - 2), 0);
matrixStack.scale(0.5f, 0.5f, 1f);
minecraft.fontRenderer.drawStringWithShadow(matrixStack, String.valueOf((int) amount), 0, 2, 0xffffffff);
RenderSystem.clearTexGen();
matrixStack.pop();
}
}
}
@Override
public boolean shouldRender(Minecraft minecraft)
{
return Utils.canPlayerSeeDemonWill(Minecraft.getInstance().player);
}
}

View file

@ -0,0 +1,68 @@
package wayoftime.bloodmagic.client.hud.element;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.math.vector.Vector2f;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import wayoftime.bloodmagic.client.hud.ElementRegistry;
@OnlyIn(Dist.CLIENT)
public abstract class HUDElement
{
private int width;
private int height;
protected int blitOffset = 0;
public HUDElement(int width, int height)
{
this.width = width;
this.height = height;
}
public boolean shouldRender(Minecraft minecraft)
{
return true;
}
public abstract void draw(MatrixStack matrixStack, float partialTicks, int drawX, int drawY);
public final int getWidth()
{
return width;
}
public final int getHeight()
{
return height;
}
// protected void drawTexturedModalRect(double x, double y, double textureX, double textureY, double width, double height)
// {
// float f = 0.00390625F;
// float f1 = 0.00390625F;
// Tessellator tessellator = Tessellator.getInstance();
// BufferBuilder buffer = tessellator.getBuffer();
// buffer.begin(7, DefaultVertexFormats.POSITION_TEX);
// buffer.pos(x + 0, y + height, 0).tex((double) ((float) (textureX + 0) * f), (double) ((float) (textureY + height) * f1)).endVertex();
// buffer.pos(x + width, y + height, 0).tex((double) ((float) (textureX + width) * f), (double) ((float) (textureY + height) * f1)).endVertex();
// buffer.pos(x + width, y + 0, 0).tex((double) ((float) (textureX + width) * f), (double) ((float) (textureY + 0) * f1)).endVertex();
// buffer.pos(x + 0, y + 0, 0).tex((double) ((float) (textureX + 0) * f), (double) ((float) (textureY + 0) * f1)).endVertex();
// tessellator.draw();
// }
public void blit(MatrixStack matrixStack, int x, int y, int uOffset, int vOffset, int uWidth, int vHeight)
{
AbstractGui.blit(matrixStack, x, y, this.blitOffset, (float) uOffset, (float) vOffset, uWidth, vHeight, 256, 256);
}
@Override
public String toString()
{
Vector2f point = ElementRegistry.getPosition(ElementRegistry.getKey(this));
return ElementRegistry.getKey(this) + "@" + point.x + "," + point.y;
}
}