Compare commits

...

14 Commits

Author SHA1 Message Date
Shweet
1f1ac0db4d Merge pull request #4 from MarkSuckerberg/build-because-why-not
Some checks failed
Build / Build Game (push) Has been cancelled
Build CI
2025-12-30 23:15:10 -08:00
Mark Suckerberg
c2f0188174 Upload the artifact because sure 2025-12-30 19:22:46 -06:00
Shweet
b76604bacf Merge pull request #3 from MarkSuckerberg/play-feedback
Game Bar Highlight
2025-12-30 16:48:40 -08:00
Shweet
85663e3c9c Merge pull request #2 from MarkSuckerberg/inventory-adjustment
Inventory Display Tweak
2025-12-30 16:47:51 -08:00
Shweet
a81a549fa1 Merge pull request #1 from MarkSuckerberg/volume
Volume setting
2025-12-30 16:47:40 -08:00
Mark Suckerberg
1745899487 Just removes the windows build 2025-12-30 18:44:30 -06:00
Mark Suckerberg
d028224fd0 Ease the outline colour when clicked 2025-12-30 18:15:00 -06:00
Mark Suckerberg
0f4ba92de5 Adjusts to also hide impossible item silhouettes 2025-12-30 17:53:57 -06:00
Mark Suckerberg
2d2faebd10 tweaks inventory screen display 2025-12-30 17:44:12 -06:00
Mark Suckerberg
aa70543411 Tiny adjustment to make the play bar highlight on mouse hover 2025-12-30 15:20:00 -06:00
Mark Suckerberg
228c87d0ee forgot the flag I meant to add + fixes msbuild 2025-12-30 14:47:52 -06:00
Mark Suckerberg
20bc2837e6 ah well 2025-12-30 14:37:26 -06:00
Mark Suckerberg
1b67f1c14b Add a build action because there's no reason not to at least test that 2025-12-30 14:28:51 -06:00
Mark Suckerberg
c30a9e3520 Volume setting 2025-12-30 13:15:50 -06:00
11 changed files with 208 additions and 63 deletions

41
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Build
on:
push:
branches:
- master
pull_request:
workflow_dispatch:
jobs:
build:
name: Build Game
runs-on: ubuntu-latest
steps:
- name: Checkout Project
uses: actions/checkout@v6
with:
submodules: "recursive"
- name: "Install dependencies"
run: |
sudo apt-get update -y
sudo apt-get install -y \
gnome-desktop-testing libasound2-dev libpulse-dev libaudio-dev libjack-dev libsndio-dev \
libusb-1.0-0-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev \
libxss-dev libxtst-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev \
libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev
- name: CMake Build
run: |
mkdir build
cmake -S . -B ./build -DSDL_UNIX_CONSOLE_BUILD=ON
make -C build
- name: Upload Artifact
uses: actions/upload-artifact@v6
with:
name: linux-build
path: build/snivy

View File

@@ -8,5 +8,6 @@ namespace game
{
public:
MeasurementSystem measurementSystem{MeasurementSystem::METRIC};
int volume{100};
};
}

View File

@@ -12,6 +12,12 @@ namespace game::resource
return mixer;
}
void Audio::set_gain(float gain)
{
auto mixer = mixer_get();
MIX_SetMasterGain(mixer, gain);
}
void Audio::retain()
{
if (refCount) ++(*refCount);

View File

@@ -10,7 +10,7 @@ namespace game::resource
MIX_Audio* internal{nullptr};
MIX_Track* track{nullptr};
int* refCount{nullptr};
MIX_Mixer* mixer_get();
static MIX_Mixer* mixer_get();
void unload();
void retain();
void release();
@@ -27,5 +27,6 @@ namespace game::resource
void play(bool isLoop = false);
void stop();
bool is_playing() const;
static void set_gain(float vol);
};
}

View File

@@ -21,4 +21,8 @@ namespace game
}
void Resources::sound_play(audio::Type type) { audio[type].play(); }
void Resources::set_audio_gain(float vol) {
Audio::set_gain(vol);
}
}

View File

@@ -124,5 +124,6 @@ namespace game
Resources();
void sound_play(audio::Type);
void set_audio_gain(float vol);
};
}

View File

