Cockatrice/cockatrice/src/interface/widgets/deck_analytics/mana_devotion_widget.cpp
BruebachL d31b044529
[Card DB] Split out database loading and querying from main class (#6175)
* Simplify add card.

Took 25 minutes

Took 8 minutes

# Commit time for manual adjustment:
# Took 16 minutes

Took 7 seconds

* Refactor out db loading from card db.

Took 39 minutes

Took 9 minutes

Took 2 minutes


Took 17 seconds

* Refactor out db queries from card db.

Took 42 minutes

* Lint.

Took 3 minutes

* I guess.

Took 7 minutes

* Tests.

Took 15 minutes

* I don't understand this.

Took 9 minutes

* fix linker errors

* Rename to querier and promote to QObject

Took 39 minutes

* Lint.

Took 3 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
Co-authored-by: ebbit1q <ebbit1q@gmail.com>
2025-09-27 00:27:15 +02:00

146 lines
5.1 KiB
C++

#include "mana_devotion_widget.h"
#include "../../../database/card_database.h"
#include "../../../database/card_database_manager.h"
#include "../../../deck/deck_loader.h"
#include "../../../main.h"
#include "../general/display/banner_widget.h"
#include "../general/display/bar_widget.h"
#include <deck_list.h>
#include <iostream>
#include <regex>
#include <string>
#include <unordered_map>
ManaDevotionWidget::ManaDevotionWidget(QWidget *parent, DeckListModel *_deckListModel)
: QWidget(parent), deckListModel(_deckListModel)
{
layout = new QVBoxLayout(this);
setLayout(layout);
bannerWidget = new BannerWidget(this, tr("Mana Devotion"), Qt::Vertical, 100);
bannerWidget->setMaximumHeight(100);
layout->addWidget(bannerWidget);
barLayout = new QHBoxLayout();
layout->addLayout(barLayout);
connect(deckListModel, &DeckListModel::dataChanged, this, &ManaDevotionWidget::analyzeManaDevotion);
retranslateUi();
}
void ManaDevotionWidget::retranslateUi()
{
bannerWidget->setText(tr("Mana Devotion"));
}
void ManaDevotionWidget::setDeckModel(DeckListModel *deckModel)
{
deckListModel = deckModel;
connect(deckListModel, &DeckListModel::dataChanged, this, &ManaDevotionWidget::analyzeManaDevotion);
analyzeManaDevotion();
}
std::unordered_map<char, int> ManaDevotionWidget::analyzeManaDevotion()
{
manaDevotionMap.clear();
InnerDecklistNode *listRoot = deckListModel->getDeckList()->getRoot();
for (int i = 0; i < listRoot->size(); i++) {
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
for (int j = 0; j < currentZone->size(); j++) {
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
if (!currentCard)
continue;
for (int k = 0; k < currentCard->getNumber(); ++k) {
CardInfoPtr info = CardDatabaseManager::query()->getCardInfo(currentCard->getName());
if (info) {
auto devotion = countManaSymbols(info->getManaCost());
mergeManaCounts(manaDevotionMap, devotion);
}
}
}
}
updateDisplay();
return manaDevotionMap;
}
void ManaDevotionWidget::updateDisplay()
{
// Clear the layout first
QLayoutItem *item;
while ((item = barLayout->takeAt(0)) != nullptr) {
item->widget()->deleteLater();
delete item;
}
int highestEntry = 0;
for (auto entry : manaDevotionMap) {
if (highestEntry < entry.second) {
highestEntry = entry.second;
}
}
// Define color mapping for devotion bars
std::unordered_map<char, QColor> manaColors = {{'W', QColor(248, 231, 185)}, {'U', QColor(14, 104, 171)},
{'B', QColor(21, 11, 0)}, {'R', QColor(211, 32, 42)},
{'G', QColor(0, 115, 62)}, {'C', QColor(150, 150, 150)}};
for (auto entry : manaDevotionMap) {
QColor barColor = manaColors.count(entry.first) ? manaColors[entry.first] : Qt::gray;
BarWidget *barWidget = new BarWidget(QString(entry.first), entry.second, highestEntry, barColor, this);
barLayout->addWidget(barWidget);
}
update(); // Update the widget display
}
std::unordered_map<char, int> ManaDevotionWidget::countManaSymbols(const QString &manaString)
{
std::unordered_map<char, int> manaCounts = {{'W', 0}, {'U', 0}, {'B', 0}, {'R', 0}, {'G', 0}};
int len = manaString.length();
for (int i = 0; i < len; ++i) {
if (manaString[i] == '{') {
++i; // Move past '{'
if (i < len && manaCounts.find(manaString[i].toLatin1()) != manaCounts.end()) {
char mana1 = manaString[i].toLatin1();
++i; // Move to next character
if (i < len && manaString[i] == '/') {
++i; // Move past '/'
if (i < len && manaCounts.find(manaString[i].toLatin1()) != manaCounts.end()) {
char mana2 = manaString[i].toLatin1();
manaCounts[mana1]++;
manaCounts[mana2]++;
} else {
// Handle cases like "{W/}" where second part is invalid
manaCounts[mana1]++;
}
} else {
manaCounts[mana1]++;
}
}
// Ensure we always skip to the closing '}'
while (i < len && manaString[i] != '}') {
++i;
}
}
// Check if the character is a standalone mana symbol (not inside {})
else if (manaCounts.find(manaString[i].toLatin1()) != manaCounts.end()) {
manaCounts[manaString[i].toLatin1()]++;
}
}
return manaCounts;
}
void ManaDevotionWidget::mergeManaCounts(std::unordered_map<char, int> &manaCounts1,
const std::unordered_map<char, int> &manaCounts2)
{
for (const auto &pair : manaCounts2) {
manaCounts1[pair.first] += pair.second; // Add values for matching keys
}
}