/**********************************************************************************
* Copyright 2020-2022 Michael McBride
*
* This file is part of PF2 Character Manager
*
* PF2 Character Manager is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
**********************************************************************************/
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QVariant>
#include <QDebug>
#include "armor.h"
#include "armormodel.h"
#include "character.h"
#include "config.h"
Armor::Armor(QObject *parent) : QObject(parent)
{
// Load Armors from the Rules.db Armor table
QString sql = QString("SELECT id, name, Desc, Level, Category, Price, ACBonus, DexCap, CheckPenalty, SpeedPenalty,"
"Strength, Bulk, Grp, Traits, Hardness, HP, BT, Source, Page, AON from Armor ORDER BY Name");
QString sql2=QString("SELECT ID, name, Desc,Price,ACBonus,SpeedPenalty,Bulk,Hardness,HP,BT,Source,Page,AON from Shields ORDER BY Name");
QSqlDatabase dDB = QSqlDatabase::addDatabase("QSQLITE");
QString cName = QSqlDatabase::database().connectionName();
{
dDB.setDatabaseName(rulesDB);
if( !dDB.open() )
{
qFatal("Could not open Rules Database....");
}
QSqlQuery query;
query.exec(sql);
while(query.next()) {
QString id = query.value(0).toString();
QString name = query.value(1).toString();
QString desc = query.value(2).toString();
QVariant lvl = query.value(3);
QVariant cat = query.value(4);
QVariant price = query.value(5);
QVariant AC = query.value(6);
QVariant dex = query.value(7);
QVariant check = query.value(8);
QVariant speed = query.value(9);
QVariant str = query.value(10);
QVariant bulk = query.value(11);
QVariant group = query.value(12);
QVariant traits = query.value(13);
QVariant hardness = query.value(14);
QVariant HP = query.value(15);
QVariant BT = query.value(16);
QVariant source = query.value(17);
QVariant page = query.value(18);
QVariant aon = query.value(19);
QString c=tr("Armor");
allItems.append({id, name, desc, lvl, cat, price, AC, dex, check, speed, str,
bulk, group, traits, hardness, HP, BT, source, page, aon, c });
}
query.exec(sql2);
while(query.next()) {
QVariant id = query.value(0).toInt()+shieldNumAdj;
QString name = query.value(1).toString();
QString desc = query.value(2).toString();
QVariant lvl = 0; //query.value(3);
QVariant cat = "S"; //query.value(4); "S" for Shield
QVariant price = query.value(3);
QVariant AC = query.value(4);
QVariant dex = -1; //query.value(7);
QVariant check = ""; //query.value(8);
QVariant speed = query.value(5);
QVariant str = ""; //query.value(10);
QVariant bulk = query.value(6);
QVariant group = ""; //query.value(12);
QVariant traits = ""; //query.value(13);
QVariant hardness = query.value(7);
QVariant HP = query.value(8);
QVariant BT = query.value(9);
QVariant source = query.value(10);
QVariant page = query.value(11);
QVariant aon = query.value(12);
QVariant c=tr("Shield");
allItems.append({id, name, desc, lvl, cat, price, AC, dex, check, speed, str,
bulk, group, traits, hardness, HP, BT, source, page, aon, c });
}
// Armor Groups
sql = QString("SELECT id, Name, SpecializationEffects from ArmorGroup ORDER BY ID");
query.exec(sql);
while(query.next()) {
QVariant id = query.value(0);
QVariant name = query.value(1);
QVariant spec = query.value(2);
mGroups.append({id, name, spec});
}
dDB.close();
}
dDB=QSqlDatabase();
QSqlDatabase::removeDatabase(cName);
filter = UNARMORED + LIGHT + MEDIUM + HEAVY;
updateList();
}
void Armor::updateList()
{
mItems.clear();
// update mItems based on filters
for (ArmorItem a : allItems)
{
if(sList.contains(a.Source.toString())) {
if (a.Category == "S" && sShields) {
mItems.append(a);
} else {
if ((a.Category == "U") && (filter & unarmored) && sArmor)
mItems.append(a);
else if ((a.Category == "L") && (filter & light) && sArmor)
mItems.append(a);
else if ((a.Category == "M") && (filter & medium) && sArmor)
mItems.append(a);
else if ((a.Category == "H") && (filter & heavy) && sArmor)
mItems.append(a);
}
}
}
this->listChanged();
}
// This should be a combo checkbox
void Armor::setStatus(QVariant i)
{
filter = filter + i.toInt();
updateList();
}
bool Armor::showShields() {return sShields;}
void Armor::setShowShields(QObject *A, bool newVle) {
sShields=newVle;
character *ch = static_cast<character*>(A);
updateList();
sortCol(ch,defColSort);
}
bool Armor::showArmor() {return sArmor; }
void Armor::setShowArmor(QObject *A, bool newVle) {
sArmor=newVle;
character *ch = static_cast<character*>(A);
updateList();
sortCol(ch,defColSort);
}
void Armor::sortCol(QObject *A, int sorton)
{
// Sort list by: 0=Name, 1= Price, 2= AC Bonus, 3=DexCap
// 4=Speed, 5=Strength, 6=Bulk, 7=Check Penalty
character *ch = static_cast<character*>(A);
defColSort=sorton;
sList=ch->sourceList;
updateList();
switch (sorton) {
case 0: {
for(int i=0;i<mItems.size();i++) {
for(int j=0;j<mItems.size();j++) {
if(mItems[i].Name.toLower()<mItems[j].Name.toLower()) {
ArmorItem tmpItem=mItems[i];
mItems[i]=mItems[j];
mItems[j]=tmpItem;
}
}
}
break;
}
case 1: {
for(int i=0;i<mItems.size();i++) {
for(int j=0;j<mItems.size();j++) {
if(mItems[i].Price.toInt()<mItems[j].Price.toInt()) {
ArmorItem tmpItem=mItems[i];
mItems[i]=mItems[j];
mItems[j]=tmpItem;
}
}
}
break;
}
case 2: {
for(int i=0;i<mItems.size();i++) {
for(int j=0;j<mItems.size();j++) {
if(mItems[i].ACBonus.toInt() <mItems[j].ACBonus.toInt()) {
ArmorItem tmpItem=mItems[i];
mItems[i]=mItems[j];
mItems[j]=tmpItem;
}
}
}
break;
}
case 3: {
for(int i=0;i<mItems.size();i++) {
for(int j=0;j<mItems.size();j++) {
if(mItems[i].DEXCap.toInt() <mItems[j].DEXCap.toInt()) {
ArmorItem tmpItem=mItems[i];
mItems[i]=mItems[j];
mItems[j]=tmpItem;
}
}
}
break;
}
case 4: {
for(int i=0;i<mItems.size();i++) {
for(int j=0;j<mItems.size();j++) {
if(mItems[i].SpeedPenality.toInt() >mItems[j].SpeedPenality.toInt()) {
ArmorItem tmpItem=mItems[i];
mItems[i]=mItems[j];
mItems[j]=tmpItem;
}
}
}
break;
}
case 5: {
for(int i=0;i<mItems.size();i++) {
for(int j=0;j<mItems.size();j++) {
if(mItems[i].Strength.toInt() <mItems[j].Strength.toInt()) {
ArmorItem tmpItem=mItems[i];
mItems[i]=mItems[j];
mItems[j]=tmpItem;
}
}
}
break;
}
case 6: {
for(int i=0;i<mItems.size();i++) {
for(int j=0;j<mItems.size();j++) {
if(mItems[i].Bulk.toInt() <mItems[j].Bulk.toInt()) {
ArmorItem tmpItem=mItems[i];
mItems[i]=mItems[j];
mItems[j]=tmpItem;
}
}
}
break;
}
case 7: {
for(int i=0;i<mItems.size();i++) {
for(int j=0;j<mItems.size();j++) {
if(mItems[i].CheckPenality.toInt() <mItems[j].CheckPenality.toInt()) {
ArmorItem tmpItem=mItems[i];
mItems[i]=mItems[j];
mItems[j]=tmpItem;
}
}
}
break;
}
}
this->listChanged();
}
QVector<ArmorItem> Armor::items() const
{
return mItems;
}
QVector<ArmorGroup> Armor::groups() const
{
return mGroups;
}
QVariant Armor::groupToTxt(QVariant id)
{
QVariant txt = "";
// Find in mGroup name with id
QSqlDatabase dDB = QSqlDatabase::addDatabase("QSQLITE");
QString cName = QSqlDatabase::database().connectionName();
{
dDB.setDatabaseName(rulesDB);
if( !dDB.open() )
{
qFatal("Could not open Rules Database....");
}
QSqlQuery query;
query.prepare("Select Name from ArmorGroup WHERE id=:id");
query.bindValue(":id",id);
query.exec();
if(query.next()) {
txt=query.value(0).toString();
}
dDB.close();
}
dDB=QSqlDatabase();
QSqlDatabase::removeDatabase(cName);
return txt;
}
// Maybe load table into a trait class with convertions to txt.
// This table is shared for all traits.
QVariant Armor::traitToTxt(QVariant trait)
{
QStringList list = trait.toString().split('/', Qt::SkipEmptyParts);
QStringList traitList;
QVariant txt = "";
foreach (const QString &item,list) {
QSqlDatabase dDB = QSqlDatabase::addDatabase("QSQLITE");
QString cName = QSqlDatabase::database().connectionName();
{
dDB.setDatabaseName(rulesDB);
if( !dDB.open() )
{
qFatal("Could not open Rules Database....");
}
QSqlQuery query;
query.prepare("Select Name from Traits WHERE id=:id;");
query.bindValue(":id",item.toInt());
query.exec();
if(query.next()) {
traitList.append(query.value(0).toString());
}
dDB.close();
}
dDB=QSqlDatabase();
QSqlDatabase::removeDatabase(cName);
}
return traitList.join(",");
}
void Armor::setUnarmored(bool vle) {
unarmored=vle;
updateList();
}
void Armor::setLight(bool vle) {
light=vle;
updateList();
}
void Armor::setMedium(bool vle) {
medium=vle;
updateList();
}
void Armor::setHeavy(bool vle) {
heavy=vle;
updateList();
}
bool Armor::setItemAt(int index, const ArmorItem &item)
{
if (index < 0 || index >= mItems.size())
return false;
const ArmorItem &oldItem = mItems.at(index);
if (item.Description == oldItem.Description)
return false;
mItems[index] = item;
return true;
}