Jump to content

Drawing a new bar.


joaogl

Recommended Posts

Having recently done this...

*Digs out code*

 

I actually added in an additional HP bar to act as "overflow healing" from a particular source (potions don't touch it, at least not without base class edits)

 

Here's the main bulk of what you need:

 

1) A ITickHandler

 

package draco18s.decay.client;

import java.util.EnumSet;

import org.lwjgl.opengl.GL11;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiIngame;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.nbt.NBTTagCompound;

import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
import draco18s.decay.PositiveDamage;

public class OverhealGUI implements ITickHandler
{
    public Minecraft mc;
    public int playerOverflowHp = 0;
    public int flag = 0;

    public OverhealGUI()
    {
        mc = Minecraft.getMinecraft();
    }

    @Override
    public void tickStart(EnumSet<TickType> type, Object... tickData)
    {
    }

    @Override
    public void tickEnd(EnumSet<TickType> type, Object... tickData)
    {
        ScaledResolution scaledresolution = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight);
        FontRenderer fontrenderer = mc.fontRenderer;
        int width = scaledresolution.getScaledWidth();
        int height = scaledresolution.getScaledHeight();
        mc.entityRenderer.setupOverlayRendering();

        if (type.equals(EnumSet.of(TickType.RENDER)))
        {
            onRenderTick();
        }
    }

    @Override
    public EnumSet<TickType> ticks()
    {
        EnumSet a;
        a = EnumSet.of(TickType.RENDER);
        return a;
    }

    @Override
    public String getLabel()
    {
        return "OverhealBar";
    }

    public void onRenderTick()
    {
        if (mc.currentScreen == null && !mc.thePlayer.capabilities.isCreativeMode)
        {
            GuiIngame gui = this.mc.ingameGUI;
            GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.mc.renderEngine.getTexture("/mods/DecayingWorld/textures/gui/overheal.png"));
            //System.out.println("Current hp: " + mc.thePlayer.getHealth());
            int hpo = playerOverflowHp;
            //hpo = 5;
            int u = (int)((double)hpo / 40 * 81);

            if (u > 0)
            {
                int u2 = ((int)((double)(hpo - (hpo % 4)) / 4) + 1) * 8 + 1;
                int v = 0;
                u++;
                int delay = 16;
                //System.out.println("flag " + flag);
                //This whole flag system was the best attempt I could make at making the bar "flash" like the vanilla one
                //when the player takes damage.  It's imperfect, but reasonably cool
                if (flag > 20 && flag < 20 + delay)
                {
                    v = 18;
                }
                else if (flag > 21 + delay * 2 && flag < 20 + delay * 3)
                {
                    v = 18;
                }
                else if (flag > 104)
                {
                    flag = 0;
                }

                //System.out.println(v);
                gui.drawTexturedModalRect(122, 209, 0, v, u, 9);
                gui.drawTexturedModalRect(122, 209, 0, v + 9, u2, 9);

                if (flag > 0)
                {
                    flag += 1;
                }
            }
            else {
            	flag = 0;
            }
        }
    }
}

 

 

2) PacketHandler

 

package draco18s.decay.network;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
import draco18s.decay.DecayingWorld;
import draco18s.decay.client.OverhealGUI;

public class PacketHandler implements IPacketHandler
{
    @Override
    public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
    {
        if (packet.channel.equals("MoreDecay"))
        {
            handleRandom(packet, player);
        }
    }

    private void handleRandom(Packet250CustomPayload packet, Player player)
    {
        EntityPlayer p = (EntityPlayer) player;
        World world = p.worldObj;
        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(packet.data));

        try
        {
            int guiId = dis.readInt();
            OverhealGUI gui = (OverhealGUI)DecayingWorld.overlayGui;

            switch (guiId)
            {
                case 1:
                    gui.playerOverflowHp = dis.readInt();
                    break;
                case 2:
                    gui.flag = 1;
                    break;
            }
        }
        catch (IOException e)
        {
            System.out.println("Failed to read packet");
        }
        finally
        {
        }
    }
}

 

 

3) EventHandler

 

package draco18s.decay;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Random;

import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;

import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.living.LivingEvent;

public class EntityDamagedEventHandler
{
    public EntityDamagedEventHandler()
    {
    }

