Wider taskbar scaled to window, bigger fonts and a cheats button

This commit is contained in:
shweet committed 2026-11-12 23:26:25 -05:00
1 parent 37e87f168a
commit eb03fc9d1d
5 files changed
+56 -41

No files matched your search

+1 -1
View File
@@ -32,7 +32,7 @@ There's two folders inside resources; "characters" and "font".
"font" is just a font containing the font used in the selection screen. That's literally it. "font" is just a font containing the font used in the selection screen. That's literally it.
"common" holds files characters share (sounds, particles, the cursor and so on). Whenever a character names a file, the game looks in the character's folder first, then in "common", so a character can use anything there as is, or replace it by having its own file at the same path. This includes the taskbar's icons, `gfx/ui/icons.anm2`: one region per icon, named after its button (`talk`, `mood`, `spawn`, `autofeed`, `home`, `stats`, `catalog`, `settings`, `help`, plus whatever `icon`s the interaction types name). A character with its own `gfx/ui/icons.anm2` gets its own icons. "common" holds files characters share (sounds, particles, the cursor and so on). Whenever a character names a file, the game looks in the character's folder first, then in "common", so a character can use anything there as is, or replace it by having its own file at the same path. This includes the taskbar's icons, `gfx/ui/icons.anm2`: one region per icon, named after its button (`talk`, `mood`, `spawn`, `autofeed`, `home`, `stats`, `catalog`, `settings`, `cheats`, `help`, plus whatever `icon`s the interaction types name). A character with its own `gfx/ui/icons.anm2` gets its own icons.
EVERYTHING ELSE is stored inside character folders in the "characters" folder; one folder per character, named however you like (the folder name is also the name of its save file). This has all data associated with characters. Think of characters more as tailored game experiences rather than literally being just the characters. Not only is there the character graphics, but backgrounds, items, parameters, etc. These are intensely customizable to suit whatever experience you'd like (within the confines of the engine, of course). EVERYTHING ELSE is stored inside character folders in the "characters" folder; one folder per character, named however you like (the folder name is also the name of its save file). This has all data associated with characters. Think of characters more as tailored game experiences rather than literally being just the characters. Not only is there the character graphics, but backgrounds, items, parameters, etc. These are intensely customizable to suit whatever experience you'd like (within the confines of the engine, of course).
+15 -14
View File
@@ -4,20 +4,21 @@
{ {
"path": "icons.png", "path": "icons.png",
"regions": [ "regions": [
{"name": "talk", "crop": [0, 0], "size": [48, 48], "origin": "center"}, {"name": "talk", "crop": [0, 0], "size": [64, 64], "origin": "center"},
{"name": "mood", "crop": [49, 0], "size": [48, 48], "origin": "center"}, {"name": "mood", "crop": [65, 0], "size": [64, 64], "origin": "center"},
{"name": "spawn", "crop": [98, 0], "size": [48, 48], "origin": "center"}, {"name": "spawn", "crop": [130, 0], "size": [64, 64], "origin": "center"},
{"name": "autofeed", "crop": [147, 0], "size": [48, 48], "origin": "center"}, {"name": "autofeed", "crop": [195, 0], "size": [64, 64], "origin": "center"},
{"name": "home", "crop": [196, 0], "size": [48, 48], "origin": "center"}, {"name": "home", "crop": [260, 0], "size": [64, 64], "origin": "center"},
{"name": "rub", "crop": [245, 0], "size": [48, 48], "origin": "center"}, {"name": "rub", "crop": [325, 0], "size": [64, 64], "origin": "center"},
{"name": "smack", "crop": [294, 0], "size": [48, 48], "origin": "center"}, {"name": "smack", "crop": [390, 0], "size": [64, 64], "origin": "center"},
{"name": "kiss", "crop": [343, 0], "size": [48, 48], "origin": "center"}, {"name": "kiss", "crop": [455, 0], "size": [64, 64], "origin": "center"},
{"name": "turn", "crop": [0, 49], "size": [48, 48], "origin": "center"}, {"name": "turn", "crop": [0, 65], "size": [64, 64], "origin": "center"},
{"name": "stats", "crop": [49, 49], "size": [48, 48], "origin": "center"}, {"name": "stats", "crop": [65, 65], "size": [64, 64], "origin": "center"},
{"name": "catalog", "crop": [98, 49], "size": [48, 48], "origin": "center"}, {"name": "catalog", "crop": [130, 65], "size": [64, 64], "origin": "center"},
{"name": "settings", "crop": [147, 49], "size": [48, 48], "origin": "center"}, {"name": "settings", "crop": [195, 65], "size": [64, 64], "origin": "center"},
{"name": "help", "crop": [196, 49], "size": [48, 48], "origin": "center"}, {"name": "help", "crop": [260, 65], "size": [64, 64], "origin": "center"},
{"name": "close", "crop": [245, 49], "size": [48, 48], "origin": "center"} {"name": "close", "crop": [325, 65], "size": [64, 64], "origin": "center"},
{"name": "cheats", "crop": [390, 65], "size": [64, 64], "origin": "center"}
] ]
} }
], ],
Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 14 KiB

