Skip to content

Commit

Permalink
Fix health bar renderer (#97)
Browse files Browse the repository at this point in the history
* delete unused locals

* add some code that has been forgotten when copying and overriding the vanilla renderHealth method

* create dedicated class HealthBarRenderer extending Gui to stop copy-pasting certain vanilla methods

* fix renegeration hearts moving when the game is paused

* only bind tinkers hearts textures if it's actually going to draw tinkers' hearts

* stop drawing vanilla hearts when they are hidden by tinkers' heart being drawn on top

* fix tinker's half heart not moving with regeneration

* fix drawing all tinkers' hearts on top of each others, and now only draw the top most hearts

* add comment to help with debugging
  • Loading branch information
Alexdoru authored Sep 24, 2023
1 parent abc424b commit 098783f
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 189 deletions.
196 changes: 7 additions & 189 deletions src/main/java/tconstruct/armor/ArmorProxyClient.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
package tconstruct.armor;

import java.util.Random;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.GuiIngameForge;
import net.minecraftforge.client.event.FOVUpdateEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
import net.minecraftforge.client.event.RenderPlayerEvent;
import net.minecraftforge.common.MinecraftForge;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import mantle.lib.client.MantleClientRegistry;
import tconstruct.armor.gui.ArmorExtendedGui;
import tconstruct.armor.gui.KnapsackGui;
Expand All @@ -42,6 +29,7 @@
import tconstruct.armor.player.KnapsackInventory;
import tconstruct.armor.player.TPlayerStats;
import tconstruct.client.ArmorControls;
import tconstruct.client.HealthBarRenderer;
import tconstruct.client.tabs.InventoryTabArmorExtended;
import tconstruct.client.tabs.InventoryTabKnapsack;
import tconstruct.client.tabs.InventoryTabVanilla;
Expand All @@ -55,19 +43,16 @@

public class ArmorProxyClient extends ArmorProxyCommon {

Minecraft mc = Minecraft.getMinecraft();

public static WingModel wings = new WingModel();
public static BootBump bootbump = new BootBump();
public static HiddenPlayerModel glove = new HiddenPlayerModel(0.25F, 4);
public static HiddenPlayerModel vest = new HiddenPlayerModel(0.25f, 1);
public static BeltModel belt = new BeltModel();

public static TPlayerStats playerStats = new TPlayerStats();

public static KnapsackInventory knapsack = new KnapsackInventory();
public static ArmorExtended armorExtended = new ArmorExtended();
private final boolean isRpghudLoaded = Loader.isModLoaded("rpghud");
private final boolean isTukmc_vzLoaded = Loader.isModLoaded("tukmc_Vz");
private final boolean isBorderlandsModLoaded = Loader.isModLoaded("borderlands");

@Override
public void preInit() {
Expand All @@ -84,7 +69,9 @@ public void initialize() {
registerManualIcons();
registerManualRecipes();
MinecraftForge.EVENT_BUS.register(this);
FMLCommonHandler.instance().bus().register(this);
final HealthBarRenderer healthBarRenderer = new HealthBarRenderer();
MinecraftForge.EVENT_BUS.register(healthBarRenderer);
FMLCommonHandler.instance().bus().register(healthBarRenderer);
}

private void registerManualIcons() {
Expand Down Expand Up @@ -230,15 +217,6 @@ public void registerKeys() {
TabRegistry.registerTab(new InventoryTabKnapsack());
}

Minecraft mc = Minecraft.getMinecraft();

private static final ResourceLocation hearts = new ResourceLocation("tinker", "textures/gui/newhearts.png");
private static final ResourceLocation icons = new ResourceLocation("textures/gui/icons.png");
// public static int left_height = 39;
// public static int right_height = 39;
Random rand = new Random();
int updateCounter = 0;

@SubscribeEvent
public void goggleZoom(FOVUpdateEvent event) {
if (ArmorControls.zoom) {
Expand All @@ -251,160 +229,6 @@ public void goggleZoom(FOVUpdateEvent event) {
// event.newfov = 1.0f;
}

@SubscribeEvent
public void onTick(TickEvent.ClientTickEvent event) {
if (event.phase == TickEvent.Phase.START) this.updateCounter++;
}

/* HUD */
@SubscribeEvent
public void renderHealthbar(RenderGameOverlayEvent.Pre event) {

if (event.type != ElementType.HEALTH) {
return;
}

// uses different display, displays health correctly by itself.
if (isRpghudLoaded) {
return;
}

if (isTukmc_vzLoaded && !isBorderlandsModLoaded) {
// Loader check to avoid conflicting
// with a GUI mod (thanks Vazkii!)
return;
}

int scaledWidth = event.resolution.getScaledWidth();
int scaledHeight = event.resolution.getScaledHeight();
int xBasePos = scaledWidth / 2 - 91;
int yBasePos = scaledHeight - 39;

boolean highlight = mc.thePlayer.hurtResistantTime / 3 % 2 == 1;

if (mc.thePlayer.hurtResistantTime < 10) {
highlight = false;
}

IAttributeInstance attrMaxHealth = this.mc.thePlayer.getEntityAttribute(SharedMonsterAttributes.maxHealth);
int health = MathHelper.ceiling_float_int(mc.thePlayer.getHealth());
int healthLast = MathHelper.ceiling_float_int(mc.thePlayer.prevHealth);
float healthMax = (float) attrMaxHealth.getAttributeValue();
if (healthMax > 20) healthMax = 20;
float absorb = this.mc.thePlayer.getAbsorptionAmount();

int healthRows = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F / 10.0F);
int rowHeight = Math.max(10 - (healthRows - 2), 3);

this.rand.setSeed(updateCounter * 312871L);

int left = scaledWidth / 2 - 91;
int top = scaledHeight - GuiIngameForge.left_height;

if (!GuiIngameForge.renderExperiance) {
top += 7;
yBasePos += 7;
}

int regen = -1;
if (mc.thePlayer.isPotionActive(Potion.regeneration)) {
regen = updateCounter % 25;
}

final int TOP = 9 * (mc.theWorld.getWorldInfo().isHardcoreModeEnabled() ? 5 : 0);
final int BACKGROUND = (highlight ? 25 : 16);
int MARGIN = 16;
if (mc.thePlayer.isPotionActive(Potion.poison)) MARGIN += 36;
else if (mc.thePlayer.isPotionActive(Potion.wither)) MARGIN += 72;
float absorbRemaining = absorb;

for (int i = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F) - 1; i >= 0; --i) {
int b0 = (highlight ? 1 : 0);
int row = MathHelper.ceiling_float_int((float) (i + 1) / 10.0F) - 1;
int x = left + i % 10 * 8;
int y = top - row * rowHeight;

if (health <= 4) y += rand.nextInt(2);
if (i == regen) y -= 2;

drawTexturedModalRect(x, y, BACKGROUND, TOP, 9, 9);

if (highlight) {
if (i * 2 + 1 < healthLast) drawTexturedModalRect(x, y, MARGIN + 54, TOP, 9, 9); // 6
else if (i * 2 + 1 == healthLast) drawTexturedModalRect(x, y, MARGIN + 63, TOP, 9, 9); // 7
}

if (absorbRemaining > 0.0F) {
if (absorbRemaining == absorb && absorb % 2.0F == 1.0F)
drawTexturedModalRect(x, y, MARGIN + 153, TOP, 9, 9); // 17
else drawTexturedModalRect(x, y, MARGIN + 144, TOP, 9, 9); // 16
absorbRemaining -= 2.0F;
} else {
if (i * 2 + 1 < health) drawTexturedModalRect(x, y, MARGIN + 36, TOP, 9, 9); // 4
else if (i * 2 + 1 == health) drawTexturedModalRect(x, y, MARGIN + 45, TOP, 9, 9); // 5
}
}

int potionOffset = 0;
PotionEffect potion = mc.thePlayer.getActivePotionEffect(Potion.wither);
if (potion != null) potionOffset = 18;
potion = mc.thePlayer.getActivePotionEffect(Potion.poison);
if (potion != null) potionOffset = 9;
if (mc.theWorld.getWorldInfo().isHardcoreModeEnabled()) potionOffset += 27;

// Extra hearts
this.mc.getTextureManager().bindTexture(hearts);

int hp = MathHelper.ceiling_float_int(this.mc.thePlayer.getHealth());
for (int iter = 0; iter < hp / 20; iter++) {
int renderHearts = (hp - 20 * (iter + 1)) / 2;
if (renderHearts > 10) renderHearts = 10;
for (int i = 0; i < renderHearts; i++) {
int y = 0;
if (i == regen) y -= 2;
this.drawTexturedModalRect(xBasePos + 8 * i, yBasePos + y, 0 + 18 * iter, potionOffset, 9, 9);
}
if (hp % 2 == 1 && renderHearts < 10) {
this.drawTexturedModalRect(xBasePos + 8 * renderHearts, yBasePos, 9 + 18 * iter, potionOffset, 9, 9);
}
}

this.mc.getTextureManager().bindTexture(icons);
GuiIngameForge.left_height += 10;
if (absorb > 0) GuiIngameForge.left_height += 10;

event.setCanceled(true);
}

public void drawTexturedModalRect(int par1, int par2, int par3, int par4, int par5, int par6) {
float f = 0.00390625F;
float f1 = 0.00390625F;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.addVertexWithUV(
par1 + 0,
par2 + par6,
this.zLevel,
(float) (par3 + 0) * f,
(float) (par4 + par6) * f1);
tessellator.addVertexWithUV(
par1 + par5,
par2 + par6,
this.zLevel,
(float) (par3 + par5) * f,
(float) (par4 + par6) * f1);
tessellator.addVertexWithUV(
par1 + par5,
par2 + 0,
this.zLevel,
(float) (par3 + par5) * f,
(float) (par4 + 0) * f1);
tessellator.addVertexWithUV(par1 + 0, par2 + 0, this.zLevel, (float) (par3 + 0) * f, (float) (par4 + 0) * f1);
tessellator.draw();
}

double zLevel = 0;

/* Armor rendering */
@SubscribeEvent
public void adjustArmor(RenderPlayerEvent.SetArmorModel event) {
Expand Down Expand Up @@ -445,17 +269,11 @@ public void adjustArmor(RenderPlayerEvent.SetArmorModel event) {
}

void renderArmorExtras(RenderPlayerEvent.SetArmorModel event) {
float partialTick = event.partialRenderTick;

EntityPlayer player = event.entityPlayer;

// todo: synchronize extra armor with other clients. Until then, only draw locally
if (player != Minecraft.getMinecraft().thePlayer) return;

float posX = (float) (player.lastTickPosX + (player.posX - player.lastTickPosX) * partialTick);
float posY = (float) (player.lastTickPosY + (player.posY - player.lastTickPosY) * partialTick);
float posZ = (float) (player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialTick);

float partialTick = event.partialRenderTick;
float yawOffset = this.interpolateRotation(player.prevRenderYawOffset, player.renderYawOffset, partialTick);
float yawRotation = this.interpolateRotation(player.prevRotationYawHead, player.rotationYawHead, partialTick);
float pitch;
Expand Down
Loading

0 comments on commit 098783f

Please sign in to comment.