From 7167aba23c9d9285cf86e59132970c5468e17470 Mon Sep 17 00:00:00 2001 From: Nicholas Ignoffo Date: Mon, 12 Feb 2018 19:45:09 -0800 Subject: [PATCH] Move Divination output to a HUD element RIP chat spam 2014-2018 :hype: --- .../WayofTime/bloodmagic/client/Sprite.java | 56 +++++++++++ .../client/hud/HUDElementCornerTile.java | 89 ++++++++++++++++++ .../item/sigil/ItemSigilDivination.java | 32 ------- .../bloodmagic/item/sigil/ItemSigilSeer.java | 37 -------- .../bloodmagic/proxy/ClientProxy.java | 43 +++++++++ .../bloodmagic/textures/gui/widgets.png | Bin 22017 -> 24967 bytes 6 files changed, 188 insertions(+), 69 deletions(-) create mode 100644 src/main/java/WayofTime/bloodmagic/client/Sprite.java create mode 100644 src/main/java/WayofTime/bloodmagic/client/hud/HUDElementCornerTile.java diff --git a/src/main/java/WayofTime/bloodmagic/client/Sprite.java b/src/main/java/WayofTime/bloodmagic/client/Sprite.java new file mode 100644 index 00000000..795286a0 --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/client/Sprite.java @@ -0,0 +1,56 @@ +package WayofTime.bloodmagic.client; + +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.ResourceLocation; + +public class Sprite { + + private final ResourceLocation textureLocation; + private final int textureX; + private final int textureY; + private final int textureWidth; + private final int textureHeight; + + public Sprite(ResourceLocation textureLocation, int textureX, int textureY, int textureWidth, int textureHeight) { + this.textureLocation = textureLocation; + this.textureX = textureX; + this.textureY = textureY; + this.textureWidth = textureWidth; + this.textureHeight = textureHeight; + } + + public ResourceLocation getTextureLocation() { + return textureLocation; + } + + public int getTextureX() { + return textureX; + } + + public int getTextureY() { + return textureY; + } + + public int getTextureWidth() { + return textureWidth; + } + + public int getTextureHeight() { + return textureHeight; + } + + public void draw(int x, int y) { + float f = 0.00390625F; + float f1 = 0.00390625F; + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + buffer.begin(7, DefaultVertexFormats.POSITION_TEX); + buffer.pos((double) x, (double) (y + getTextureHeight()), 1.0F).tex((double) ((float) (getTextureX()) * f), (double) ((float) (getTextureY() + getTextureHeight()) * f1)).endVertex(); + buffer.pos((double) (x + getTextureWidth()), (double) (y + getTextureHeight()), 1.0F).tex((double) ((float) (getTextureX() + getTextureWidth()) * f), (double) ((float) (getTextureY() + getTextureHeight()) * f1)).endVertex(); + buffer.pos((double) (x + getTextureWidth()), (double) (y), 1.0F).tex((double) ((float) (getTextureX() + getTextureWidth()) * f), (double) ((float) (getTextureY()) * f1)).endVertex(); + buffer.pos((double) x, (double) (y), 1.0F).tex((double) ((float) (getTextureX()) * f), (double) ((float) (getTextureY()) * f1)).endVertex(); + tessellator.draw(); + } +} diff --git a/src/main/java/WayofTime/bloodmagic/client/hud/HUDElementCornerTile.java b/src/main/java/WayofTime/bloodmagic/client/hud/HUDElementCornerTile.java new file mode 100644 index 00000000..207fde44 --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/client/hud/HUDElementCornerTile.java @@ -0,0 +1,89 @@ +package WayofTime.bloodmagic.client.hud; + +import WayofTime.bloodmagic.client.Sprite; +import WayofTime.bloodmagic.item.sigil.ItemSigilDivination; +import WayofTime.bloodmagic.item.sigil.ItemSigilSeer; +import WayofTime.bloodmagic.tile.TileAltar; +import com.google.common.collect.Lists; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumHand; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import org.apache.commons.lang3.tuple.Pair; + +import java.awt.Color; +import java.util.List; +import java.util.function.Function; + +public abstract class HUDElementCornerTile extends HUDElement { + + protected final List>> information; + + public HUDElementCornerTile() { + super(5, 5, RenderGameOverlayEvent.ElementType.HOTBAR); + + this.information = Lists.newArrayList(); + addInformation(information); + } + + protected abstract void addInformation(List>> information); + + @SuppressWarnings("unchecked") + @Override + public void render(Minecraft minecraft, ScaledResolution resolution, float partialTicks) { + T tile = (T) Minecraft.getMinecraft().world.getTileEntity(Minecraft.getMinecraft().objectMouseOver.getBlockPos()); + + int yOffset = 0; + for (Pair> sprite : information) { + Minecraft.getMinecraft().renderEngine.bindTexture(sprite.getLeft().getTextureLocation()); + sprite.getLeft().draw(getXOffset(), getYOffset() + yOffset); + int textY = getYOffset() + yOffset + (sprite.getLeft().getTextureHeight() / 4); + Minecraft.getMinecraft().fontRenderer.drawStringWithShadow(sprite.getRight().apply(tile), getXOffset() + sprite.getLeft().getTextureWidth() + 2, textY, Color.WHITE.getRGB()); + yOffset += sprite.getLeft().getTextureHeight() + 2; + } + } + + public static abstract class BloodAltar extends HUDElementCornerTile { + + private final boolean simple; + + public BloodAltar(boolean simple) { + this.simple = simple; + } + + @Override + public boolean shouldRender(Minecraft minecraft) { + EntityPlayer player = Minecraft.getMinecraft().player; + ItemStack sigilStack = player.getHeldItem(EnumHand.MAIN_HAND); + boolean flag = false; + if (simple) { + if (sigilStack.getItem() instanceof ItemSigilDivination) + flag = true; + + if (!flag) { + sigilStack = player.getHeldItem(EnumHand.OFF_HAND); + if (sigilStack.getItem() instanceof ItemSigilDivination) + flag = true; + } + } else { + if (sigilStack.getItem() instanceof ItemSigilSeer) + flag = true; + + if (!flag) { + sigilStack = player.getHeldItem(EnumHand.OFF_HAND); + if (sigilStack.getItem() instanceof ItemSigilSeer) + flag = true; + } + } + + TileEntity tile = Minecraft.getMinecraft().world.getTileEntity(Minecraft.getMinecraft().objectMouseOver.getBlockPos()); + if (!(tile instanceof TileAltar)) + flag = false; + + return flag; + } + } +} diff --git a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilDivination.java b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilDivination.java index 13f9c407..4f97fab1 100644 --- a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilDivination.java +++ b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilDivination.java @@ -1,17 +1,12 @@ package WayofTime.bloodmagic.item.sigil; -import WayofTime.bloodmagic.apibutnotreally.altar.IBloodAltar; import WayofTime.bloodmagic.apibutnotreally.iface.IAltarReader; import WayofTime.bloodmagic.apibutnotreally.iface.ISigil; import WayofTime.bloodmagic.apibutnotreally.util.helper.NetworkHelper; import WayofTime.bloodmagic.apibutnotreally.util.helper.PlayerHelper; -import WayofTime.bloodmagic.tile.TileIncenseAltar; -import WayofTime.bloodmagic.tile.TileInversionPillar; import WayofTime.bloodmagic.util.ChatUtil; -import WayofTime.bloodmagic.util.helper.NumeralHelper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; @@ -63,33 +58,6 @@ public class ItemSigilDivination extends ItemSigilBase implements IAltarReader { toSend.add(new TextComponentTranslation(tooltipBase + "otherNetwork", getOwnerName(stack))); toSend.add(new TextComponentTranslation(tooltipBase + "currentEssence", currentEssence)); ChatUtil.sendNoSpam(player, toSend.toArray(new ITextComponent[toSend.size()])); - } else { - if (position.typeOfHit == RayTraceResult.Type.BLOCK) { - TileEntity tile = world.getTileEntity(position.getBlockPos()); - - if (tile != null && tile instanceof IBloodAltar) { - IBloodAltar altar = (IBloodAltar) tile; - int tier = altar.getTier().ordinal() + 1; - int currentEssence = altar.getCurrentBlood(); - int capacity = altar.getCapacity(); - altar.checkTier(); - ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentAltarTier", NumeralHelper.toRoman(tier)), new TextComponentTranslation(tooltipBase + "currentEssence", currentEssence), new TextComponentTranslation(tooltipBase + "currentAltarCapacity", capacity)); - } else if (tile != null && tile instanceof TileIncenseAltar) { - TileIncenseAltar altar = (TileIncenseAltar) tile; - altar.recheckConstruction(); - double tranquility = altar.tranquility; - ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentTranquility", (int) ((100D * (int) (100 * tranquility)) / 100d)), new TextComponentTranslation(tooltipBase + "currentBonus", (int) (100 * altar.incenseAddition))); - } else if (tile != null && tile instanceof TileInversionPillar) { - TileInversionPillar pillar = (TileInversionPillar) tile; - double inversion = pillar.getCurrentInversion(); - ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentInversion", ((int) (10 * inversion)) / 10d)); - } else - - { - int currentEssence = NetworkHelper.getSoulNetwork(getOwnerUUID(stack)).getCurrentEssence(); - ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentEssence", currentEssence)); - } - } } } diff --git a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilSeer.java b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilSeer.java index fc2fb523..ffb2eb29 100644 --- a/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilSeer.java +++ b/src/main/java/WayofTime/bloodmagic/item/sigil/ItemSigilSeer.java @@ -1,17 +1,12 @@ package WayofTime.bloodmagic.item.sigil; -import WayofTime.bloodmagic.apibutnotreally.altar.IBloodAltar; import WayofTime.bloodmagic.apibutnotreally.iface.IAltarReader; import WayofTime.bloodmagic.apibutnotreally.iface.ISigil; import WayofTime.bloodmagic.apibutnotreally.util.helper.NetworkHelper; import WayofTime.bloodmagic.apibutnotreally.util.helper.PlayerHelper; -import WayofTime.bloodmagic.tile.TileIncenseAltar; import WayofTime.bloodmagic.util.ChatUtil; -import WayofTime.bloodmagic.util.helper.NumeralHelper; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; @@ -48,38 +43,6 @@ public class ItemSigilSeer extends ItemSigilBase implements IAltarReader { toSend.add(new TextComponentTranslation(tooltipBase + "otherNetwork", getOwnerName(stack))); toSend.add(new TextComponentTranslation(tooltipBase + "currentEssence", currentEssence)); ChatUtil.sendNoSpam(player, toSend.toArray(new ITextComponent[toSend.size()])); - } else { - if (rayTrace.typeOfHit == RayTraceResult.Type.BLOCK) { - - TileEntity tile = world.getTileEntity(rayTrace.getBlockPos()); - - if (tile != null && tile instanceof IBloodAltar) { - IBloodAltar altar = (IBloodAltar) tile; - int tier = altar.getTier().ordinal() + 1; - int currentEssence = altar.getCurrentBlood(); - int capacity = altar.getCapacity(); - int charge = altar.getTotalCharge(); - altar.checkTier(); - if (tile instanceof IInventory) { - if (!((IInventory) tile).getStackInSlot(0).isEmpty()) { - int progress = altar.getProgress(); - int totalLiquidRequired = altar.getLiquidRequired() * ((IInventory) tile).getStackInSlot(0).getCount(); - int consumptionRate = (int) (altar.getConsumptionRate() * (altar.getConsumptionMultiplier() + 1)); - ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentAltarProgress", progress, totalLiquidRequired), new TextComponentTranslation(tooltipBase + "currentAltarConsumptionRate", consumptionRate), new TextComponentTranslation(tooltipBase + "currentAltarTier", NumeralHelper.toRoman(tier)), new TextComponentTranslation(tooltipBase + "currentEssence", currentEssence), new TextComponentTranslation(tooltipBase + "currentAltarCapacity", capacity), new TextComponentTranslation(tooltipBase + "currentCharge", charge)); - } else { - ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentAltarTier", NumeralHelper.toRoman(tier)), new TextComponentTranslation(tooltipBase + "currentEssence", currentEssence), new TextComponentTranslation(tooltipBase + "currentAltarCapacity", capacity), new TextComponentTranslation(tooltipBase + "currentCharge", charge)); - } - } - } else if (tile != null && tile instanceof TileIncenseAltar) { - TileIncenseAltar altar = (TileIncenseAltar) tile; - altar.recheckConstruction(); - double tranquility = altar.tranquility; - ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentTranquility", (int) ((100D * (int) (100 * tranquility)) / 100d)), new TextComponentTranslation(tooltipBase + "currentBonus", (int) (100 * altar.incenseAddition))); - } else { - int currentEssence = NetworkHelper.getSoulNetwork(getOwnerUUID(stack)).getCurrentEssence(); - ChatUtil.sendNoSpam(player, new TextComponentTranslation(tooltipBase + "currentEssence", currentEssence)); - } - } } } diff --git a/src/main/java/WayofTime/bloodmagic/proxy/ClientProxy.java b/src/main/java/WayofTime/bloodmagic/proxy/ClientProxy.java index 42ef7613..26a98d86 100644 --- a/src/main/java/WayofTime/bloodmagic/proxy/ClientProxy.java +++ b/src/main/java/WayofTime/bloodmagic/proxy/ClientProxy.java @@ -5,7 +5,9 @@ import WayofTime.bloodmagic.apibutnotreally.Constants; import WayofTime.bloodmagic.apibutnotreally.soul.DemonWillHolder; import WayofTime.bloodmagic.client.IMeshProvider; import WayofTime.bloodmagic.client.IVariantProvider; +import WayofTime.bloodmagic.client.Sprite; import WayofTime.bloodmagic.client.helper.ShaderHelper; +import WayofTime.bloodmagic.client.hud.HUDElementCornerTile; import WayofTime.bloodmagic.client.hud.HUDElementDemonWillAura; import WayofTime.bloodmagic.client.hud.HUDElementHolding; import WayofTime.bloodmagic.client.key.KeyBindings; @@ -20,6 +22,7 @@ import WayofTime.bloodmagic.entity.projectile.EntitySentientArrow; import WayofTime.bloodmagic.entity.projectile.EntitySoulSnare; import WayofTime.bloodmagic.tile.*; import WayofTime.bloodmagic.tile.routing.TileRoutingNode; +import WayofTime.bloodmagic.util.helper.NumeralHelper; import com.google.common.collect.ImmutableMap; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; @@ -42,7 +45,9 @@ import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import org.apache.commons.lang3.tuple.Pair; import java.awt.Color; +import java.util.List; import java.util.Map; +import java.util.function.Function; public class ClientProxy extends CommonProxy { public static DemonWillHolder currentAura = new DemonWillHolder(); @@ -118,6 +123,44 @@ public class ClientProxy extends CommonProxy { public void postInit() { new HUDElementHolding(); new HUDElementDemonWillAura(); + new HUDElementCornerTile.BloodAltar(true) { // Divination Sigil + @Override + protected void addInformation(List>> information) { + information.add(Pair.of(new Sprite(new ResourceLocation(BloodMagic.MODID, "textures/gui/widgets.png"), 0, 46, 16, 16), altar -> NumeralHelper.toRoman(altar.getTier().toInt()))); + information.add(Pair.of(new Sprite(new ResourceLocation(BloodMagic.MODID, "textures/gui/widgets.png"), 16, 46, 16, 16), altar -> String.format("%d/%d", altar.getCurrentBlood(), altar.getCapacity()))); + } + }; + new HUDElementCornerTile.BloodAltar(false) { // Seer Sigil + @Override + protected void addInformation(List>> information) { + information.add(Pair.of( + new Sprite(new ResourceLocation(BloodMagic.MODID, "textures/gui/widgets.png"), 0, 46, 16, 16), + altar -> NumeralHelper.toRoman(altar.getTier().toInt()) + )); + information.add(Pair.of( + new Sprite(new ResourceLocation(BloodMagic.MODID, "textures/gui/widgets.png"), 16, 46, 16, 16), + altar -> String.format("%d/%d", altar.getCurrentBlood(), altar.getCapacity()) + )); + information.add(Pair.of( // Craft Progress + new Sprite(new ResourceLocation(BloodMagic.MODID, "textures/gui/widgets.png"), 32, 46, 16, 16), + altar -> { + if (!altar.isActive()) + return "Inactive"; // FIXME localize + int progress = altar.getProgress(); + int totalLiquidRequired = altar.getLiquidRequired() * altar.getStackInSlot(0).getCount(); + return String.format("%d/%d", progress, totalLiquidRequired); + } + )); + information.add(Pair.of( + new Sprite(new ResourceLocation(BloodMagic.MODID, "textures/gui/widgets.png"), 48, 46, 16, 16), + altar -> String.valueOf((int) (altar.getConsumptionRate() * (altar.getConsumptionMultiplier() + 1))) + )); + information.add(Pair.of( + new Sprite(new ResourceLocation(BloodMagic.MODID, "textures/gui/widgets.png"), 64, 46, 16, 16), + altar -> String.valueOf(altar.getTotalCharge()) + )); + } + }; } @Override diff --git a/src/main/resources/assets/bloodmagic/textures/gui/widgets.png b/src/main/resources/assets/bloodmagic/textures/gui/widgets.png index 456166c9145b8337c66386ce688b5ec30a2eb1dd..6d8d9cfe1c773bcda8dbd235b756b045a7817ebf 100644 GIT binary patch delta 6789 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 JDmCq*{sYpBJxl-q delta 4177 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