This commit is contained in:
2026-11-08 07:45:01 -05:00
commit 36e093f84c
1109 changed files with 254529 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
#include "StatBar.h"
#include <algorithm>
#include <cmath>
#include "Gui.h"
static constexpr float BAR_BORDER = 3.0f;
static constexpr float LABEL_HEIGHT = 26.0f;
static constexpr float LABEL_GAP = 2.0f;
static constexpr float TRAIL_DELAY = 0.45f; // seconds the lost amount lingers before draining
static constexpr float TRAIL_DRAIN_SPEED = 0.6f; // of the whole bar a second
static constexpr float FLASH_TIME = 0.35f;
static const glm::vec3 BACKGROUND_COLOR(0.03f, 0.04f, 0.06f);
static const glm::vec3 HURT_BACKGROUND_COLOR(0.45f, 0.06f, 0.05f);
static const glm::vec3 TRAIL_COLOR(0.98f, 0.92f, 0.80f);
static const glm::vec3 DIMMED_COLOR(0.38f, 0.40f, 0.44f);
static const glm::vec3 TEXT_COLOR(0.95f, 0.97f, 1.0f);
// Drawn from images: the empty part is the fill image darkened, the lost part the fill image brightened
static const glm::vec3 IMAGE_EMPTY_TINT(0.16f, 0.13f, 0.13f);
static const glm::vec3 IMAGE_HURT_TINT(0.55f, 0.18f, 0.16f);
static const glm::vec3 IMAGE_TRAIL_TINT(2.2f, 1.9f, 1.7f);
static ImageBox* MakeImage(Texture* texture) {
ImageBox* image = new ImageBox();
image->surface = SurfaceTexture::Stretched(texture);
image->Opacity = 0.0f;
image->BindToRenderSystem();
return image;
}
static Box* MakeBox(const glm::vec3& color) {
Box* box = new Box();
box->Color = color;
box->Opacity = 0.0f;
box->BindToRenderSystem();
return box;
}
StatBar::StatBar(Font* font, const Style& newStyle) : style(newStyle) {
if (Images()) {
background = MakeImage(style.fillImage);
trail = MakeImage(style.fillImage);
fill = MakeImage(style.fillImage);
if (style.frameImage)
frame = MakeImage(style.frameImage);
}
else {
background = MakeBox(BACKGROUND_COLOR);
background->rounding = 0.5f;
trail = MakeBox(TRAIL_COLOR);
fill = MakeBox(style.fillColor);
}
label = new TextBox();
label->font = font;
label->fontsize = style.labelSize;
label->Color = TEXT_COLOR;
label->Opacity = 0.0f;
label->textCenter = { 0.0f, 1.0f };
label->BindToRenderSystem();
}
float StatBar::GetHeight() const {
return LABEL_HEIGHT + LABEL_GAP + style.height;
}
void StatBar::Update(float dt, float opacity, float target, const std::string& text, const glm::vec2& position,
bool reset, bool dimmed) {
target = glm::clamp(target, 0.0f, 1.0f);
if (reset) {
fraction = trailFraction = target;
flash = 0.0f;
trailWait = 0.0f;
}
if (style.showLoss && target < fraction - 0.0001f) {
flash = 1.0f;
trailWait = TRAIL_DELAY;
}
fraction = target;
if (style.showLoss) {
trailWait -= dt;
if (trailWait <= 0.0f)
trailFraction = std::max(trailFraction - TRAIL_DRAIN_SPEED * dt, fraction);
trailFraction = std::max(trailFraction, fraction); // filling back up doesn't leave a trail
}
else {
trailFraction = fraction;
}
flash = std::max(flash - dt / FLASH_TIME, 0.0f);
dim += ((dimmed ? 1.0f : 0.0f) - dim) * (1.0f - std::exp(-10.0f * dt));
const glm::vec2 barTopLeft = glm::round(position + glm::vec2(0.0f, LABEL_HEIGHT + LABEL_GAP));
label->text = text;
label->t2d.position = { 0.0f, 0.0f, std::round(position.x + 2.0f), std::round(position.y) };
label->t2d.size = { 0.0f, 0.0f, style.width, LABEL_HEIGHT };
label->Opacity = text.empty() ? 0.0f : opacity;
// The fill color all the way down to lowFraction, then turning to lowColor
const float low = 1.0f - glm::clamp(fraction / std::max(style.lowFraction, 0.0001f), 0.0f, 1.0f);
glm::vec3 color = glm::mix(style.fillColor, style.lowColor, low);
color = glm::mix(color, DIMMED_COLOR, dim);
color = glm::mix(color, glm::vec3(1.0f), flash * 0.5f);
if (Images()) {
// Every layer covers the whole bar, the trail and fill cropped from the left to how much they show
auto Place = [&](Box* box, float shown) {
box->t2d.position = { 0.0f, 0.0f, barTopLeft.x, barTopLeft.y };
box->t2d.size = { 0.0f, 0.0f, std::round(style.width * shown), style.height };
static_cast<ImageBox*>(box)->crop = glm::vec2(shown, 1.0f);
};
Place(background, 1.0f);
background->Color = glm::mix(IMAGE_EMPTY_TINT, IMAGE_HURT_TINT, flash);
background->Opacity = opacity * 0.9f;
Place(trail, trailFraction);
trail->Color = IMAGE_TRAIL_TINT;
trail->Opacity = trailFraction > fraction ? opacity : 0.0f;
Place(fill, fraction);
fill->Color = color;
fill->Opacity = fraction > 0.0f ? opacity : 0.0f;
if (frame) {
Place(frame, 1.0f);
frame->Opacity = opacity;
}
return;
}
const float inner = style.width - BAR_BORDER * 2.0f;
const float innerHeight = style.height - BAR_BORDER * 2.0f;
background->t2d.position = { 0.0f, 0.0f, barTopLeft.x, barTopLeft.y };
background->t2d.size = { 0.0f, 0.0f, style.width, style.height };
background->Color = glm::mix(BACKGROUND_COLOR, HURT_BACKGROUND_COLOR, flash);
background->Opacity = opacity * 0.8f;
trail->t2d.position = { 0.0f, 0.0f, barTopLeft.x + BAR_BORDER, barTopLeft.y + BAR_BORDER };
trail->t2d.size = { 0.0f, 0.0f, std::round(inner * trailFraction), innerHeight };
trail->Opacity = opacity * 0.85f;
fill->t2d.position = { 0.0f, 0.0f, barTopLeft.x + BAR_BORDER, barTopLeft.y + BAR_BORDER };
fill->t2d.size = { 0.0f, 0.0f, std::round(inner * fraction), innerHeight };
fill->Color = color;
fill->Opacity = opacity;
}