    @ForgeSubscribe
    public void EntityDamaged(LivingHurtEvent event)
    {
        EntityLiving ent = event.entityLiving;
        NBTTagCompound nbt = ent.getEntityData();
        int hpo = nbt.getInteger("HealthOverflow");
        int hp = ent.getHealth();
        int mhp = ent.getMaxHealth();
        int newhp = hp;
        int newhpo = hpo;

        if (newhpo > mhp * 2)
        {
        }
        else if (hp < mhp)
        {
            newhp = Math.min(hp + hpo, mhp);
            newhpo = Math.max(hp + hpo - mhp, 0);
            ent.heal(newhp - hp);
            if(ent.isDead && (newhp - hp) > 0)
            	ent.isDead = false;
        }

        nbt.setInteger("HealthOverflow", newhpo);
        nbt.setBoolean("TookDamageFlag", true);

        if (ent instanceof EntityPlayer)
        {
            ByteArrayOutputStream bt = new ByteArrayOutputStream();
            DataOutputStream out = new DataOutputStream(bt);

            try
            {
                out.writeInt(2);
                out.writeBoolean(true);
                Packet250CustomPayload packet = new Packet250CustomPayload("MoreDecay", bt.toByteArray());
                Player player = (Player)ent;
                PacketDispatcher.sendPacketToAllAround(ent.posX, ent.posY, ent.posZ, 0.01, ent.worldObj.provider.dimensionId, packet);
            }
            catch (IOException ex)
            {
                System.out.println("couldnt send packet!");
            }
        }
    }
}

 

 

4) Registering it all

 

        overlayGui = new OverhealGUI();
        TickRegistry.registerTickHandler(overlayGui, Side.CLIENT);
        MinecraftForge.EVENT_BUS.register(new EntityDamagedEventHandler());

 

 

And the result:

 

 

 

I overlayed mine on top of the exp bar because:

a) I didn't want it above the armor bar

b) Covering a portion of the exp bar was not critical (there are still a few pixels visible for that section).

 

The only problem is that it renders on top of the chat. :\  Also, it goes away if another gui screen (chest, inventory, etc.) is open, but that's not a big deal.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Having recently done this...

*Digs out code*

 

I actually added in an additional HP bar to act as "overflow healing" from a particular source (potions don't touch it, at least not without base class edits)

 

Here's the main bulk of what you need:

 

1) A ITickHandler

 

package draco18s.decay.client;

import java.util.EnumSet;

import org.lwjgl.opengl.GL11;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiIngame;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.nbt.NBTTagCompound;

import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
import draco18s.decay.PositiveDamage;

public class OverhealGUI implements ITickHandler
{
    public Minecraft mc;
    public int playerOverflowHp = 0;
    public int flag = 0;

    public OverhealGUI()
    {
        mc = Minecraft.getMinecraft();
    }

    @Override
    public void tickStart(EnumSet<TickType> type, Object... tickData)
    {
    }

    @Override
    public void tickEnd(EnumSet<TickType> type, Object... tickData)
    {
        ScaledResolution scaledresolution = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight);
        FontRenderer fontrenderer = mc.fontRenderer;
        int width = scaledresolution.getScaledWidth();
        int height = scaledresolution.getScaledHeight();
        mc.entityRenderer.setupOverlayRendering();

        if (type.equals(EnumSet.of(TickType.RENDER)))
        {
            onRenderTick();
        }
    }

    @Override
    public EnumSet<TickType> ticks()
    {
        EnumSet a;
        a = EnumSet.of(TickType.RENDER);
        return a;
    }

    @Override
    public String getLabel()
    {
        return "OverhealBar";
    }

    public void onRenderTick()
    {
        if (mc.currentScreen == null && !mc.thePlayer.capabilities.isCreativeMode)
        {
            GuiIngame gui = this.mc.ingameGUI;
            GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.mc.renderEngine.getTexture("/mods/DecayingWorld/textures/gui/overheal.png"));
            //System.out.println("Current hp: " + mc.thePlayer.getHealth());
            int hpo = playerOverflowHp;
            //hpo = 5;
            int u = (int)((double)hpo / 40 * 81);

            if (u > 0)
            {
                int u2 = ((int)((double)(hpo - (hpo % 4)) / 4) + 1) * 8 + 1;
                int v = 0;
                u++;
                int delay = 16;
                //System.out.println("flag " + flag);
                //This whole flag system was the best attempt I could make at making the bar "flash" like the vanilla one
                //when the player takes damage.  It's imperfect, but reasonably cool
                if (flag > 20 && flag < 20 + delay)
                {
                    v = 18;
                }
                else if (flag > 21 + delay * 2 && flag < 20 + delay * 3)
                {
                    v = 18;
                }
                else if (flag > 104)
                {
                    flag = 0;
                }

                //System.out.println(v);
                gui.drawTexturedModalRect(122, 209, 0, v, u, 9);
                gui.drawTexturedModalRect(122, 209, 0, v + 9, u2, 9);

                if (flag > 0)
                {
                    flag += 1;
                }
            }
            else {
            	flag = 0;
            }
        }
    }
}

 

 