@@ -123,8 +123,7 @@ namespace game
((Item::SPAWN_Y_MAX - Item::SPAWN_Y_MIN) * math::random()) + Item::SPAWN_Y_MIN);
items.emplace_back(&resources.anm2s[anm2::ITEMS], position, type);
inventory.values[type]--;
if (inventory.values[type] == 0) inventory.values.erase(type);
inventory.adjust_item(type, -1);
type = Item::NONE;
inventory.isQueued = false;
}
@@ -159,7 +158,7 @@ namespace game
{
if (Item::queuedReturnItem->state == Item::DEFAULT)
{
inventory.values[item.type]++;
inventory.adjust_item(item.type);
resources.sound_play(audio::RETURN);
}
else

View File

@@ -9,6 +9,31 @@ using namespace glm;
namespace game::window
{
Inventory::Inventory()
{
count = 0;
for (auto& [type, quantity] : values)
{
count += quantity;
}
}
void Inventory::adjust_item(Item::Type type, int quantity)
{
values[type] += quantity;
count += quantity;
}
void Inventory::set_item(Item::Type type, int value)
{
count -= values[type];
values[type] = value;
count += value;
}
int Inventory::get_item(Item::Type type) { return values.contains(type) ? values[type] : 0; }
void Inventory::update(Resources& resources, Character& character, GameData& gameData)
{
auto& texture = resources.anm2s[anm2::ITEMS].content.spritesheets.at(0).texture;
@@ -18,9 +43,13 @@ namespace game::window
auto cursorPos = ImGui::GetCursorPos();
auto cursorStartX = ImGui::GetCursorPosX();
for (auto& [type, quantity] : values)
for (int index = 0; index < Item::ITEM_COUNT; index++)
{
if (quantity == 0) continue;
auto type = (Item::Type)index;
auto seen = values.contains(type);
//Hide invalid items and impossible-to-obtain items when not seen.
if (!seen && (Item::CATEGORIES[type] == Item::INVALID || Item::RARITIES[type] == Item::IMPOSSIBLE)) continue;
auto columns = (int)(texture.size.x / ITEM_SIZE.x);
auto crop = vec2(type % columns, type / columns) * ITEM_SIZE;
@@ -30,23 +59,24 @@ namespace game::window
ImGui::PushID(type);
ImGui::SetCursorPos(cursorPos);
auto cursorScreenPos = ImGui::GetCursorScreenPos();
auto quantity = 0;
if (seen)
{
quantity = values[type];
ImGui::BeginDisabled(quantity < 1);
if (ImGui::ImageButton("##Image Button", texture.id, IMAGE_SIZE, imgui::to_imvec2(uvMin),
imgui::to_imvec2(uvMax)))
imgui::to_imvec2(uvMax)) &&
quantity > 0)
{
queuedItemType = type;
isQueued = true;
resources.sound_play(audio::SUMMON);
}
auto increment = ImGui::GetItemRectSize().x + ImGui::GetStyle().ItemSpacing.x;
cursorPos.x += increment;
if (cursorPos.x + increment > ImGui::GetContentRegionAvail().x)
{
cursorPos.x = cursorStartX;
cursorPos.y += increment;
}
ImGui::EndDisabled();
if (ImGui::BeginItemTooltip())
{
@@ -77,7 +107,6 @@ namespace game::window
ImGui::PopStyleColor();
ImGui::EndTooltip();
}
ImGui::PopID();
ImGui::PushFont(resources.font.get(), Font::BIG);
auto text = std::format("x{}", quantity);
@@ -87,8 +116,41 @@ namespace game::window
text.c_str());
ImGui::PopFont();
}
else
{
ImGui::BeginDisabled(true);
ImGui::ImageButton("##Image Button", texture.id, IMAGE_SIZE, imgui::to_imvec2(uvMin), imgui::to_imvec2(uvMax),
ImVec4(0, 0, 0, 0), ImVec4(0, 0, 0, 1));
ImGui::EndDisabled();
if (values.empty()) ImGui::Text("Check the \"Play\" tab to earn rewards!");
if (ImGui::BeginItemTooltip())
{
ImGui::TextUnformatted("??? (x0)");
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(imgui::to_imvec4(GRAY)));
ImGui::TextUnformatted("-- ??? (\?\?\?) --");
ImGui::Separator();
ImGui::TextUnformatted("???");
ImGui::PopStyleColor();
ImGui::EndTooltip();
}
}
auto increment = ImGui::GetItemRectSize().x + ImGui::GetStyle().ItemSpacing.x;
cursorPos.x += increment;
if (cursorPos.x + increment > ImGui::GetContentRegionAvail().x)
{
cursorPos.x = cursorStartX;
cursorPos.y += increment;
}
ImGui::PopID();
}
if (count == 0) ImGui::Text("Check the \"Play\" tab to earn rewards!");
ImGui::PopStyleVar();
}

View File

@@ -11,20 +11,26 @@ namespace game::window
{
class Inventory
{
public:
static constexpr auto ITEM_SIZE = glm::vec2(48, 48);
static constexpr auto IMAGE_SIZE = ImVec2(48, 48);
static constexpr auto BUTTON_ROUNDING = 32.0f;
private:
std::map<Item::Type, int> values = {{Item::POKE_PUFF_BASIC_SWEET, 1},
{Item::POKE_PUFF_BASIC_CITRUS, 1},
{Item::POKE_PUFF_BASIC_MINT, 1},
{Item::POKE_PUFF_BASIC_MOCHA, 1},
{Item::POKE_PUFF_BASIC_SPICE, 1}};
public:
static constexpr auto ITEM_SIZE = glm::vec2(48, 48);
static constexpr auto IMAGE_SIZE = ImVec2(48, 48);
static constexpr auto BUTTON_ROUNDING = 32.0f;
int count;
bool isQueued{};
Item::Type queuedItemType{};
Inventory();
void update(Resources&, Character&, GameData&);
void adjust_item(Item::Type, int = 1);
void set_item(Item::Type, int);
int get_item(Item::Type);
};
}

