mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-02 17:57:59 +03:00
285 lines
5.5 KiB
C++
285 lines
5.5 KiB
C++
#include "framework.h"
|
|
#include "Game/health.h"
|
|
|
|
#include "Game/animation.h"
|
|
#include "Game/camera.h"
|
|
#include "Game/control/control.h"
|
|
#include "Game/items.h"
|
|
#include "Game/Lara/lara.h"
|
|
#include "Game/Lara/lara_helpers.h"
|
|
#include "Game/Lara/lara_tests.h"
|
|
#include "Game/pickup/pickup.h"
|
|
#include "Renderer/Renderer11.h"
|
|
#include "Specific/level.h"
|
|
|
|
using namespace TEN::Renderer;
|
|
short PickupX;
|
|
short PickupY;
|
|
short CurrentPickup;
|
|
DisplayPickup Pickups[MAX_COLLECTED_PICKUPS];
|
|
short PickupVel;
|
|
int OldHitPoints = LARA_HEALTH_MAX;
|
|
int HealthBarTimer = 40;
|
|
float HealthBar = OldHitPoints;
|
|
float MutateAmount = 0;
|
|
int FlashState = 0;
|
|
int FlashCount = 0;
|
|
int PoisonFlag = 0;
|
|
extern RendererHUDBar* g_HealthBar;
|
|
extern RendererHUDBar* g_DashBar;
|
|
extern RendererHUDBar* g_AirBar;
|
|
|
|
bool EnableSmoothHealthBar = true;
|
|
|
|
void DrawHealthBarOverlay(ITEM_INFO* item, int value)
|
|
{
|
|
auto* lara = GetLaraInfo(item);
|
|
|
|
if (CurrentLevel)
|
|
{
|
|
int color2 = 0;
|
|
if (lara->PoisonPotency)
|
|
color2 = 0xA0A000;
|
|
else
|
|
color2 = 0xA00000;
|
|
|
|
g_Renderer.drawBar(value, ::g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, lara->PoisonPotency);
|
|
}
|
|
}
|
|
|
|
void DrawHealthBar(ITEM_INFO* item, float value)
|
|
{
|
|
auto* lara = GetLaraInfo(item);
|
|
|
|
if (CurrentLevel)
|
|
g_Renderer.drawBar(value, ::g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, lara->PoisonPotency);
|
|
}
|
|
|
|
void UpdateHealthBar(ITEM_INFO* item, int flash)
|
|
{
|
|
auto* lara = GetLaraInfo(item);
|
|
|
|
auto HitPoints = item->HitPoints;
|
|
|
|
if (HitPoints < 0)
|
|
HitPoints = 0;
|
|
else if (HitPoints > LARA_HEALTH_MAX)
|
|
HitPoints = LARA_HEALTH_MAX;
|
|
|
|
// OPT: smoothly transition health bar display.
|
|
if (EnableSmoothHealthBar)
|
|
{
|
|
if (OldHitPoints != HitPoints)
|
|
{
|
|
MutateAmount += OldHitPoints - HitPoints;
|
|
OldHitPoints = HitPoints;
|
|
HealthBarTimer = 40;
|
|
}
|
|
|
|
if (HealthBar - MutateAmount < 0)
|
|
MutateAmount = HealthBar;
|
|
else if (HealthBar - MutateAmount > LARA_HEALTH_MAX)
|
|
MutateAmount = HealthBar - LARA_HEALTH_MAX;
|
|
|
|
HealthBar -= MutateAmount / 3;
|
|
MutateAmount -= MutateAmount / 3;
|
|
|
|
if (MutateAmount > -0.5f && MutateAmount < 0.5f)
|
|
{
|
|
MutateAmount = 0;
|
|
HealthBar = HitPoints;
|
|
}
|
|
}
|
|
|
|
// OG: discretely transition health bar display.
|
|
else
|
|
{
|
|
if (OldHitPoints != HitPoints)
|
|
{
|
|
OldHitPoints = HitPoints;
|
|
HealthBar = HitPoints;
|
|
HealthBarTimer = 40;
|
|
}
|
|
}
|
|
|
|
if (HealthBarTimer < 0)
|
|
HealthBarTimer = 0;
|
|
|
|
// Flash when at 1/4 capacity AND HP bar is not transitioning.
|
|
if (HealthBar <= LARA_HEALTH_MAX / 4)
|
|
{
|
|
if (!BinocularRange)
|
|
{
|
|
if (flash)
|
|
DrawHealthBar(item, HealthBar / LARA_HEALTH_MAX);
|
|
else
|
|
DrawHealthBar(item, 0);
|
|
}
|
|
else
|
|
{
|
|
if (flash)
|
|
DrawHealthBarOverlay(item, HealthBar / LARA_HEALTH_MAX);
|
|
else
|
|
DrawHealthBarOverlay(item, 0);
|
|
}
|
|
}
|
|
else if (HealthBarTimer > 0 || HealthBar <= 0 ||
|
|
lara->Control.HandStatus == HandStatus::WeaponReady &&
|
|
lara->Control.Weapon.GunType != LaraWeaponType::Torch ||
|
|
lara->PoisonPotency)
|
|
{
|
|
if (!BinocularRange)
|
|
DrawHealthBar(item, HealthBar / LARA_HEALTH_MAX);
|
|
else
|
|
DrawHealthBarOverlay(item, HealthBar / LARA_HEALTH_MAX);
|
|
}
|
|
|
|
if (PoisonFlag)
|
|
PoisonFlag--;
|
|
}
|
|
|
|
void DrawAirBar(float value)
|
|
{
|
|
if (CurrentLevel)
|
|
g_Renderer.drawBar(value, ::g_AirBar,ID_AIR_BAR_TEXTURE,0,0);
|
|
}
|
|
|
|
void UpdateAirBar(ITEM_INFO* item, int flash)
|
|
{
|
|
auto* lara = GetLaraInfo(item);
|
|
|
|
if (lara->Air == LARA_AIR_MAX || item->HitPoints <= 0)
|
|
return;
|
|
|
|
if (lara->Vehicle == NO_ITEM ||
|
|
g_Level.Items[lara->Vehicle].ObjectNumber != ID_UPV)
|
|
{
|
|
if (lara->Control.WaterStatus != WaterStatus::Underwater &&
|
|
lara->Control.WaterStatus != WaterStatus::TreadWater &&
|
|
!(TestEnvironment(ENV_FLAG_SWAMP, item) && lara->WaterSurfaceDist < -(CLICK(3) - 1)))
|
|
return;
|
|
}
|
|
|
|
int air = lara->Air;
|
|
if (air < 0)
|
|
air = 0;
|
|
else if (air > LARA_AIR_MAX)
|
|
air = LARA_AIR_MAX;
|
|
|
|
if (air <= (LARA_AIR_MAX / 4))
|
|
{
|
|
if (flash)
|
|
DrawAirBar(air / LARA_AIR_MAX);
|
|
else
|
|
DrawAirBar(0);
|
|
}
|
|
else
|
|
DrawAirBar(air / LARA_AIR_MAX);
|
|
}
|
|
|
|
void DrawSprintBar(float value)
|
|
{
|
|
if (CurrentLevel)
|
|
g_Renderer.drawBar(value, ::g_DashBar, ID_DASH_BAR_TEXTURE, 0, 0);
|
|
}
|
|
|
|
void UpdateSprintBar(ITEM_INFO* item)
|
|
{
|
|
auto* lara = GetLaraInfo(item);
|
|
|
|
if (lara->SprintEnergy < LARA_SPRINT_MAX)
|
|
DrawSprintBar(lara->SprintEnergy / LARA_SPRINT_MAX);
|
|
}
|
|
|
|
void DrawAllPickups()
|
|
{
|
|
auto* pickup = &Pickups[CurrentPickup];
|
|
|
|
if (pickup->Life > 0)
|
|
{
|
|
if (PickupX > 0)
|
|
PickupX += -PickupX >> 3;
|
|
else
|
|
pickup->Life--;
|
|
}
|
|
else if (pickup->Life == 0)
|
|
{
|
|
if (PickupX < 128)
|
|
{
|
|
if (PickupVel < 16)
|
|
PickupVel++;
|
|
|
|
PickupX += PickupVel;
|
|
}
|
|
else
|
|
{
|
|
pickup->Life = -1;
|
|
PickupVel = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
for (i = 0; i < MAX_COLLECTED_PICKUPS; i++)
|
|
{
|
|
if (Pickups[CurrentPickup].Life > 0)
|
|
break;
|
|
|
|
CurrentPickup++;
|
|
CurrentPickup &= (MAX_COLLECTED_PICKUPS - 1);
|
|
}
|
|
|
|
if (i == MAX_COLLECTED_PICKUPS)
|
|
{
|
|
CurrentPickup = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
g_Renderer.drawPickup(Pickups[CurrentPickup].ObjectNumber);
|
|
}
|
|
|
|
|
|
void AddDisplayPickup(GAME_OBJECT_ID objectNumber)
|
|
{
|
|
auto* pickup = Pickups;
|
|
|
|
for (int i = 0; i < MAX_COLLECTED_PICKUPS; i++)
|
|
{
|
|
if (pickup->Life < 0)
|
|
{
|
|
pickup->Life = 45;
|
|
pickup->ObjectNumber = objectNumber;
|
|
break;
|
|
}
|
|
|
|
pickup++;
|
|
}
|
|
|
|
// No free slot found; pickup the object without displaying it.
|
|
PickedUpObject(objectNumber, 0);
|
|
}
|
|
|
|
void InitialisePickupDisplay()
|
|
{
|
|
for (int i = 0; i < MAX_COLLECTED_PICKUPS; i++)
|
|
Pickups[i].Life = -1;
|
|
|
|
PickupX = 128;
|
|
PickupY = 128;
|
|
PickupVel = 0;
|
|
CurrentPickup = 0;
|
|
}
|
|
|
|
int FlashIt()
|
|
{
|
|
if (FlashCount)
|
|
FlashCount--;
|
|
else
|
|
{
|
|
FlashState ^= 1;
|
|
FlashCount = 5;
|
|
}
|
|
|
|
return FlashState;
|
|
}
|