Juice: pitch variation, squash, dust, trails, jiggle, breathing, hit-stop, numbers, stage-up, digest and rare flair

This commit is contained in:
shweet committed 2026-11-13 00:45:55 -05:00
1 parent 7e27ffad94
commit fdfea89373
11 files changed
+363 -21

No files matched your search

+66 -2
View File
@@ -25,6 +25,14 @@ constexpr float INDICATOR_SIZE = 0.35f;
constexpr float INDICATOR_SPEED = 2;
constexpr float ITEM_SIZE = 96;
constexpr float ROUNDING = 10;
constexpr ImVec4 CALORIES_COLOR = {1, 0.85f, 0.3f, 1};
constexpr float BAR_EASE = 6;
constexpr float BAR_SHAKE = 2;
constexpr float BAR_SHAKE_SPEED = 40;
constexpr float FLOATER_OUTLINE = 2;
constexpr float OVERSTUFFED_PULSE = 0.35f;
constexpr float OVERSTUFFED_SPEED = 6;
constexpr float STAR_WAIST = 0.3f;
constexpr float BAR_WIDTH_MIN = 120;
constexpr float BUTTON_SIZE_MAX = 96;
constexpr float BUTTON_SIZE_MIN = 56;
@@ -558,9 +566,16 @@ void Ui::taskbar_draw(Play& play, ImVec2 screen)
ImGui::AlignTextToFramePadding();
ImGui::TextUnformatted(labels[i]);
ImGui::SameLine();
float time = (float)ImGui::GetTime();
barFills[i] += (fills[i] - barFills[i]) * std::min(1.0f, BAR_EASE * ImGui::GetIO().DeltaTime);
if (i == 1 && overstuffed > 0)
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(1, 1 - overstuffed, 1 - overstuffed, 1));
ImGui::ProgressBar(fills[i], {widths[i], 0}, bars[i].c_str());
{
float red = 1 - overstuffed * (1 - OVERSTUFFED_PULSE * (1 + std::sin(time * OVERSTUFFED_SPEED)) / 2);
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(1, red, red, 1));
ImVec2 cursor = ImGui::GetCursorScreenPos();
ImGui::SetCursorScreenPos({cursor.x + std::sin(time * BAR_SHAKE_SPEED) * BAR_SHAKE * overstuffed, cursor.y});
}
ImGui::ProgressBar(barFills[i], {widths[i], 0}, bars[i].c_str());
if (i == 1 && overstuffed > 0)
ImGui::PopStyleColor();
if (i == 0 && ImGui::BeginItemTooltip())
@@ -709,6 +724,54 @@ void Ui::text_draw(Play& play, ImVec2 screen)
ImGui::PopFont();
}
// The flourishes over the world: sparks, rising numbers (outlined so they read on anything), and the screen's flash.
void Ui::effects_draw(Play& play, ImVec2 screen)
{
Effects& effects = play.effects;
Affine view = play.camera.view_get({screen.x, screen.y});
ImDrawList* drawList = ImGui::GetBackgroundDrawList();
for (Spark& spark : effects.sparks)
{
Vec2 at = view * spark.position;
float fade = (float)spark.life / std::max(1, spark.lifeMax);
float size = spark.size * view.a * fade;
ImU32 color = ImGui::GetColorU32(ImVec4(spark.color.r, spark.color.g, spark.color.b, spark.color.a * fade));
if (spark.shape == SPARK_CIRCLE)
{
drawList->AddCircleFilled({at.x, at.y}, size, color);
continue;
}
float waist = size * STAR_WAIST;
drawList->AddQuadFilled({at.x, at.y - size}, {at.x + waist, at.y}, {at.x, at.y + size}, {at.x - waist, at.y},
color);
drawList->AddQuadFilled({at.x - size, at.y}, {at.x, at.y - waist}, {at.x + size, at.y}, {at.x, at.y + waist},
color);
}
ImFont* font = ImGui::GetFont();
for (Floater& floater : effects.floaters)
{
std::string text = floater.type == FLOATER_CALORIES ? text_format("+%.0f kcal", floater.value)
: "+" + weight_format(floater.value, *measurement);
float alpha = std::min(1.0f, (float)floater.life / (FLOATER_LIFE / 2));
ImVec4 color = floater.type == FLOATER_CALORIES ? CALORIES_COLOR : ImGui::GetStyleColorVec4(ImGuiCol_PlotHistogram);
color.w = alpha;
ImVec2 size = font->CalcTextSizeA(FONT_HEADER_2, FLT_MAX, 0, text.c_str());
Vec2 at = view * floater.position;
ImVec2 position = {at.x - size.x / 2, at.y - size.y / 2};
ImU32 outline = ImGui::GetColorU32(ImVec4(0, 0, 0, alpha));
for (int x = -1; x <= 1; x++)
for (int y = -1; y <= 1; y++)
if (x != 0 || y != 0)
drawList->AddText(font, FONT_HEADER_2,
{position.x + x * FLOATER_OUTLINE, position.y + y * FLOATER_OUTLINE}, outline,
text.c_str());
drawList->AddText(font, FONT_HEADER_2, position, ImGui::GetColorU32(color), text.c_str());
}
if (effects.flash > 0)
drawList->AddRectFilled({0, 0}, screen, ImGui::GetColorU32(ImVec4(1, 1, 1, effects.flash)));
}
// Fading messages stacked down from the top right, newest first.
void Ui::toasts_draw(Play& play)
{
@@ -994,6 +1057,7 @@ void Ui::play_update(Play& play, Settings& settings)
character = play.character;
measurement = &settings.measurement;
ImVec2 screen = ImGui::GetIO().DisplaySize;
effects_draw(play, screen);
if (play.items.tooltip >= 0 && !play.isBlocked && ImGui::BeginTooltip())
{
item_details_draw(*character, &character->catalog.items[play.items.tooltip]);