View File

@@ -6,6 +6,7 @@ namespace game::window
ImVec2 pos)
{
MeasurementSystem& measurementSystem = gameData.measurementSystem;
int& volume = gameData.volume;
ImGui::SetNextWindowSize(size);
ImGui::SetNextWindowPos(pos);
@@ -48,6 +49,13 @@ namespace game::window
ImGui::RadioButton("Metric", (int*)&measurementSystem, MeasurementSystem::METRIC);
ImGui::SameLine();
ImGui::RadioButton("Imperial", (int*)&measurementSystem, MeasurementSystem::IMPERIAL);
ImGui::SeparatorText("Sound");
if (ImGui::SliderInt("Volume", (int*)&volume, 0, 100))
{
resources.set_audio_gain((float)volume / 100);
}
ImGui::EndTabItem();
}
@@ -115,9 +123,16 @@ namespace game::window
ImGui::PushItemWidth(100);
for (int i = 0; i < Item::ITEM_COUNT; i++)
{
if (i == Item::INVALID) continue;
if (Item::CATEGORIES[i] == Item::INVALID) continue;
ImGui::PushID(i);
ImGui::DragInt(Item::NAMES[i], &inventory.values[(Item::Type)i], 0.1f, 0, 999);
//TODO: Probably a cleaner way to do this, maybe
int value = inventory.get_item((Item::Type)i);
if (ImGui::DragInt(Item::NAMES[i], &value, 0.1f, 0, 999))
{
inventory.set_item((Item::Type)i, value);
}
ImGui::PopID();
}
ImGui::PopItemWidth();

View File

@@ -85,6 +85,18 @@ namespace game::window
auto barMin = ImVec2(position.x + (size.x * 0.5f) - (spacing * 0.5f), position.y + (spacing * 2.0f));
auto barMax = ImVec2(barMin.x + (spacing * 2.0f), barMin.y + size.y - (spacing * 4.0f));
bool mouseHovering = ImGui::IsMouseHoveringRect(barMin, barMax);
auto endTimerProgress = (float)endTimer / endTimerMax;
if (mouseHovering)
{
auto color = RECT_COLOR;
//Ease out and back in again
color.w = isActive ? 1.0f : (4 * pow(endTimerProgress, 2) - 4 * endTimerProgress + 1);
drawList->AddRect(ImVec2(barMin.x - 1, barMin.y - 1), ImVec2(barMax.x + 1, barMax.y + 1),
ImGui::GetColorU32(color));
}
drawList->AddRectFilled(barMin, barMax, ImGui::GetColorU32(BG_COLOR));
auto barWidth = barMax.x - barMin.x;
@@ -132,8 +144,6 @@ namespace game::window
}
};
auto endTimerProgress = (float)endTimer / endTimerMax;
range_draw(challenge.range, isActive ? 1.0f : 0.0f);
auto lineMin = ImVec2(barMin.x - LINE_WIDTH_BONUS, barMin.y + (barHeight * tryValue));
@@ -171,8 +181,7 @@ namespace game::window
}
}
if (ImGui::IsKeyPressed(ImGuiKey_Space) ||
(ImGui::IsMouseHoveringRect(barMin, barMax) && ImGui::IsMouseClicked(ImGuiMouseButton_Left)))
if (ImGui::IsKeyPressed(ImGuiKey_Space) || (mouseHovering && ImGui::IsMouseClicked(ImGuiMouseButton_Left)))
{
Grade grade{MISS};
auto subRanges = sub_ranges_get(challenge.range);
@@ -203,7 +212,7 @@ namespace game::window
resources.sound_play(audio::HIGH_SCORE_BIG);
isHighScoreBigAchieved = true;
inventory.values[Item::POKE_PUFF_SUPREME_HONOR]++;
inventory.adjust_item(Item::POKE_PUFF_SUPREME_HONOR);
auto toastItemPosition =
ImVec2(math::random_in_range(barMax.x + ITEM_SIZE.x, barMax.x + (size.x * 0.5f) - ITEM_SIZE.x),
@@ -265,7 +274,7 @@ namespace game::window
resources.sound_play(audio::FALL);
resources.sound_play(RARITY_SOUNDS.at(rarity));
inventory.values[rewardType]++;
inventory.adjust_item(rewardType);
auto toastItemPosition =
ImVec2(math::random_in_range(barMax.x + ITEM_SIZE.x, barMax.x + (size.x * 0.5f) - ITEM_SIZE.x),