Untitled

mail@pastecode.io avatar
unknown
c_cpp
5 months ago
5.7 kB
2
Indexable
#pragma once

#include <iostream>
#include <string>
#include "SFML/Graphics/Color.hpp"
#include "SFML/Graphics/Drawable.hpp"
#include "SFML/Graphics/Rect.hpp"
#include "SFML/Graphics/RenderTarget.hpp"
#include "SFML/System/Vector2.hpp"
#include "artifact-type.hpp"
#include "artifact.hpp"
#include "rounded-rectangle.hpp"

class ArtifactBox : public sf::Drawable {
public:
    explicit ArtifactBox(ArtifactType artifactType_) : m_artifact(artifactType_) {
        const sf::Color rectangleColor{0x323232FF};
        m_rectangle.setFillColor(rectangleColor);
        int       typeIndex{static_cast<int>(m_artifact.type())};
        const int columnCount{7};
        // TODO: the way i use the magin and pad is arbitrary and retarded, oh well
        const float margin{10};
        const float pad{margin / 2};
        auto        borderSize = m_border.getSize();
        auto        column     = static_cast<float>(typeIndex % columnCount);
        auto        row        = std::floorf(static_cast<float>(typeIndex) / columnCount);

        m_rectangle.setPosition(
            column * (borderSize.x + pad) + margin, row * (borderSize.y + pad) + margin);

        m_artifact.setOrigin(static_cast<sf::Vector2f>(m_artifact.getSize()) / 2.F);

        auto rectCenter = m_rectangle.getPosition() + m_rectangle.getSize() / 2.F;

        m_artifact.setPosition(
            {rectCenter.x,
             m_rectangle.getPosition().y +
                 m_rectangle.getSize().y /
                     3.F}); // NOLINT(*magic*) // divisor sets artifact higher in the box
        m_border.setOrigin(borderSize / 2.F);
        m_border.setPosition(rectCenter);
        static const std::string fontPath{"../assets/NotoSans-Regular.ttf"};
        if (m_font->getInfo().family.empty()) {
            if (!m_font->loadFromFile(fontPath)) {
                std::cerr << "Could not load font \"" << fontPath << "\"\n";
                std::cerr.flush();
            }
        }
        m_count.setFillColor(sf::Color::White);
        m_count.setOrigin(0, std::roundf(m_count.getLocalBounds().getSize().y) + margin);
        m_count.setPosition(
            m_rectangle.getPosition().x + margin,
            m_rectangle.getPosition().y + m_rectangleSize.y - margin);

        const std::string texturePath{"../assets/craft-icon-white.png"};
        while (true) {
            if (m_craftTexture->loadFromFile(texturePath)) {
                break;
            }
            std::cerr << "Texture \"" << texturePath << "\" failed to load...";
            std::cerr.flush();
        }
        m_craftIcon.setTexture(*m_craftTexture);
        m_craftIcon.setScale(0.05, 0.05);
        m_craftIcon.setOrigin(m_craftIcon.getLocalBounds().getSize());
        m_craftIcon.setPosition(
            m_rectangle.getPosition().x + m_rectangleSize.x - margin,
            m_rectangle.getPosition().y + m_rectangleSize.y - margin);

        m_plus.setOrigin(std::roundf(m_plus.getLocalBounds().getSize().x) + margin, 0);
        m_plus.setPosition(
            m_rectangle.getPosition().x + m_rectangleSize.x - pad,
            m_rectangle.getPosition().y - pad);
        m_minus.setPosition(
            m_rectangle.getPosition().x + margin, m_rectangle.getPosition().y - pad);
    }

    [[nodiscard]] auto artifact() const -> Artifact { return m_artifact; }

    void setCount(int count_) { m_count.setString(std::to_string(count_)); }

    void borderSwitch(bool canCraft_) {
        if (canCraft_) {
            m_border.setFillColor(sf::Color::White);
        } else {
            m_border.setFillColor(sf::Color::Black);
        }
    }

    [[nodiscard]] auto plusBounds() -> sf::FloatRect { return m_plus.getGlobalBounds(); }

    [[nodiscard]] auto minusBounds() -> sf::FloatRect {
        return m_minus.getGlobalBounds();
    }

    [[nodiscard]] auto craftBounds() -> sf::FloatRect {
        return m_craftIcon.getGlobalBounds();
    }

private:
    void draw(sf::RenderTarget& target_, sf::RenderStates states_) const override {
        target_.draw(m_border, states_);
        target_.draw(m_rectangle, states_);
        target_.draw(m_artifact, states_);
        target_.draw(m_count, states_);
        target_.draw(m_craftIcon, states_);
        target_.draw(m_plus, states_);
        target_.draw(m_minus, states_);
    }

    Artifact                     m_artifact;
    sf::Vector2f                 m_rectangleSize{200.F, 100.F};   // NOLINT (*magic*)
    float                        m_rectangleCornerRadius{10.F};   // NOLINT (*magic*)
    unsigned int                 m_rectangleCornerPointCount{10}; // NOLINT (*magic*)
    std::shared_ptr<sf::Font>    m_font{std::make_shared<sf::Font>()};
    static const unsigned int    m_fontSize{36};
    sf::Text                     m_count{"0", *m_font, m_fontSize};
    sf::Text                     m_plus{"+", *m_font, m_fontSize};
    sf::Text                     m_minus{"-", *m_font, m_fontSize};
    std::shared_ptr<sf::Texture> m_craftTexture{std::make_shared<sf::Texture>()};
    sf::Sprite                   m_craftIcon;

    sf::RoundedRectangleShape m_rectangle{
        m_rectangleSize, m_rectangleCornerRadius, m_rectangleCornerPointCount};

    float m_borderWidth{m_rectangleSize.y / 10.F}; // NOLINT (*magic*)

    sf::RoundedRectangleShape m_border{
        {m_rectangleSize.x + m_borderWidth, m_rectangleSize.y + m_borderWidth},
        m_rectangleCornerRadius *
            1.5F, // NOLINT(*magic*) // this multiplier makes the corner radius look good
                  // in a few specific cases but its good enough, theres probably a
                  // formula to do this but this will do for now
        m_rectangleCornerPointCount};
};
Leave a Comment