+32 -21
View File
@@ -25,23 +25,25 @@ constexpr float INDICATOR_SIZE = 0.35f;
constexpr float INDICATOR_SPEED = 2; constexpr float INDICATOR_SPEED = 2;
constexpr float ITEM_SIZE = 96; constexpr float ITEM_SIZE = 96;
constexpr float BAR_WIDTH_MIN = 120; constexpr float BAR_WIDTH_MIN = 120;
constexpr float BUTTON_SIZE = 64; constexpr float BUTTON_SIZE_MAX = 96;
constexpr float BUTTON_SIZE_MIN = 56;
constexpr float CATALOG_DIVIDER = 2; constexpr float CATALOG_DIVIDER = 2;
constexpr float CATALOG_GRID = 0.55f; constexpr float CATALOG_GRID = 0.55f;
constexpr float COOLDOWN_ALPHA = 0.6f; constexpr float COOLDOWN_ALPHA = 0.6f;
constexpr float COOLDOWN_RADIUS = 0.42f; constexpr float COOLDOWN_RADIUS = 0.42f;
constexpr float ICON_SIZE = 48; constexpr float ICON_FRACTION = 0.7f;
constexpr float TOGGLE_FADE_FAR = 220; constexpr float TOGGLE_FADE_FAR = 220;
constexpr float TOGGLE_FADE_NEAR = 60; constexpr float TOGGLE_FADE_NEAR = 60;
constexpr float TOGGLE_HEIGHT = 28; constexpr float TOGGLE_HEIGHT = 28;
constexpr float WINDOW_FIT = 0.9f; constexpr float WINDOW_FIT = 0.9f;
constexpr float WINDOW_HEIGHT = 680; constexpr float WINDOW_HEIGHT = 680;
constexpr float WINDOW_WIDTH = 1000; constexpr float WINDOW_WIDTH = 1000;
constexpr float TASKBAR_FIT = 0.8f;
constexpr int BUTTONS_FIXED = 9; constexpr int BUTTONS_FIXED = 9;
constexpr float INFO_GAP = 4; constexpr float INFO_GAP = 4;
constexpr int COOLDOWN_SEGMENTS = 48; constexpr int COOLDOWN_SEGMENTS = 48;
constexpr const char* PANEL_ICONS[] = {"", "stats", "catalog", "settings"}; constexpr const char* PANEL_ICONS[] = {"", "stats", "catalog", "settings", "cheats"};
constexpr const char* PANEL_NAMES[] = {"", "Stats", "Catalog", "Settings"}; constexpr const char* PANEL_NAMES[] = {"", "Stats", "Catalog", "Settings", "Cheats"};
constexpr float KG_TO_G = 1000; constexpr float KG_TO_G = 1000;
constexpr float KG_TO_LB = 2.20462f; constexpr float KG_TO_LB = 2.20462f;
constexpr float LB_TO_OZ = 16; constexpr float LB_TO_OZ = 16;
@@ -56,7 +58,7 @@ constexpr float SLIDE_TIME = 0.125f;
constexpr float TEXT_BIG = 1.25f; constexpr float TEXT_BIG = 1.25f;
constexpr float TEXT_HEIGHT_LINES = 5; constexpr float TEXT_HEIGHT_LINES = 5;
constexpr float TEXT_SMALL = 0.75f; constexpr float TEXT_SMALL = 0.75f;
constexpr float TEXT_WIDTH = 0.4f; constexpr float TEXT_WIDTH = 0.5f;
constexpr float TOOLTIP_WRAP = 24; constexpr float TOOLTIP_WRAP = 24;
constexpr float TRIANGLE_SIZE = 0.22f; constexpr float TRIANGLE_SIZE = 0.22f;
constexpr float UNDISCOVERED_ALPHA = 0.5f; constexpr float UNDISCOVERED_ALPHA = 0.5f;
@@ -412,10 +414,10 @@ bool Ui::icon_button(const char* icon, const char* tooltip, ButtonState state)
if (state == BUTTON_ACTIVE) if (state == BUTTON_ACTIVE)
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered)); ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered));
ImGui::BeginDisabled(state == BUTTON_DISABLED); ImGui::BeginDisabled(state == BUTTON_DISABLED);
bool isPressed = is_fx(ImGui::Button("##Icon", {BUTTON_SIZE, BUTTON_SIZE})); bool isPressed = is_fx(ImGui::Button("##Icon", {buttonSize, buttonSize}));
ImVec2 min = ImGui::GetItemRectMin(); ImVec2 min = ImGui::GetItemRectMin();
float inset = (BUTTON_SIZE - ICON_SIZE) / 2; float inset = buttonSize * (1 - ICON_FRACTION) / 2;
icon_draw(icon, {min.x + inset, min.y + inset}, ICON_SIZE, ImGui::GetColorU32(ImGuiCol_Text)); icon_draw(icon, {min.x + inset, min.y + inset}, buttonSize * ICON_FRACTION, ImGui::GetColorU32(ImGuiCol_Text));
ImGui::EndDisabled(); ImGui::EndDisabled();
if (state == BUTTON_ACTIVE) if (state == BUTTON_ACTIVE)
ImGui::PopStyleColor(); ImGui::PopStyleColor();
@@ -485,12 +487,15 @@ void Ui::taskbar_draw(Play& play, ImVec2 screen)
widths[i] = std::max(BAR_WIDTH_MIN, ImGui::CalcTextSize(bars[i].c_str()).x + style.FramePadding.x * 4); widths[i] = std::max(BAR_WIDTH_MIN, ImGui::CalcTextSize(bars[i].c_str()).x + style.FramePadding.x * 4);
used += ImGui::CalcTextSize(labels[i]).x + style.ItemSpacing.x + widths[i]; used += ImGui::CalcTextSize(labels[i]).x + style.ItemSpacing.x + widths[i];
} }
int count = BUTTONS_FIXED + (int)data.interactTypes.size(); int count = BUTTONS_FIXED + (int)data.interactTypes.size() + play.isCheats;
float spacing = (count - 1) * style.ItemSpacing.x;
buttonSize = std::clamp((screen.x * TASKBAR_FIT - style.WindowPadding.x * 2 - spacing) / count, BUTTON_SIZE_MIN,
BUTTON_SIZE_MAX);
float nameWidth = ImGui::CalcTextSize(data.name.c_str()).x; float nameWidth = ImGui::CalcTextSize(data.name.c_str()).x;
float rowWidth = count * BUTTON_SIZE + (count - 1) * style.ItemSpacing.x; float rowWidth = count * buttonSize + spacing;
float infoWidth = nameWidth + used + style.ItemSpacing.x * INFO_GAP * std::size(labels); float infoWidth = nameWidth + used + style.ItemSpacing.x * INFO_GAP * std::size(labels);
float width = std::max(rowWidth, infoWidth) + style.WindowPadding.x * 2; float width = std::max(rowWidth, infoWidth) + style.WindowPadding.x * 2;
float height = style.WindowPadding.y * 2 + ImGui::GetFrameHeight() + style.ItemSpacing.y * 2 + BUTTON_SIZE; float height = style.WindowPadding.y * 2 + ImGui::GetFrameHeight() + style.ItemSpacing.y * 2 + buttonSize;
slide_update(taskbarSlide, play.isTaskbarOpen && !play.text.isScene); slide_update(taskbarSlide, play.isTaskbarOpen && !play.text.isScene);
float shown = std::pow(taskbarSlide, SLIDE_EASE) * height; float shown = std::pow(taskbarSlide, SLIDE_EASE) * height;
float x = (screen.x - width) / 2; float x = (screen.x - width) / 2;
@@ -539,14 +544,14 @@ void Ui::taskbar_draw(Play& play, ImVec2 screen)
(ImGui::GetContentRegionAvail().x - nameWidth - used) / std::size(labels)); (ImGui::GetContentRegionAvail().x - nameWidth - used) / std::size(labels));
for (int i = 0; i < (int)std::size(labels); i++) for (int i = 0; i < (int)std::size(labels); i++)
{ {
ImGui::SameLine(0, gap / 2); ImGui::SameLine(0, gap);
if (i > 0) if (i > 0)
{ {
ImVec2 cursor = ImGui::GetCursorScreenPos(); ImVec2 cursor = ImGui::GetCursorScreenPos();
cursor.x -= gap / 2;
ImGui::GetWindowDrawList()->AddLine(cursor, {cursor.x, cursor.y + ImGui::GetFrameHeight()}, ImGui::GetWindowDrawList()->AddLine(cursor, {cursor.x, cursor.y + ImGui::GetFrameHeight()},
ImGui::GetColorU32(ImGuiCol_Separator)); ImGui::GetColorU32(ImGuiCol_Separator));
} }
ImGui::SameLine(0, gap / 2);
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
ImGui::TextUnformatted(labels[i]); ImGui::TextUnformatted(labels[i]);
ImGui::SameLine(); ImGui::SameLine();
@@ -607,9 +612,11 @@ void Ui::taskbar_draw(Play& play, ImVec2 screen)
play.cursorType = i; play.cursorType = i;
ImGui::PopID(); ImGui::PopID();
} }
Panel panels[] = {PANEL_STATS, PANEL_CATALOG, PANEL_SETTINGS}; Panel panels[] = {PANEL_STATS, PANEL_CATALOG, PANEL_SETTINGS, PANEL_CHEATS};
for (Panel each : panels) for (Panel each : panels)
{ {
if (each == PANEL_CHEATS && !play.isCheats)
continue;
ImGui::SameLine(); ImGui::SameLine();
if (icon_button(PANEL_ICONS[each], PANEL_NAMES[each], BUTTON_NORMAL)) if (icon_button(PANEL_ICONS[each], PANEL_NAMES[each], BUTTON_NORMAL))
window_open(play, each); window_open(play, each);
@@ -781,13 +788,12 @@ void Ui::settings_draw(Settings& settings)
ImGui::SetItemTooltip("Go back to the character selection screen.\nProgress will be saved."); ImGui::SetItemTooltip("Go back to the character selection screen.\nProgress will be saved.");
} }
// The body in full (weight and stage, calories and digestion, totals), and the cheats when unlocked. // The body in full: weight and stage, calories and digestion, and totals.
void Ui::stats_draw(Play& play) void Ui::stats_draw(Play& play)
{ {
Character& data = *play.character; Character& data = *play.character;
Body& body = play.body; Body& body = play.body;
Stats& stats = body.stats; Stats& stats = body.stats;
Traits& traits = data.traits;
bool isMax = body.stage >= (int)data.stages.size(); bool isMax = body.stage >= (int)data.stages.size();
ImGui::PushFont(nullptr, FONT_HEADER_2); ImGui::PushFont(nullptr, FONT_HEADER_2);
@@ -819,12 +825,15 @@ void Ui::stats_draw(Play& play)
ImGui::Text("Total Items Spawned: %i", stats.totalSpawned); ImGui::Text("Total Items Spawned: %i", stats.totalSpawned);
ImGui::Text("Total Items Consumed: %i", stats.totalConsumed); ImGui::Text("Total Items Consumed: %i", stats.totalConsumed);
ImGui::Text("Total Playtime: %s", playtime_format(stats.playtime).c_str()); ImGui::Text("Total Playtime: %s", playtime_format(stats.playtime).c_str());
if (!play.isCheats) }
return;
ImGui::PushFont(nullptr, FONT_HEADER_2); // Sliders setting the body's stats directly, unlocked by the cheat code.
ImGui::SeparatorText("Cheats"); void Ui::cheats_draw(Play& play)
ImGui::PopFont(); {
Character& data = *play.character;
Body& body = play.body;
Stats& stats = body.stats;
Traits& traits = data.traits;
is_fx(ImGui::SliderFloat("Calories", &stats.calories, 0, body.capacity_max_get(), "%0.0f kcal")); is_fx(ImGui::SliderFloat("Calories", &stats.calories, 0, body.capacity_max_get(), "%0.0f kcal"));
is_fx(ImGui::SliderFloat("Capacity", &stats.capacity, traits.capacityMin, traits.capacityMax, "%0.0f kcal")); is_fx(ImGui::SliderFloat("Capacity", &stats.capacity, traits.capacityMin, traits.capacityMax, "%0.0f kcal"));
if (is_fx(ImGui::SliderFloat("Weight", &stats.weight, traits.weight, traits.weightMax, "%0.2f kg"))) if (is_fx(ImGui::SliderFloat("Weight", &stats.weight, traits.weight, traits.weightMax, "%0.2f kg")))
@@ -960,6 +969,8 @@ void Ui::window_draw(Play& play, Settings& settings, ImVec2 screen)
stats_draw(play); stats_draw(play);
else if (panel == PANEL_CATALOG) else if (panel == PANEL_CATALOG)
catalog_draw(play); catalog_draw(play);
else if (panel == PANEL_CHEATS)
cheats_draw(play);
else else
settings_draw(settings); settings_draw(settings);
if (ImGui::IsKeyPressed(ImGuiKey_Escape)) if (ImGui::IsKeyPressed(ImGuiKey_Escape))
+8 -5
View File
@@ -4,10 +4,10 @@
#include "save.h" #include "save.h"
#include <imgui.h> #include <imgui.h>
constexpr float FONT_NORMAL = 26; constexpr float FONT_NORMAL = 30;
constexpr float FONT_HEADER_3 = 30; constexpr float FONT_HEADER_3 = 34;
constexpr float FONT_HEADER_2 = 34; constexpr float FONT_HEADER_2 = 40;
constexpr float FONT_DIALOGUE = 32; constexpr float FONT_DIALOGUE = 38;
class Play; class Play;
@@ -22,7 +22,8 @@ enum Panel
PANEL_NONE, PANEL_NONE,
PANEL_STATS, PANEL_STATS,
PANEL_CATALOG, PANEL_CATALOG,
PANEL_SETTINGS PANEL_SETTINGS,
PANEL_CHEATS
}; };
enum ButtonState enum ButtonState
@@ -68,6 +69,7 @@ public:
Commands* commands = nullptr; Commands* commands = nullptr;
Measurement* measurement = nullptr; Measurement* measurement = nullptr;
Renderer* renderer = nullptr; Renderer* renderer = nullptr;
float buttonSize = 0;
float taskbarSlide = 1; float taskbarSlide = 1;
int characterIndex = 0; int characterIndex = 0;
int selectedIndex = -1; int selectedIndex = -1;
@@ -89,6 +91,7 @@ private:
void taskbar_draw(Play& play, ImVec2 screen); void taskbar_draw(Play& play, ImVec2 screen);
void window_draw(Play& play, Settings& settings, ImVec2 screen); void window_draw(Play& play, Settings& settings, ImVec2 screen);
void stats_draw(Play& play); void stats_draw(Play& play);
void cheats_draw(Play& play);
void catalog_draw(Play& play); void catalog_draw(Play& play);
void settings_draw(Settings& settings); void settings_draw(Settings& settings);
void text_draw(Play& play, ImVec2 screen); void text_draw(Play& play, ImVec2 screen);