diff --git a/Makefile b/Makefile index 097aa95..a1533ce 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ tracy_build: meson compile -j 10 -C builddir test: build - ./builddir/runtests "[lel]" + ./builddir/runtests run: build test powershell "cp ./builddir/zedcaster.exe ." diff --git a/assets/config.json b/assets/config.json index af8773d..736c7e0 100644 --- a/assets/config.json +++ b/assets/config.json @@ -26,7 +26,7 @@ "player": { }, "worldgen": { - "enemy_probability": 20, + "enemy_probability": 40, "empty_room_probability": 10, "device_probability": 20 } diff --git a/combat_ui.cpp b/combat_ui.cpp index e9a7ac0..721fd9f 100644 --- a/combat_ui.cpp +++ b/combat_ui.cpp @@ -20,65 +20,45 @@ namespace gui { $background.setFillColor({0, 0, 0}); for(auto& [name, cell] : $layout.cells) { - sf::RectangleShape shape; - shape.setPosition({float(cell.x + 3), float(cell.y + 3)}); - shape.setSize({float(cell.w - 6), float(cell.h - 6)}); - shape.setFillColor(ColorValue::DARK_MID); - shape.setOutlineColor(ColorValue::MID); - shape.setOutlineThickness(1); - - if(name.starts_with("button_")) { - sf::Text label($font, name); - auto bounds = label.getLocalBounds(); - auto label_cell = lel::center(bounds.size.x, bounds.size.y, cell); - // this stupid / 2 is because SFML renders from baseline rather than from the claimed bounding box - label.setPosition({float(label_cell.x), float(label_cell.y) - label_cell.h / 2}); - $labels.push_back(label); - } else if(name == "bar_hp") { - shape.setFillColor({150, 30, 30}); + if(name == "bar_hp") { + $meters.try_emplace(name, cell); } else if(name == "label_hp") { - sf::Text label($font, "hp:"); - label.scale({0.8, 0.8}); - auto bounds = label.getGlobalBounds(); - auto label_cell = lel::center(bounds.size.x, bounds.size.y, cell); - // this stupid / 2 is because SFML renders from baseline rather than from the claimed bounding box - label.setPosition({float(label_cell.x), float(label_cell.y + bounds.size.y)}); - $labels.push_back(label); + gui::Label label(cell, "hp:", $font); + $labels.emplace_back(cell, "hp:", $font); + } else if(name.starts_with("button_")) { + $buttons.try_emplace(name, cell, name, $font); } - - $shapes.insert_or_assign(name, shape); } } void CombatUI::draw(sf::RenderWindow& window) { + window.draw($background); auto &player = $level.world->get_the(); auto &combat = $level.world->get(player.entity); - auto &hp_shape = $shapes.at("bar_hp"); - auto &hp_cell = $layout.cells.at("bar_hp"); - float hp_now = float(combat.hp) / float(combat.max_hp) * float(hp_cell.w); - hp_shape.setSize({std::max(hp_now, 0.0f), float(hp_cell.h - 6)}); + float hp_now = float(combat.hp) / float(combat.max_hp); + auto& bar_hp = $meters.at("bar_hp"); + bar_hp.set_percent(hp_now); - window.draw($background); - - for(auto& [name, shape] : $shapes) { - window.draw(shape); + for(auto& [name, button] : $buttons) { + button.draw(window); } - for(auto& [name, shape] : $label_boxes) { - window.draw(shape); + for(auto& [name, meter] : $meters) { + meter.draw(window); } for(auto& label : $labels) { - window.draw(label); + label.draw(window); } + } void CombatUI::click(int x, int y) { if(auto name = $layout.hit(x, y)) { if((*name).starts_with("button_")) { - auto& shape = $shapes.at(*name); - shape.setFillColor({100, 0, 0}); + auto& button = $buttons.at(*name); + button.shape.setFillColor({100, 0, 0}); } } } diff --git a/combat_ui.hpp b/combat_ui.hpp index be2a8f5..961d809 100644 --- a/combat_ui.hpp +++ b/combat_ui.hpp @@ -6,6 +6,7 @@ #include #include #include "lel.hpp" +#include "gui_gadgets.hpp" namespace gui { class CombatUI { @@ -17,9 +18,9 @@ namespace gui { GameLevel $level; sf::Font $font; sf::RectangleShape $background; - std::unordered_map $shapes; - std::unordered_map $label_boxes; - std::vector $labels; + std::unordered_map $buttons; + std::vector $labels; + std::unordered_map $meters; CombatUI(GameLevel level); void render(); diff --git a/gui_gadgets.hpp b/gui_gadgets.hpp new file mode 100644 index 0000000..39e28be --- /dev/null +++ b/gui_gadgets.hpp @@ -0,0 +1,75 @@ +#pragma once +#include +#include +#include +#include "lel.hpp" + +namespace gui { + struct Label { + sf::Font &font; + sf::Text text; + lel::Cell& cell; + + Label(lel::Cell& cell, std::string label_text, sf::Font &font) : + font(font), + text(font, label_text), + cell(cell) + { + auto bounds = text.getLocalBounds(); + auto text_cell = lel::center(bounds.size.x, bounds.size.y, cell); + // this stupid / 2 is because SFML renders from baseline rather than from the claimed bounding box + text.setPosition({float(text_cell.x), float(text_cell.y) - text_cell.h / 2}); + } + + void draw(sf::RenderWindow& window) { + window.draw(text); + } + }; + + struct Button { + Label label; + lel::Cell& cell; + sf::RectangleShape shape; + + Button(lel::Cell& cell, std::string label_text, sf::Font &font) : + label(cell, label_text, font), + cell(cell) + { + shape.setPosition({float(cell.x + 3), float(cell.y + 3)}); + shape.setSize({float(cell.w - 6), float(cell.h - 6)}); + shape.setFillColor(ColorValue::DARK_MID); + shape.setOutlineColor(ColorValue::MID); + shape.setOutlineThickness(1); + } + + void draw(sf::RenderWindow& window) { + window.draw(shape); + label.draw(window); + } + }; + + struct Meter { + sf::RectangleShape shape; + lel::Cell& cell; + + Meter(lel::Cell& cell) : + cell(cell) + { + shape.setPosition({float(cell.x + 3), float(cell.y + 3)}); + shape.setSize({float(cell.w - 6), float(cell.h - 6)}); + shape.setFillColor(ColorValue::DARK_MID); + shape.setOutlineColor(ColorValue::MID); + shape.setOutlineThickness(1); + } + + void draw(sf::RenderWindow& window) { + window.draw(shape); + } + + void set_percent(float percent) { + float level = percent * float(cell.w); + // ZED: this 6 is a border to make it a thing + shape.setSize({std::max(level, 0.0f), float(cell.h - 6)}); + } + }; +}