1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Added skills customization

This commit is contained in:
nordsoft 2023-09-10 23:39:54 +02:00
parent 445e39ad20
commit a89a8019ab
6 changed files with 394 additions and 2 deletions

View File

@ -999,8 +999,11 @@ int32_t CGHeroInstance::getSpellCost(const spells::Spell * sp) const
void CGHeroInstance::pushPrimSkill( PrimarySkill which, int val )
{
assert(!hasBonus(Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int>(which))
.And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL))));
auto sel = Selector::typeSubtype(BonusType::PRIMARY_SKILL, static_cast<int>(which))
.And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL));
if(hasBonus(sel))
removeBonuses(sel);
addNewBonus(std::make_shared<Bonus>(BonusDuration::PERMANENT, BonusType::PRIMARY_SKILL, BonusSource::HERO_BASE_SKILL, val, id.getNum(), static_cast<int>(which)));
}

View File

@ -32,6 +32,7 @@ set(editor_SRCS
inspector/messagewidget.cpp
inspector/rewardswidget.cpp
inspector/questwidget.cpp
inspector/heroskillswidget.cpp
resourceExtractor/ResourceConverter.cpp
)
@ -68,6 +69,7 @@ set(editor_HEADERS
inspector/messagewidget.h
inspector/rewardswidget.h
inspector/questwidget.h
inspector/heroskillswidget.h
resourceExtractor/ResourceConverter.h
)
@ -91,6 +93,7 @@ set(editor_FORMS
inspector/messagewidget.ui
inspector/rewardswidget.ui
inspector/questwidget.ui
inspector/heroskillswidget.ui
)
set(editor_TS

View File

@ -0,0 +1,149 @@
/*
* heroskillswidget.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "heroskillswidget.h"
#include "ui_heroskillswidget.h"
#include "../../lib/constants/StringConstants.h"
#include "../../lib/CSkillHandler.h"
#include "inspector.h"
static QList<std::pair<QString, QVariant>> LevelIdentifiers
{
{QObject::tr("Beginner"), QVariant::fromValue(1)},
{QObject::tr("Advanced"), QVariant::fromValue(2)},
{QObject::tr("Expert"), QVariant::fromValue(3)},
};
HeroSkillsWidget::HeroSkillsWidget(CGHeroInstance & h, QWidget *parent) :
QDialog(parent),
ui(new Ui::HeroSkillsWidget),
hero(h)
{
ui->setupUi(this);
ui->labelAttack->setText(QString::fromStdString(NPrimarySkill::names[0]));
ui->labelDefence->setText(QString::fromStdString(NPrimarySkill::names[1]));
ui->labelPower->setText(QString::fromStdString(NPrimarySkill::names[2]));
ui->labelKnowledge->setText(QString::fromStdString(NPrimarySkill::names[3]));
auto * delegate = new InspectorDelegate;
for(auto s : VLC->skillh->objects)
delegate->options.push_back({QString::fromStdString(s->getNameTranslated()), QVariant::fromValue(s->getId().getNum())});
ui->skills->setItemDelegateForColumn(0, delegate);
delegate = new InspectorDelegate;
delegate->options = LevelIdentifiers;
ui->skills->setItemDelegateForColumn(1, delegate);
}
HeroSkillsWidget::~HeroSkillsWidget()
{
delete ui;
}
void HeroSkillsWidget::on_addButton_clicked()
{
ui->skills->setRowCount(ui->skills->rowCount() + 1);
}
void HeroSkillsWidget::on_removeButton_clicked()
{
ui->skills->removeRow(ui->skills->currentRow());
}
void HeroSkillsWidget::on_checkBox_toggled(bool checked)
{
ui->skills->setEnabled(checked);
ui->addButton->setEnabled(checked);
ui->removeButton->setEnabled(checked);
}
void HeroSkillsWidget::obtainData()
{
ui->attack->setValue(hero.getPrimSkillLevel(PrimarySkill::ATTACK));
ui->defence->setValue(hero.getPrimSkillLevel(PrimarySkill::DEFENSE));
ui->power->setValue(hero.getPrimSkillLevel(PrimarySkill::SPELL_POWER));
ui->knowledge->setValue(hero.getPrimSkillLevel(PrimarySkill::KNOWLEDGE));
if(!hero.secSkills.empty() && hero.secSkills.front().first.getNum() == -1)
return;
ui->checkBox->setChecked(true);
ui->skills->setRowCount(hero.secSkills.size());
int i = 0;
for(auto & s : hero.secSkills)
{
auto * itemSkill = new QTableWidgetItem;
itemSkill->setText(QString::fromStdString(VLC->skillh->getById(s.first)->getNameTranslated()));
itemSkill->setData(Qt::UserRole, QVariant::fromValue(s.first.getNum()));
ui->skills->setItem(i, 0, itemSkill);
auto * itemLevel = new QTableWidgetItem;
itemLevel->setText(LevelIdentifiers[s.second - 1].first);
itemLevel->setData(Qt::UserRole, LevelIdentifiers[s.second - 1].second);
ui->skills->setItem(i++, 1, itemLevel);
}
}
void HeroSkillsWidget::commitChanges()
{
hero.pushPrimSkill(PrimarySkill::ATTACK, ui->attack->value());
hero.pushPrimSkill(PrimarySkill::DEFENSE, ui->defence->value());
hero.pushPrimSkill(PrimarySkill::SPELL_POWER, ui->power->value());
hero.pushPrimSkill(PrimarySkill::KNOWLEDGE, ui->knowledge->value());
hero.secSkills.clear();
if(!ui->checkBox->isChecked())
{
hero.secSkills.push_back(std::make_pair(SecondarySkill(-1), -1));
return;
}
for(int i = 0; i < ui->skills->rowCount(); ++i)
{
if(ui->skills->item(i, 0) && ui->skills->item(i, 1))
hero.secSkills.push_back(std::make_pair(SecondarySkill(ui->skills->item(i, 0)->data(Qt::UserRole).toInt()), ui->skills->item(i, 1)->data(Qt::UserRole).toInt()));
}
}
HeroSkillsDelegate::HeroSkillsDelegate(CGHeroInstance & h): hero(h), QStyledItemDelegate()
{
}
QWidget * HeroSkillsDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return new HeroSkillsWidget(hero, parent);
}
void HeroSkillsDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if(auto * ed = qobject_cast<HeroSkillsWidget *>(editor))
{
ed->obtainData();
}
else
{
QStyledItemDelegate::setEditorData(editor, index);
}
}
void HeroSkillsDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if(auto * ed = qobject_cast<HeroSkillsWidget *>(editor))
{
ed->commitChanges();
}
else
{
QStyledItemDelegate::setModelData(editor, model, index);
}
}

View File

@ -0,0 +1,59 @@
/*
* heroskillswidget.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include <QDialog>
#include "../../lib/mapObjects/CGHeroInstance.h"
namespace Ui {
class HeroSkillsWidget;
}
class HeroSkillsWidget : public QDialog
{
Q_OBJECT
public:
explicit HeroSkillsWidget(CGHeroInstance &, QWidget *parent = nullptr);
~HeroSkillsWidget();
void obtainData();
void commitChanges();
private slots:
void on_addButton_clicked();
void on_removeButton_clicked();
void on_checkBox_toggled(bool checked);
private:
Ui::HeroSkillsWidget *ui;
CGHeroInstance & hero;
std::set<int> occupiedSkills;
};
class HeroSkillsDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
using QStyledItemDelegate::QStyledItemDelegate;
HeroSkillsDelegate(CGHeroInstance &);
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
private:
CGHeroInstance & hero;
};

View File

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>HeroSkillsWidget</class>
<widget class="QDialog" name="HeroSkillsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>464</width>
<height>301</height>
</rect>
</property>
<property name="windowTitle">
<string>Hero skills</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>4</number>
</property>
<item>
<layout class="QHBoxLayout" name="statsLayout">
<item>
<widget class="QLabel" name="labelAttack">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="attack"/>
</item>
<item>
<widget class="QLabel" name="labelDefence">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="defence"/>
</item>
<item>
<widget class="QLabel" name="labelPower">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="power"/>
</item>
<item>
<widget class="QLabel" name="labelKnowledge">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="knowledge"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="addButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTableWidget" name="skills">
<property name="enabled">
<bool>false</bool>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>120</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>21</number>
</attribute>
<column>
<property name="text">
<string>Skill</string>
</property>
</column>
<column>
<property name="text">
<string>Level</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Customize skills</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -25,6 +25,7 @@
#include "messagewidget.h"
#include "rewardswidget.h"
#include "questwidget.h"
#include "heroskillswidget.h"
static QList<std::pair<QString, QVariant>> MissionIdentifiers
{
@ -279,6 +280,9 @@ void Inspector::updateProperties(CGHeroInstance * o)
addProperty("Biography", o->biographyCustom, new MessageDelegate, false);
addProperty("Portrait", o->portrait, false);
auto * delegate = new HeroSkillsDelegate(*o);
addProperty("Skills", PropertyEditorPlaceholder(), delegate, false);
if(o->type)
{ //Hero type
auto * delegate = new InspectorDelegate;