2) PacketHandler

 

package draco18s.decay.network;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
import draco18s.decay.DecayingWorld;
import draco18s.decay.client.OverhealGUI;

public class PacketHandler implements IPacketHandler
{
    @Override
    public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
    {
        if (packet.channel.equals("MoreDecay"))
        {
            handleRandom(packet, player);
        }
    }

    private void handleRandom(Packet250CustomPayload packet, Player player)
    {
        EntityPlayer p = (EntityPlayer) player;
        World world = p.worldObj;
        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(packet.data));

        try
        {
            int guiId = dis.readInt();
            OverhealGUI gui = (OverhealGUI)DecayingWorld.overlayGui;

            switch (guiId)
            {
                case 1:
                    gui.playerOverflowHp = dis.readInt();
                    break;
                case 2:
                    gui.flag = 1;
                    break;
            }
        }
        catch (IOException e)
        {
            System.out.println("Failed to read packet");
        }
        finally
        {
        }
    }
}

 

 

3) EventHandler

 

package draco18s.decay;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Random;

import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;

import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.living.LivingEvent;

public class EntityDamagedEventHandler
{
    public EntityDamagedEventHandler()
    {
    }

    @ForgeSubscribe
    public void EntityDamaged(LivingHurtEvent event)
    {
        EntityLiving ent = event.entityLiving;
        NBTTagCompound nbt = ent.getEntityData();
        int hpo = nbt.getInteger("HealthOverflow");
        int hp = ent.getHealth();
        int mhp = ent.getMaxHealth();
        int newhp = hp;
        int newhpo = hpo;

        if (newhpo > mhp * 2)
        {
        }
        else if (hp < mhp)
        {
            newhp = Math.min(hp + hpo, mhp);
            newhpo = Math.max(hp + hpo - mhp, 0);
            ent.heal(newhp - hp);
            if(ent.isDead && (newhp - hp) > 0)
            	ent.isDead = false;
        }

        nbt.setInteger("HealthOverflow", newhpo);
        nbt.setBoolean("TookDamageFlag", true);

        if (ent instanceof EntityPlayer)
        {
            ByteArrayOutputStream bt = new ByteArrayOutputStream();
            DataOutputStream out = new DataOutputStream(bt);

            try
            {
                out.writeInt(2);
                out.writeBoolean(true);
                Packet250CustomPayload packet = new Packet250CustomPayload("MoreDecay", bt.toByteArray());
                Player player = (Player)ent;
                PacketDispatcher.sendPacketToAllAround(ent.posX, ent.posY, ent.posZ, 0.01, ent.worldObj.provider.dimensionId, packet);
            }
            catch (IOException ex)
            {
                System.out.println("couldnt send packet!");
            }
        }
    }
}

 

 

4) Registering it all

 

        overlayGui = new OverhealGUI();
        TickRegistry.registerTickHandler(overlayGui, Side.CLIENT);
        MinecraftForge.EVENT_BUS.register(new EntityDamagedEventHandler());

 

 

And the result:

 

 

 

I overlayed mine on top of the exp bar because:

a) I didn't want it above the armor bar

b) Covering a portion of the exp bar was not critical (there are still a few pixels visible for that section).

 

The only problem is that it renders on top of the chat. :\  Also, it goes away if another gui screen (chest, inventory, etc.) is open, but that's not a big deal.

 

You could also use the Events Forge providesto render HUD stuff, look at the RenderGameOverlayEvent class and its sub-classes to get more information.

Don't ask for support per PM! They'll get ignored! | If a post helped you, click the "Thank You" button at the top right corner of said post! |

mah twitter

This thread makes me sad because people just post copy-paste-ready code when it's obvious that the OP has little to no programming experience. This is not how learning works.

Link to comment
Share on other sites

You could also use the Events Forge providesto render HUD stuff, look at the RenderGameOverlayEvent class and its sub-classes to get more information.

 

You certainly can!  I just don't have an example of it, because it requires a newer Forge than I can work with.

(Specifically because my mod is a plugin to another mod which doesn't work past 664).

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

You could also use the Events Forge providesto render HUD stuff, look at the RenderGameOverlayEvent class and its sub-classes to get more information.

 

You certainly can!  I just don't have an example of it, because it requires a newer Forge than I can work with.

(Specifically because my mod is a plugin to another mod which doesn't work past 664).

 

But I have one! https://gist.github.com/SanAndreasP/44bbf54c283e1d246946

Don't ask for support per PM! They'll get ignored! | If a post helped you, click the "Thank You" button at the top right corner of said post! |

mah twitter

This thread makes me sad because people just post copy-paste-ready code when it's obvious that the OP has little to no programming experience. This is not how learning works.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.