diff --git a/src/BattleServer/battle.cpp b/src/BattleServer/battle.cpp index e251d61494..94e0f59bbb 100644 --- a/src/BattleServer/battle.cpp +++ b/src/BattleServer/battle.cpp @@ -624,7 +624,7 @@ BattleChoices BattleSituation::createChoice(int slot) } //Mega Evolution is not hindered by Embargo, etc. - if (((ItemInfo::isMegaStone(poke(slot).item()) && ItemInfo::MegaStoneForme(poke(slot).item()).original() == poke(slot).num()) || (poke(slot).num() == Pokemon::Rayquaza && hasMove(slot, Move::DragonAscent))) && !megas[player(slot)]) { + if (canMegaEvolve(slot)) { Pokemon::uniqueId forme = poke(slot).num() == Pokemon::Rayquaza ? Pokemon::Rayquaza_Mega : ItemInfo::MegaStoneForme(poke(slot).item()); if (!bannedPokes[0].contains(PokemonInfo::Name(forme)) && !bannedPokes[1].contains(PokemonInfo::Name(forme))) { ret.mega = true; @@ -902,7 +902,7 @@ void BattleSituation::megaEvolve(int slot) //Split to allow Mega Evo to activate on Special Pursuit //Mega Evolution is not hindered by Embargo, etc. if (choice(slot).mega()) { - if ((ItemInfo::isMegaStone(poke(slot).item()) && ItemInfo::MegaStoneForme(poke(slot).item()).original() == poke(slot).num()) || (poke(slot).num() == Pokemon::Rayquaza && hasMove(slot, Move::DragonAscent))) { + if (canMegaEvolve(slot)) { Pokemon::uniqueId forme = poke(slot).num() == Pokemon::Rayquaza ? Pokemon::Rayquaza_Mega : ItemInfo::MegaStoneForme(poke(slot).item()); if (!bannedPokes[0].contains(PokemonInfo::Name(forme)) && !bannedPokes[1].contains(PokemonInfo::Name(forme))) { sendItemMessage(66, slot, 0, 0, 0, forme.toPokeRef()); @@ -4442,3 +4442,21 @@ bool BattleSituation::preTransPoke(int s, Pokemon::uniqueId check) } return false; } + +bool BattleSituation::canMegaEvolve (int slot) { + if (megas[player(slot)]) { + return false; + } + if (ItemInfo::isMegaStone(poke(slot).item())) { + if (ItemInfo::MegaStoneForme(poke(slot).item()).original() == poke(slot).num()) { + return true; + } + if (ItemInfo::MegaStoneForme(poke(slot).item()).original() == Pokemon::uniqueId(poke(slot).num().pokenum,0)) { + return true; + } + } + if ((poke(slot).num() == Pokemon::Rayquaza && hasMove(slot, Move::DragonAscent))) { + return true; + } + return false; +} diff --git a/src/BattleServer/battle.h b/src/BattleServer/battle.h index 3a9340012e..5e5b27039c 100644 --- a/src/BattleServer/battle.h +++ b/src/BattleServer/battle.h @@ -82,6 +82,7 @@ class BattleSituation : public BattleBase void symbiosisPass(int s); bool canPassMStone(int target, int item); bool preTransPoke(int s, Pokemon::uniqueId check); + bool canMegaEvolve(int slot); void inflictStatus(int player, int Status, int inflicter, int minturns = 0, int maxturns = 0); void inflictConfused(int player, int source, bool tell=true); void inflictRecoil(int source, int target); diff --git a/src/Server/scriptengine.cpp b/src/Server/scriptengine.cpp index 148d58577e..0db8094813 100644 --- a/src/Server/scriptengine.cpp +++ b/src/Server/scriptengine.cpp @@ -1965,6 +1965,16 @@ bool ScriptEngine::hasTeamPoke(int id, int team, int pokemonnum) return false; } +bool ScriptEngine::teamPokeIllegal(int id, int team, int slot) +{ + if (!testPlayer("teamPokeIllegal(id, team, slot)", id) || !testTeamCount("teamPokeIllegal(id, team, slot)", id, team) + || !testRange("teamPokeIllegal(id, team, slot)", slot, 0, 5)) { + return false; + } + + return myserver->player(id)->team(team).poke(slot).illegal(); +} + QScriptValue ScriptEngine::indexOfTeamPoke(int id, int team, int pokenum) { if (!testPlayer("indexOfTeamPoke(id, team, pokenum)", id) diff --git a/src/Server/scriptengine.h b/src/Server/scriptengine.h index 2fca854787..d3cf074d2b 100644 --- a/src/Server/scriptengine.h +++ b/src/Server/scriptengine.h @@ -352,6 +352,7 @@ class ScriptEngine : public QObject Q_INVOKABLE QScriptValue teamPokePP(int id, int team, int slot, int moveslot); Q_INVOKABLE QScriptValue teamPoke(int id, quint32 teamLo, int index, quint32 teamHi = 0); Q_INVOKABLE QScriptValue teamPokeName(int id, int team, int pokemonnum); + Q_INVOKABLE bool teamPokeIllegal(int id, int team, int slot); Q_INVOKABLE bool hasTeamPoke(int id, int team, int pokemonnum); Q_INVOKABLE QScriptValue indexOfTeamPoke(int id, int team, int pokenum); Q_INVOKABLE bool hasDreamWorldAbility(int id, int team, int slot, int gen = 5); diff --git a/src/Server/tier.cpp b/src/Server/tier.cpp index fb8aae1d8a..22fea93590 100644 --- a/src/Server/tier.cpp +++ b/src/Server/tier.cpp @@ -326,45 +326,48 @@ void Tier::addBanParent(Tier *t) QString Tier::bannedReason(const PokeBattle &p, bool child) const { QString errorList = ""; - if(banPokes) { - if(bannedPokes.contains(PokemonInfo::NonAestheticForme(p.num()))) { + if (banPokes) { + if (bannedPokes.contains(PokemonInfo::NonAestheticForme(p.num()))) { errorList += QString("Pokemon %1 is banned, ").arg(PokemonInfo::Name(p.num())); } - if(bannedMoves.size() > 0) { + if (bannedMoves.size() > 0) { for(int i = 0; i < 4; i++) { if(bannedMoves.contains(p.move(i).num())) { errorList += QString("Move %1 is banned, ").arg(MoveInfo::Name(p.move(i).num())); } } } - if(bannedItems.contains(p.item())) { + if (bannedItems.contains(p.item())) { errorList += QString("Item %1 is banned, ").arg(ItemInfo::Name(p.item())); } if (bannedAbilities.contains(p.ability())) { errorList += QString("Ability %1 is banned, ").arg(AbilityInfo::Name(p.ability())); } } else { - if(bannedPokes.size() > 0 && !bannedPokes.contains(PokemonInfo::NonAestheticForme(p.num()))) { + if (bannedPokes.size() > 0 && !bannedPokes.contains(PokemonInfo::NonAestheticForme(p.num()))) { errorList += QString("Pokemon %1 is banned, ").arg(PokemonInfo::Name(p.num())); } - if(bannedMoves.size() > 0) { + if (bannedMoves.size() > 0) { for(int i = 0; i < 4; i++) { if(p.move(i).num() != 0 && !bannedMoves.contains(p.move(i).num())) { errorList += QString("Move %1 is banned, ").arg(MoveInfo::Name(p.move(i).num())); } } } - if(bannedItems.size() > 0 && p.item() != 0 && !bannedItems.contains(p.item())) { + if (bannedItems.size() > 0 && p.item() != 0 && !bannedItems.contains(p.item())) { errorList += QString("Item %1 is banned, ").arg(ItemInfo::Name(p.item())); } if (bannedAbilities.size() > 0 && p.ability() != 0 && !bannedAbilities.contains(p.ability())) { errorList += QString("Ability %1 is banned, ").arg(AbilityInfo::Name(p.ability())); } } + if (allowIllegal != "true" && p.illegal()) { + errorList += QString("Pokemon %1 has an illegal set, ").arg(PokemonInfo::Name(p.num())); + } if (parent) { errorList += parent->bannedReason(p, true); } - if(errorList.length() >= 2 && !child) { + if (errorList.length() >= 2 && !child) { QStringList errors = errorList.split(", ").toSet().toList(); //remove duplicates QMutableListIterator i(errors); while (i.hasNext()) { @@ -432,7 +435,9 @@ bool Tier::isBanned(const PokeBattle &p) const { return true; } } - + if (allowIllegal != "true" && p.illegal()) { + return true; + } if (parent) { return parent->isBanned(p); } else { @@ -893,6 +898,7 @@ void Tier::loadFromXml(const QDomElement &elem) } minGen = elem.attribute("minGen", "-1").toInt(); + allowIllegal = elem.attribute("allowIllegal", "false"); maxLevel = elem.attribute("maxLevel", "100").toInt(); numberOfPokemons = elem.attribute("numberOfPokemons", "6").toInt(); maxRestrictedPokes = elem.attribute("numberOfRestricted", "1").toInt(); @@ -990,6 +996,7 @@ QDomElement & Tier::toXml(QDomElement &dest) const { dest.setAttribute("gen", m_gen.num); dest.setAttribute("subgen", m_gen.subnum); dest.setAttribute("minGen", minGen); + dest.setAttribute("allowIllegal", allowIllegal); dest.setAttribute("maxLevel", maxLevel); dest.setAttribute("numberOfPokemons", numberOfPokemons); dest.setAttribute("numberOfRestricted", maxRestrictedPokes); @@ -1231,6 +1238,7 @@ Tier::Tier(TierMachine *boss, TierCategory *cat) : boss(boss), node(cat), holder parent = nullptr; m_gen = Pokemon::gen(GenInfo::GenMax(), GenInfo::NumberOfSubgens(GenInfo::GenMax())-1); minGen = -1; + allowIllegal = "false"; maxLevel = 100; numberOfPokemons = 6; maxRestrictedPokes = 1; @@ -1298,6 +1306,7 @@ Tier *Tier::dataClone() const t.maxLevel = maxLevel; t.m_gen = m_gen; t.minGen = minGen; + t.allowIllegal = allowIllegal; t.banParentS = banParentS; t.bannedItems = bannedItems; t.bannedMoves = bannedMoves; diff --git a/src/Server/tier.h b/src/Server/tier.h index d84b632001..0b968ed853 100644 --- a/src/Server/tier.h +++ b/src/Server/tier.h @@ -187,6 +187,7 @@ class Tier : public TierNode int maxLevel; Pokemon::gen m_gen; int minGen; + QString allowIllegal; QString banParentS; Tier *parent; QSet bannedItems; diff --git a/src/Shared/config.h b/src/Shared/config.h index 0be143e644..f0c7c7e903 100644 --- a/src/Shared/config.h +++ b/src/Shared/config.h @@ -3,11 +3,11 @@ #include -#define VERSION QString("2.5.2") +#define VERSION QString("2.6.0") static const quint16 PROTOCOL_VERSION = 3; static const quint16 PROTOCOL_SUBVERSION = 2; -static const quint16 CLIENT_VERSION_NUMBER = 2520; +static const quint16 CLIENT_VERSION_NUMBER = 2600; static const int UPDATE_ID = 4; #ifdef Q_OS_LINUX diff --git a/src/Teambuilder/Teambuilder/evbox.cpp b/src/Teambuilder/Teambuilder/evbox.cpp index f2015878a2..355ffc2cee 100644 --- a/src/Teambuilder/Teambuilder/evbox.cpp +++ b/src/Teambuilder/Teambuilder/evbox.cpp @@ -3,6 +3,7 @@ #include #include "evbox.h" #include "ui_evbox.h" +#include "Teambuilder/pokeedit.h" EvBox::EvBox(QWidget *parent) : QWidget(parent), @@ -15,7 +16,7 @@ EvBox::EvBox(QWidget *parent) : QLabel *labels[6] = {ui->hplabel, ui->atklabel, ui->deflabel, ui->satklabel, ui->sdeflabel, ui->speedlabel}; QLineEdit *edits[6] = {ui->hpedit, ui->atkedit, ui->defedit, ui->satkedit, ui->sdefedit, ui->speededit}; QImageButtonLR *boosts[6] = {ui->hpboost, ui->atkboost, ui->defboost, ui->satkboost, ui->sdefboost, ui->speedboost}; - + PokeEdit::hackMons ? ui->maxEVs->show() : ui->maxEVs->hide(); memcpy(m_sliders, sliders, sizeof(sliders)); memcpy(m_descs, descs, sizeof(descs)); memcpy(m_stats, labels, sizeof(labels)); @@ -34,6 +35,7 @@ EvBox::EvBox(QWidget *parent) : connect(m_boosts[i], SIGNAL(rightClick()), this, SLOT(changeToMinusBoost())); connect(m_boosts[i], SIGNAL(leftClick()), this, SLOT(changeToPlusBoost())); } + connect(ui->maxEVs, SIGNAL(clicked()), this, SLOT(maxEVs())); } void EvBox::updateNatureButtons() @@ -138,10 +140,10 @@ void EvBox::updateMain() ui->totallabel->setText(QString::number(poke().EVSum())); } -void EvBox::changeEV(int newValue) +void EvBox::changeEV(int newValue, int sentStat) { - int stat = sender()->property("stat").toInt(); - poke().setEV(stat, newValue/4*4); + int stat = sentStat == -1 ? sender()->property("stat").toInt() : sentStat; + poke().setEV(stat, newValue/4*4, PokeEdit::hackMons); updateEV(stat); updateMain(); } @@ -149,7 +151,7 @@ void EvBox::changeEV(int newValue) void EvBox::changeEV(const QString &newValue) { int stat = sender()->property("stat").toInt(); - poke().setEV(stat, std::max(std::min(newValue.toInt(), 252), 0)); + poke().setEV(stat, std::max(std::min(newValue.toInt(), 252), 0), PokeEdit::hackMons); updateEV(stat); updateMain(); } @@ -183,3 +185,16 @@ void EvBox::changeToMinusBoost() emit natureChanged(NatureInfo::NatureOf(plus,minus)); emit natureBoostChanged(); } + +void EvBox::changeMaximumEv(bool hack) +{ + ui->totalslider->setProperty(("maximum"), hack ? 1512 : 508); + hack ? ui->maxEVs->show() : ui->maxEVs->hide(); +} + +void EvBox::maxEVs() +{ + for (int i = 0; i < 6; i++) { + changeEV(252, i); + } +} diff --git a/src/Teambuilder/Teambuilder/evbox.h b/src/Teambuilder/Teambuilder/evbox.h index d7f532e0ee..c679d38f64 100644 --- a/src/Teambuilder/Teambuilder/evbox.h +++ b/src/Teambuilder/Teambuilder/evbox.h @@ -12,6 +12,7 @@ class QSlider; class QLabel; class QLineEdit; class QImageButtonLR; +class PokeEdit; class EvBox : public QWidget { @@ -21,7 +22,7 @@ class EvBox : public QWidget explicit EvBox(QWidget *parent = 0); void setPoke(PokeTeam *poke); void updateAll(); - + void changeMaximumEv(bool hack); ~EvBox(); signals: @@ -30,9 +31,10 @@ class EvBox : public QWidget private slots: void changeEV(const QString &newValue); - void changeEV(int newValue); + void changeEV(int newValue, int sentStat = -1); void changeToPlusBoost(); void changeToMinusBoost(); + void maxEVs(); public slots: void updateEVs(); diff --git a/src/Teambuilder/Teambuilder/evbox.ui b/src/Teambuilder/Teambuilder/evbox.ui index 906272c8f5..25bfc9ed52 100644 --- a/src/Teambuilder/Teambuilder/evbox.ui +++ b/src/Teambuilder/Teambuilder/evbox.ui @@ -35,55 +35,67 @@ 3 - - - - Hit Points: + + + + Qt::ClickFocus - - - - 0 + + + + Qt::ClickFocus - - + + - Qt::NoFocus + Qt::ClickFocus - - 252 + + + + + + Qt::ClickFocus - - 4 + + + + + + Qt::ClickFocus - - 40 + + + + + + false - - Qt::Horizontal + + Qt::ClickFocus - - + + - Attack: + 0 - - + + 0 - - + + Qt::NoFocus @@ -101,8 +113,15 @@ - - + + + + Special Defense: + + + + + 35 @@ -111,41 +130,51 @@ - - + + - Defense: + Speed: - - - - 0 + + + + + 35 + 16777215 + - - + + + + + 35 + 16777215 + + + + + + + + false + Qt::NoFocus - 252 - - - 4 - - - 40 + 508 Qt::Horizontal - - + + 35 @@ -154,20 +183,6 @@ - - - - Special Attack: - - - - - - - 0 - - - @@ -187,26 +202,19 @@ - - - - - 35 - 16777215 - - - - - - - - false - + + Qt::NoFocus - 508 + 252 + + + 4 + + + 40 Qt::Horizontal @@ -220,8 +228,29 @@ - - + + + + Attack: + + + + + + + Hit Points: + + + + + + + 0 + + + + + Qt::NoFocus @@ -239,46 +268,29 @@ - - - - - 35 - 16777215 - - - - - - - - 0 - - - - - + + - Special Defense: + Defense: - - + + - Speed: + 0 - - + + 0 - - + + Qt::NoFocus @@ -296,18 +308,8 @@ - - - - - 35 - 16777215 - - - - - - + + 35 @@ -316,48 +318,56 @@ - - + + - Qt::ClickFocus + Qt::NoFocus - - - - - - Qt::ClickFocus + + 252 + + + 4 + + + 40 + + + Qt::Horizontal - - - - Qt::ClickFocus + + + + 0 - - - - Qt::ClickFocus + + + + Special Attack: - - - - Qt::ClickFocus + + + + + 35 + 16777215 + - - + + - false + true - - Qt::ClickFocus + + Max EVs diff --git a/src/Teambuilder/Teambuilder/pokeedit.cpp b/src/Teambuilder/Teambuilder/pokeedit.cpp index 827af34601..bff27ea4b9 100644 --- a/src/Teambuilder/Teambuilder/pokeedit.cpp +++ b/src/Teambuilder/Teambuilder/pokeedit.cpp @@ -20,7 +20,7 @@ #include "teambuilder.h" bool PokeEdit::advancedWindowClosed = false; - +bool PokeEdit::hackMons = false; PokeEdit::PokeEdit(TeamBuilderWidget *master, PokeTeam *poke, QAbstractItemModel *pokeModel, QAbstractItemModel *itemsModel, QAbstractItemModel *natureModel) : ui(new Ui::PokeEdit), pokemonModel(pokeModel), @@ -73,11 +73,32 @@ PokeEdit::PokeEdit(TeamBuilderWidget *master, PokeTeam *poke, QAbstractItemModel /* 20 characters for the name. Longest name: Vivillon-Archipelago = 20 characters */ ui->nickname->setValidator(new QNickValidator(ui->nickname, 20)); - movesModel = new PokeMovesModel(poke->num(), poke->gen(), this); + fillMoves(); + connect(ui->levelSettings, SIGNAL(levelUpdated()), this, SLOT(updateStats())); + connect(ui->levelSettings, SIGNAL(levelUpdated()), ui->ivbox, SLOT(updateStats())); + connect(ui->levelSettings, SIGNAL(genderUpdated()), this, SLOT(updatePicture())); + connect(ui->levelSettings, SIGNAL(genderUpdated()), this, SLOT(updateGender())); + connect(ui->ivbox, SIGNAL(genderUpdated()), SLOT(updateGender())); + connect(ui->ivbox, SIGNAL(genderUpdated()), ui->levelSettings, SLOT(updateGender())); + connect(ui->ivbox, SIGNAL(shinyUpdated()), SLOT(updatePicture())); + connect(ui->happiness, SIGNAL(valueChanged(int)), this, SLOT(changeHappiness(int))); + connect(ui->nature, SIGNAL(currentIndexChanged(int)), this, SLOT(changeNature(int))); + connect(ui->item, SIGNAL(currentIndexChanged(QString)), this, SLOT(changeItem(QString))); + connect(ui->evbox, SIGNAL(natureChanged(int)), this, SLOT(setNature(int))); + connect(ui->evbox, SIGNAL(natureBoostChanged()), ui->ivbox, SLOT(updateStats())); + connect(ui->ivbox, SIGNAL(statsUpdated()), ui->evbox, SLOT(updateEVs())); + + updateAll(); +} + +void PokeEdit::fillMoves() +{ + movesModel = new PokeMovesModel(m_poke->num(), m_poke->gen(), this, hackMons); QSortFilterProxyModel *filter = new QSortFilterProxyModel(this); filter->setSourceModel(movesModel); ui->moveChoice->setModel(filter); - + ui->moveChoice->disconnect(SIGNAL(activated(QModelIndex)), this); + connect(ui->moveChoice, SIGNAL(activated(QModelIndex)), SLOT(moveEntered(QModelIndex))); #ifdef QT5 ui->moveChoice->horizontalHeader()->setSectionResizeMode(PokeMovesModel::PP, QHeaderView::ResizeToContents); ui->moveChoice->horizontalHeader()->setSectionResizeMode(PokeMovesModel::Priority, QHeaderView::ResizeToContents); @@ -95,16 +116,12 @@ PokeEdit::PokeEdit(TeamBuilderWidget *master, PokeTeam *poke, QAbstractItemModel ui->moveChoice->setIconSize(Theme::TypePicture(Type::Normal).size()); ui->moveChoice->sortByColumn(PokeMovesModel::Name, Qt::AscendingOrder); - m_moves[0] = ui->move1; m_moves[1] = ui->move2; m_moves[2] = ui->move3; m_moves[3] = ui->move4; - connect(ui->speciesLabel, SIGNAL(clicked()), SLOT(on_pokemonFrame_clicked())); - connect(ui->moveChoice, SIGNAL(activated(QModelIndex)), SLOT(moveEntered(QModelIndex))); - /* the four move choice items */ for (int i = 0; i < 4; i++) { @@ -118,27 +135,10 @@ PokeEdit::PokeEdit(TeamBuilderWidget *master, PokeTeam *poke, QAbstractItemModel completer->setProperty("move", i); m_moves[i]->setProperty("move", i); - connect(completer, SIGNAL(activated(QString)), SLOT(changeMove())); connect(m_moves[i], SIGNAL(returnPressed()), SLOT(changeMove())); connect(m_moves[i], SIGNAL(editingFinished()), SLOT(changeMove())); } - - connect(ui->levelSettings, SIGNAL(levelUpdated()), this, SLOT(updateStats())); - connect(ui->levelSettings, SIGNAL(levelUpdated()), ui->ivbox, SLOT(updateStats())); - connect(ui->levelSettings, SIGNAL(genderUpdated()), this, SLOT(updatePicture())); - connect(ui->levelSettings, SIGNAL(genderUpdated()), this, SLOT(updateGender())); - connect(ui->ivbox, SIGNAL(genderUpdated()), SLOT(updateGender())); - connect(ui->ivbox, SIGNAL(genderUpdated()), ui->levelSettings, SLOT(updateGender())); - connect(ui->ivbox, SIGNAL(shinyUpdated()), SLOT(updatePicture())); - connect(ui->happiness, SIGNAL(valueChanged(int)), this, SLOT(changeHappiness(int))); - connect(ui->nature, SIGNAL(currentIndexChanged(int)), this, SLOT(changeNature(int))); - connect(ui->item, SIGNAL(currentIndexChanged(QString)), this, SLOT(changeItem(QString))); - connect(ui->evbox, SIGNAL(natureChanged(int)), this, SLOT(setNature(int))); - connect(ui->evbox, SIGNAL(natureBoostChanged()), ui->ivbox, SLOT(updateStats())); - connect(ui->ivbox, SIGNAL(statsUpdated()), ui->evbox, SLOT(updateEVs())); - - updateAll(); } void PokeEdit::closeAdvancedTab() @@ -151,6 +151,18 @@ void PokeEdit::showAdvancedTab() findChild("AdvancedTab")->show(); } +void PokeEdit::toggleHackmons() +{ + fillMoves(); + ui->levelSettings->fillAbilities(); + ui->levelSettings->updateAll(); + ui->evbox->changeMaximumEv(hackMons); + if (!PokeEdit::hackMons) { + poke().runCheck(); + ui->evbox->updateAll(); + } +} + void PokeEdit::openPokemonSelection() { on_pokemonFrame_clicked(); @@ -213,7 +225,7 @@ void PokeEdit::changeMove() void PokeEdit::setMove(int slot, int move) { try { - poke().setMove(move, slot, true); + poke().setMove(move, slot, !hackMons); m_moves[slot]->setText(MoveInfo::Name(move)); if (move == Move::Return) { @@ -415,7 +427,7 @@ void PokeEdit::setNum(Pokemon::uniqueId num) poke().item() = ItemInfo::PlateForType(num.subnum); } else if (num.pokenum == Pokemon::Genesect && ItemInfo::DriveForme(poke().item()) != num.subnum) { poke().item() = ItemInfo::DriveForForme(num.subnum); - } else if (PokemonInfo::IsMegaEvo(num)) { + } else if (PokemonInfo::IsMegaEvo(num) && !PokeEdit::hackMons) { poke().item() = ItemInfo::StoneForForme(num); /*Override using the mega until there's a better solution.*/ num = Pokemon::uniqueId(num.pokenum, 0); @@ -424,14 +436,14 @@ void PokeEdit::setNum(Pokemon::uniqueId num) poke().setNum(num); poke().load(); - if (PokemonInfo::IsMegaEvo(num)) { + if (PokemonInfo::IsMegaEvo(num) && !PokeEdit::hackMons) { poke().nickname() = PokemonInfo::Name(Pokemon::uniqueId(num.pokenum, 0)); } else { poke().nickname() = PokemonInfo::Name(num); } if (sameForme) { - poke().runCheck(); + poke().runCheck(PokeEdit::hackMons); } emit numChanged(); @@ -469,7 +481,7 @@ void PokeEdit::changeItem(const QString &itemName) setNum(Pokemon::uniqueId(poke().num().pokenum, subnum)); } if (itemNum != ItemInfo::StoneForForme(poke().num())) { - if (PokemonInfo::IsMegaEvo(poke().num())) { + if (PokemonInfo::IsMegaEvo(poke().num()) && !PokeEdit::hackMons) { setNum(Pokemon::uniqueId(poke().num().pokenum,0)); } } diff --git a/src/Teambuilder/Teambuilder/pokeedit.h b/src/Teambuilder/Teambuilder/pokeedit.h index 03a6cb1f81..d183fef4e1 100644 --- a/src/Teambuilder/Teambuilder/pokeedit.h +++ b/src/Teambuilder/Teambuilder/pokeedit.h @@ -34,6 +34,7 @@ class PokeEdit : public QWidget }; static bool advancedWindowClosed; + static bool hackMons; public slots: void updateStats(); @@ -52,6 +53,8 @@ public slots: void setNum(const QString &num); void setItem(int num); void openPokemonSelection(); + void toggleHackmons(); + void fillMoves(); signals: void numChanged(); void nameChanged(); diff --git a/src/Teambuilder/Teambuilder/pokelevelsettings.cpp b/src/Teambuilder/Teambuilder/pokelevelsettings.cpp index c46cfccee2..6adfc9fbd3 100644 --- a/src/Teambuilder/Teambuilder/pokelevelsettings.cpp +++ b/src/Teambuilder/Teambuilder/pokelevelsettings.cpp @@ -1,8 +1,10 @@ #include +#include #include #include #include "Teambuilder/pokelevelsettings.h" +#include "Teambuilder/pokeedit.h" #include "ui_pokelevelsettings.h" PokeLevelSettings::PokeLevelSettings(QWidget *parent) : @@ -10,14 +12,6 @@ PokeLevelSettings::PokeLevelSettings(QWidget *parent) : ui(new Ui::PokeLevelSettings) { ui->setupUi(this); - m_abilities[0] = ui->ability1; - m_abilities[1] = ui->ability2; - m_abilities[2] = ui->ability3; - - QButtonGroup *abilityGroup = new QButtonGroup(this); - for (int i =0; i < 3; i++) { - abilityGroup->addButton(m_abilities[i]); - } QButtonGroup *genderGroup = new QButtonGroup(this); genderGroup->addButton(ui->maleButton); genderGroup->addButton(ui->femaleButton); @@ -30,9 +24,6 @@ PokeLevelSettings::PokeLevelSettings(QWidget *parent) : // female if it is. //connect(ui->femaleButton, SIGNAL(toggled(bool)), this, SLOT(changeGender())); - for (int i = 0; i < 3; i++) { - connect(m_abilities[i], SIGNAL(toggled(bool)), this, SLOT(changeAbility())); - } } PokeLevelSettings::~PokeLevelSettings() @@ -40,10 +31,53 @@ PokeLevelSettings::~PokeLevelSettings() delete ui; } +void PokeLevelSettings::fillAbilities() +{ + if (!PokeEdit::hackMons) { + ui->ability->hide(); + ui->ability1->show(); + ui->ability2->show(); + ui->ability3->show(); + m_abilities[0] = ui->ability1; + m_abilities[1] = ui->ability2; + m_abilities[2] = ui->ability3; + + QButtonGroup *abilityGroup = new QButtonGroup(this); + for (int i =0; i < 3; i++) { + abilityGroup->addButton(m_abilities[i]); + } + for (int i = 0; i < 3; i++) { + m_abilities[i]->disconnect(SIGNAL(toggled(bool)), this); + connect(m_abilities[i], SIGNAL(toggled(bool)), this, SLOT(changeAbility())); + } + } else { + ui->ability1->hide(); + ui->ability2->hide(); + ui->ability3->hide(); + QStringList abilities; + for (int i = 1; i < AbilityInfo::NumberOfAbilities(poke().gen().num); i++) { + abilities.push_back(AbilityInfo::Name(i)); + } + qSort(abilities); + abilities.removeAll(""); + QString ability = AbilityInfo::Name(poke().ability()); + ui->ability->setModel(new QStringListModel(abilities, this)); + ui->ability->show(); + ui->ability->disconnect(SIGNAL(currentIndexChanged(int)), this); + connect(ui->ability, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAbility())); + int index = ui->ability->findText(ability); + if (index != -1) { + ui->ability->setCurrentIndex(index); + } + } +} + void PokeLevelSettings::setPoke(PokeTeam *poke) { m_poke = poke; + fillAbilities(); setGender(); + updateAll(); } void PokeLevelSettings::updateAll() @@ -87,16 +121,19 @@ void PokeLevelSettings::changeAbility() } int abilityToSet; - if (m_abilities[1]->isChecked()) { - abilityToSet = poke().abilities().ab(1); - } else if (m_abilities[2]->isChecked()) { - abilityToSet = poke().abilities().ab(2); + if (!PokeEdit::hackMons) { + if (m_abilities[1]->isChecked()) { + abilityToSet = poke().abilities().ab(1); + } else if (m_abilities[2]->isChecked()) { + abilityToSet = poke().abilities().ab(2); + } else { + abilityToSet = poke().abilities().ab(0); + } } else { - abilityToSet = poke().abilities().ab(0); + abilityToSet = AbilityInfo::Number(ui->ability->currentText()); } - try { - poke().setAbility(abilityToSet); + poke().setAbility(abilityToSet, PokeEdit::hackMons); } catch (const QString &s) { QMessageBox::information(NULL, tr("Invalid moveset"), s); for(int i = 0; i < 3; i++) { @@ -111,17 +148,25 @@ void PokeLevelSettings::changeAbility() void PokeLevelSettings::setAbilities() { - for(int i = 0; i < 3; i++) { - if(poke().abilities().ab(i) != 0 && poke().gen() >= 3 && (i == 0 || poke().abilities().ab(i) != poke().abilities().ab(0))) { - m_abilities[i]->setVisible(true); - m_abilities[i]->setText(AbilityInfo::Name(poke().abilities().ab(i))); - m_abilities[i]->setToolTip(AbilityInfo::Desc(poke().abilities().ab(i))); + if (!PokeEdit::hackMons) { + for(int i = 0; i < 3; i++) { + if(poke().abilities().ab(i) != 0 && poke().gen() >= 3 && (i == 0 || poke().abilities().ab(i) != poke().abilities().ab(0))) { + m_abilities[i]->setVisible(true); + m_abilities[i]->setText(AbilityInfo::Name(poke().abilities().ab(i))); + m_abilities[i]->setToolTip(AbilityInfo::Desc(poke().abilities().ab(i))); - if (poke().abilities().ab(i) == poke().ability()) { - m_abilities[i]->setChecked(true); + if (poke().abilities().ab(i) == poke().ability()) { + m_abilities[i]->setChecked(true); + } + } else { + m_abilities[i]->setVisible(false); } - } else { - m_abilities[i]->setVisible(false); + } + } else { + ui->ability->setVisible(true); + int index = ui->ability->findText(AbilityInfo::Name(poke().ability())); + if (index != -1) { + ui->ability->setCurrentIndex(index); } } } @@ -179,12 +224,20 @@ void PokeLevelSettings::updateAbility() if (poke().gen() < 3) { return; } - if (poke().ability() == poke().abilities().ab(0)) { - m_abilities[0]->setChecked(true); - } else if (poke().ability() == poke().abilities().ab(1)) { - m_abilities[1]->setChecked(true); - } else if (poke().ability() == poke().abilities().ab(2)) { - m_abilities[2]->setChecked(true); + if (!PokeEdit::hackMons) { + if (poke().ability() == poke().abilities().ab(0)) { + m_abilities[0]->setChecked(true); + } else if (poke().ability() == poke().abilities().ab(1)) { + m_abilities[1]->setChecked(true); + } else if (poke().ability() == poke().abilities().ab(2)) { + m_abilities[2]->setChecked(true); + } + } else { + ui->ability->setVisible(true); + int index = ui->ability->findText(AbilityInfo::Name(poke().ability())); + if (index != -1) { + ui->ability->setCurrentIndex(index); + } } } diff --git a/src/Teambuilder/Teambuilder/pokelevelsettings.h b/src/Teambuilder/Teambuilder/pokelevelsettings.h index 8dce6b107f..ad92b34705 100644 --- a/src/Teambuilder/Teambuilder/pokelevelsettings.h +++ b/src/Teambuilder/Teambuilder/pokelevelsettings.h @@ -8,7 +8,7 @@ class QRadioButton; namespace Ui { class PokeLevelSettings; } - +class PokeEdit; class PokeTeam; class PokeLevelSettings : public QFrame @@ -21,6 +21,7 @@ class PokeLevelSettings : public QFrame void setPoke(PokeTeam *poke); void updateAll(); + void fillAbilities(); signals: void levelUpdated(); diff --git a/src/Teambuilder/Teambuilder/pokelevelsettings.ui b/src/Teambuilder/Teambuilder/pokelevelsettings.ui index 819dc9efb0..ad573587fc 100644 --- a/src/Teambuilder/Teambuilder/pokelevelsettings.ui +++ b/src/Teambuilder/Teambuilder/pokelevelsettings.ui @@ -136,6 +136,9 @@ + + + diff --git a/src/Teambuilder/Teambuilder/teambuilder.cpp b/src/Teambuilder/Teambuilder/teambuilder.cpp index 2b8dc34e17..ba06355ae2 100644 --- a/src/Teambuilder/Teambuilder/teambuilder.cpp +++ b/src/Teambuilder/Teambuilder/teambuilder.cpp @@ -180,7 +180,10 @@ void TeamBuilder::genChanged() for (int i = 0; i < 6; i++) { team().team().poke(i).load(); - team().team().poke(i).runCheck(); + if (team().team().hackMons() == "false" || team().team().poke(i).isLegal()) { + team().team().poke(i).illegal() = false; + team().team().poke(i).runCheck(); + } } markAllUpdated(); @@ -561,3 +564,4 @@ void TeamBuilder::setTierList(const QStringList &tiers) { trainer->setTiers(tiers); } + diff --git a/src/Teambuilder/Teambuilder/teammenu.cpp b/src/Teambuilder/Teambuilder/teammenu.cpp index ed99af7829..327cbce494 100644 --- a/src/Teambuilder/Teambuilder/teammenu.cpp +++ b/src/Teambuilder/Teambuilder/teammenu.cpp @@ -24,7 +24,7 @@ TeamMenu::TeamMenu(TeamBuilder *tb, QAbstractItemModel *pokeModel, TeamHolder *t { setMainWindow(tb); setTeambuilder(tb); - + PokeEdit::hackMons = team->team().hackMons() == "true"; ui->pokemonModel = pokeModel; setupUi(); updateTabs(); @@ -51,8 +51,11 @@ void TeamMenu::addMenus(QMenuBar *b) QAction *adv = options->addAction(tr("&Advanced menu"), this, SLOT(toggleAdvanced())); adv->setCheckable(true); adv->setChecked(!PokeEdit::advancedWindowClosed); - + QAction *hackmons = options->addAction(tr("&Show Illegal"), this, SLOT(toggleHackmons())); + hackmons->setCheckable(true); + hackmons->setChecked(PokeEdit::hackMons); advancedMenu = adv; + hackMons = hackmons; } void TeamMenu::setupUi() @@ -167,6 +170,16 @@ void TeamMenu::toggleAdvanced() } } +void TeamMenu::toggleHackmons() +{ + PokeEdit::hackMons = !PokeEdit::hackMons; + foreach(PokeEdit *p, ui->pokemons) { + p->toggleHackmons(); + } + hackMons->setChecked(PokeEdit::hackMons); + team().team().setIllegal(PokeEdit::hackMons); +} + void TeamMenu::tabIconChanged() { int slot = sender()->property("slot").toInt(); diff --git a/src/Teambuilder/Teambuilder/teammenu.h b/src/Teambuilder/Teambuilder/teammenu.h index 1eec38a304..707befc53d 100644 --- a/src/Teambuilder/Teambuilder/teammenu.h +++ b/src/Teambuilder/Teambuilder/teammenu.h @@ -32,6 +32,7 @@ public slots: /* Close the advanced tab */ void toggleAdvanced(); void closeAdvanced(); + void toggleHackmons(); /* Called from boxes, when team is changed */ void updatePokemons(); private slots: @@ -57,6 +58,7 @@ private slots: TeamHolder *m_team; QPointer advancedMenu; + QPointer hackMons; Pokemon::gen lastGen; TeamHolder &team() { return *m_team;} const TeamHolder &team() const { return *m_team;} diff --git a/src/Teambuilder/Teambuilder/trainermenu.cpp b/src/Teambuilder/Teambuilder/trainermenu.cpp index 2f77a1de6a..f031d0b76b 100644 --- a/src/Teambuilder/Teambuilder/trainermenu.cpp +++ b/src/Teambuilder/Teambuilder/trainermenu.cpp @@ -101,7 +101,7 @@ void TrainerMenu::on_importTeam_clicked() void TrainerMenu::importTeam(const QString &team) { - this->team().team().importFromTxt(team); + this->team().team().importFromTxt(team, this->team().team().hackMons() == "true"); } void TrainerMenu::openImportAndroidDialog() diff --git a/src/Teambuilder/Teambuilder/trainermenu.h b/src/Teambuilder/Teambuilder/trainermenu.h index 723b1dab5c..f00b3d31ae 100644 --- a/src/Teambuilder/Teambuilder/trainermenu.h +++ b/src/Teambuilder/Teambuilder/trainermenu.h @@ -57,7 +57,6 @@ private slots: void on_saveTeam_clicked(); void on_loadTeam_clicked(); void on_importTeam_clicked(); - void on_importAndroidTeam_clicked(); void on_teamFolderButton_clicked(); void on_profileList_currentIndexChanged(int); void on_newProfile_clicked(); @@ -71,6 +70,7 @@ private slots: void setColor(); void loadProfileList(); void updateButtonName(); + void on_importAndroidTeam_clicked(); Ui::TrainerMenu *ui; QPushButton *teamButtons[6]; diff --git a/src/libraries/PokemonInfo/battlestructs.cpp b/src/libraries/PokemonInfo/battlestructs.cpp index 43daa27dcc..039ba65ab6 100644 --- a/src/libraries/PokemonInfo/battlestructs.cpp +++ b/src/libraries/PokemonInfo/battlestructs.cpp @@ -128,7 +128,8 @@ void PokeBattle::setNormalStat(int stat, quint16 i) void PokeBattle::init(PokePersonal &poke) { /* Checks num, ability, moves, item */ - poke.runCheck(); + poke.runCheck(poke.illegal()); + illegal() = poke.illegal(); num() = poke.num(); @@ -197,7 +198,7 @@ void PokeBattle::init(PokePersonal &poke) QSet taken_moves; for (int i = 0; i < 4; i++) { - if (!taken_moves.contains(poke.move(i)) && poke.move(i) != 0) { + if (!taken_moves.contains(poke.move(i) || poke.illegal()) && poke.move(i) != 0) { taken_moves.insert(poke.move(i)); move(curs).num() = poke.move(i); move(curs).load(poke.gen()); @@ -242,7 +243,7 @@ void PokeBattle::init(PokePersonal &poke) //Arceus if (PokemonInfo::OriginalForme(num()) == Pokemon::Arceus && evs()[i] > 100 && p.gen() < 5) evs()[i] = 100; sum += evs()[i]; - if (sum > 510) { + if (sum > 510 && !poke.illegal()) { evs()[i] -= (sum-510); sum = 510; } @@ -287,7 +288,6 @@ DataStream & operator >> (DataStream &in, PokeBattle &po) for (int i = 0; i < 6; i++) { in >> po.dvs()[i]; } - return in; } @@ -314,7 +314,6 @@ DataStream & operator << (DataStream &out, const PokeBattle &po) for (int i = 0; i < 6; i++) { out << po.dvs()[i]; } - return out; } @@ -339,6 +338,7 @@ void ShallowBattlePoke::init(const PokeBattle &poke) fullStatus() = poke.fullStatus(); num() = poke.num(); shiny() = poke.shiny(); + illegal() = poke.illegal(); gender() = poke.gender(); setLifePercent( (poke.lifePoints() * 100) / poke.totalLifePoints() ); if (lifePercent() == 0 && poke.lifePoints() > 0) { diff --git a/src/libraries/PokemonInfo/battlestructs.h b/src/libraries/PokemonInfo/battlestructs.h index 6ad0970ab4..132ac40690 100644 --- a/src/libraries/PokemonInfo/battlestructs.h +++ b/src/libraries/PokemonInfo/battlestructs.h @@ -43,6 +43,7 @@ class ShallowBattlePoke PROPERTY(quint8, gender) PROPERTY(quint8, level) PROPERTY(quint16, ability) + PROPERTY(bool, illegal) public: ShallowBattlePoke(); ShallowBattlePoke(const PokeBattle &poke); diff --git a/src/libraries/PokemonInfo/pokemonstructs.cpp b/src/libraries/PokemonInfo/pokemonstructs.cpp index 97763ef6c5..ba6963f68f 100644 --- a/src/libraries/PokemonInfo/pokemonstructs.cpp +++ b/src/libraries/PokemonInfo/pokemonstructs.cpp @@ -186,10 +186,14 @@ void PokePersonal::setMove(int moveNum, int moveSlot, bool check) throw(QString) } } -void PokePersonal::setAbility(int abilityNum) throw(QString) +void PokePersonal::setAbility(int abilityNum, bool hack) throw(QString) { QSet invalid_moves; QString error; + if (hack) { + ability() = abilityNum; + return; + } if (!MoveSetChecker::isValid(num(), gen(), m_moves[0],m_moves[1],m_moves[2],m_moves[3],abilityNum,gender(),level(),false,&invalid_moves, &error)) { throw error; } else { @@ -197,13 +201,50 @@ void PokePersonal::setAbility(int abilityNum) throw(QString) } } -void PokePersonal::runCheck() +//this function simply returns true/false depending on the legality of the pokemon, instead of changing it +bool PokePersonal::isLegal() const +{ + if (!PokemonInfo::Exists(num(), gen())) { + return false; + } + if (PokemonInfo::IsForme(num()) && !PokemonInfo::AFormesShown(num())) { + return false; + } + if (gen() > 2) { + AbilityGroup ab = PokemonInfo::Abilities(num(), gen()); + if (ability() == 0 || (ability() != ab.ab(2) && ability() != ab.ab(1) && ability() != ab.ab(0))) { + return false; + } + } + if (gen() > 2 && EVSum() > 510) { + return false; + } + QSet invalidMoves; + + MoveSetChecker::isValid(num(), gen(), move(0), move(1), move(2), move(3), ability(), gender(), level(), false, &invalidMoves); + + while (invalidMoves.size() > 0) { + for (int i = 0; i < 4; i++) { + if (invalidMoves.contains(move(i))) { + return false; + } + } + invalidMoves.clear(); + + MoveSetChecker::isValid(num(), gen(), move(0), move(1), move(2), move(3), ability(), gender(), level(), false, &invalidMoves); + } + return true; +} + +void PokePersonal::runCheck(bool hack) { if (!PokemonInfo::Exists(num(), gen())) { reset(); return; } - + if (hack) { + return; + } if (!PokemonInfo::AFormesShown(num())) { num() = num().original(); } @@ -326,8 +367,12 @@ void PokePersonal::controlEVs(int stat) } } -void PokePersonal::setEV(int stat, quint8 val) +void PokePersonal::setEV(int stat, quint8 val, bool hack) { + if (hack) { + m_EVs[stat] = val; + return; + } if (PokemonInfo::OriginalForme(num()) == Pokemon::Arceus && gen() < 5 && val > 100) { val = 100; @@ -532,11 +577,11 @@ void PokeTeam::setGen(Pokemon::gen gen) PokeGraphics::setGen(gen); } -void PokeTeam::runCheck() +void PokeTeam::runCheck(bool hack) { Pokemon::uniqueId num = this->num(); - PokePersonal::runCheck(); + PokePersonal::runCheck(hack); /* If the pokemon is reset to 0, we also make PokeGeneral and PokeGraphics reset */ if (num != PokePersonal::num()) { @@ -691,6 +736,7 @@ void Team::toXml(QDomDocument &document) const Team.setAttribute("gen", gen().num); Team.setAttribute("subgen", gen().subnum); Team.setAttribute("defaultTier", defaultTier()); + Team.setAttribute("hackMons", hackMons()); Team.setAttribute("version", 1); document.appendChild(Team); @@ -770,7 +816,7 @@ void loadTTeamDialog(Team &team, QObject *receiver, const char *slot) QObject::connect(f, SIGNAL(fileSelected(QString)), receiver, slot); } -void PokeTeam::loadFromXml(const QDomElement &poke, int version) +void PokeTeam::loadFromXml(const QDomElement &poke, int version, bool hack) { if (poke.hasAttribute("Gen")) { setGen(Pokemon::gen(poke.attribute("Gen", QString::number(GenInfo::GenMax())).toInt(), @@ -813,7 +859,6 @@ void PokeTeam::loadFromXml(const QDomElement &poke, int version) shiny() = QVariant(poke.attribute("Shiny")).toBool(); happiness() = poke.attribute("Happiness").toInt(); level() = poke.attribute("Lvl").toInt(); - int cptMove=0; QDomElement moveElement = poke.firstChildElement("Move"); @@ -839,10 +884,11 @@ void PokeTeam::loadFromXml(const QDomElement &poke, int version) QDomElement EVElement = poke.firstChildElement("EV"); while(!EVElement.isNull()) { - setEV(outdated ? NatureInfo::ConvertToStat(cptEV) : cptEV,EVElement.text().toInt()); + setEV(outdated ? NatureInfo::ConvertToStat(cptEV) : cptEV,EVElement.text().toInt(), hack); cptEV++; EVElement = EVElement.nextSiblingElement("EV"); } + illegal() = hack; } Pokemon::gen PokeTeam::gen() const @@ -886,12 +932,12 @@ bool Team::loadFromFile(const QString &path) setGen(Pokemon::gen(team.attribute("gen", QString::number(GenInfo::GenMax())).toInt(), team.attribute("subgen", QString::number(GenInfo::NumberOfSubgens(team.attribute("gen", QString::number(GenInfo::GenMax())).toInt())-1)).toInt())); defaultTier() = team.attribute("defaultTier"); - + hackMons() = team.attribute("hackMons", "false"); QDomElement poke = team.firstChildElement("Pokemon"); int cpt = 0; while(!poke.isNull()) { - this->poke(cpt).loadFromXml(poke, version); + this->poke(cpt).loadFromXml(poke, version, hackMons() == "true"); cpt++; poke = poke.nextSiblingElement("Pokemon"); @@ -900,7 +946,7 @@ bool Team::loadFromFile(const QString &path) } /******** Really ugly *********/ -bool Team::importFromTxt(const QString &file1) +bool Team::importFromTxt(const QString &file1, bool hack) { QString file = file1; file.replace("---", ""); @@ -964,7 +1010,19 @@ bool Team::importFromTxt(const QString &file1) if (pokestring.indexOf('-') != -1 && pokestring.indexOf('-') <= pokestring.length() - 2) { pokestring[pokestring.indexOf('-')+1] = pokestring[pokestring.indexOf('-')+1].toUpper(); } - + //PS mega imports + if (pokestring.indexOf("-") != -1) { + int index = pokestring.indexOf("-"); + QString forme = pokestring.mid(index+1); + if (forme.indexOf("Mega") != -1) { + pokestring = pokestring.mid(0, index); + if (forme.indexOf("-") != -1) {//Mega charizard/mewtwo + pokestring = "Mega " + pokestring + " " + forme.mid(forme.indexOf("-")+1); + } else { + pokestring = "Mega " + pokestring; + } + } + } pokenum = PokemonInfo::Number(pokestring); int item = 0; @@ -1032,7 +1090,7 @@ bool Team::importFromTxt(const QString &file1) stat = Hp; if (key == "EVs") { - p.setEV(stat, unsigned(evnum)%255); + p.setEV(stat, unsigned(evnum)%255, hack); } else { p.setDV(stat, unsigned(evnum)%32); } @@ -1070,8 +1128,8 @@ bool Team::importFromTxt(const QString &file1) } } - /* Removes invalid move combinations */ - p.runCheck(); + /* Checks if hackmons are valid, if yes, fix them up in the checker */ + p.runCheck(!hack || p.isLegal()); } return true; /* @@ -1228,7 +1286,7 @@ bool Team::importFromAndroid(const QString &file2) QStringList settings = teamsettings.split("@"); Team::defaultTier() = settings[0]; - + Team::hackMons() = "false"; QStringList pokes = file.split("***",QString::SkipEmptyParts); for (int i = 0; i < 6 && i < pokes.size(); i++) { PokeTeam &p = this->poke(i); @@ -1375,6 +1433,19 @@ void Team::setFolder(const QString &folder) m_path = folder + "/" + QUrl::toPercentEncoding(name()) + ".tp"; } +void Team::setIllegal(bool hack) +{ + for(int i = 0; i < 6; i++) { + if (hack && !poke(i).isLegal()) { + poke(i).illegal() = true; + } else { + poke(i).illegal() = false; + poke(i).runCheck(); + } + } + hackMons() = hack ? "true" : "false"; +} + void Team::sanityCheck() { if (defaultTier().length() > 100) { @@ -1401,7 +1472,6 @@ DataStream & operator << (DataStream & out, const Team & team) } v.stream << team.gen(); - for (int i = 0; i < 6; i++) { v.stream << team.poke(i); } @@ -1428,14 +1498,16 @@ DataStream & operator << (DataStream & out, const PokePersonal & p) break; } } - v.stream << network; v.stream << p.num(); v.stream << p.level(); Flags data; data.setFlag(pp::isShiny, p.shiny()); - + //make sure the poke is 100% illegal + if (p.illegal() && !p.isLegal() && p.num() != 0) { + data.setFlag(pp::isIllegal, p.illegal()); + } v.stream << data; if (p.nickname().length() > 0) { @@ -1496,7 +1568,7 @@ DataStream & operator >> (DataStream & in, PokePersonal & p) v.stream >> p.num() >> p.level() >> data; p.shiny() = data[pp::isShiny]; - + bool hack = data[pp::isIllegal]; if (network[pp::hasNickname]) { v.stream >> p.nickname(); } @@ -1525,14 +1597,14 @@ DataStream & operator >> (DataStream & in, PokePersonal & p) } quint16 moveNum; v.stream >> moveNum; - p.setMove(moveNum,i); + p.setMove(moveNum,i, false); } for(int i=0;i<6;i++) { quint8 EV; v.stream >> EV; - p.setEV(i,EV); + p.setEV(i,EV,hack); } if (network[pp::hasIVs]) { @@ -1543,6 +1615,6 @@ DataStream & operator >> (DataStream & in, PokePersonal & p) p.setDV(i,IV); } } - + p.illegal() = hack; return in; } diff --git a/src/libraries/PokemonInfo/pokemonstructs.h b/src/libraries/PokemonInfo/pokemonstructs.h index 2ce15b20eb..a0d03681e9 100644 --- a/src/libraries/PokemonInfo/pokemonstructs.h +++ b/src/libraries/PokemonInfo/pokemonstructs.h @@ -100,6 +100,7 @@ class PokePersonal PROPERTY(quint8, happiness) PROPERTY(quint8, level) PROPERTY(Pokemon::gen, gen) + PROPERTY(bool, illegal) protected: quint16 m_moves[4]; @@ -117,15 +118,15 @@ class PokePersonal /* resets everything to default values */ void reset(); /* Removes / Reset things if they are wrong */ - void runCheck(); - + void runCheck(bool hack = false); + bool isLegal() const; void setMove(int moveNum, int moveSlot, bool check=false) throw (QString); int addMove(int moveNum, bool check = false) throw (QString); void removeMove(int movenum); bool hasMove(int moveNum); - void setAbility(int abilityNum) throw (QString); + void setAbility(int abilityNum, bool hack) throw (QString); quint8 DV(int stat) const; void setDV(int stat, quint8 DV); @@ -136,11 +137,11 @@ class PokePersonal quint8 EV(int stat) const; int EVSum() const; - void setEV(int stat, quint8 EV); + void setEV(int stat, quint8 EV, bool hack = false); enum Flags { hasGen, hasNickname, hasPokeball, hasHappiness, hasPPups, hasIVs, - isShiny=0 + isShiny=0, isIllegal }; }; @@ -187,7 +188,7 @@ class PokeTeam : virtual public PokeGeneral, virtual public PokePersonal, virtua void setNum(Pokemon::uniqueId num); void setGen(Pokemon::gen gen); Pokemon::gen gen() const; - void runCheck(); + void runCheck(bool hack = false); int stat(int statno) const; @@ -199,7 +200,7 @@ class PokeTeam : virtual public PokeGeneral, virtual public PokePersonal, virtua QPixmap picture(); QIcon icon(); - void loadFromXml(const QDomElement &el, int version); + void loadFromXml(const QDomElement &el, int version, bool hack = false); QDomElement & toXml(QDomElement &dest) const; void sanityCheck(); @@ -208,6 +209,7 @@ class PokeTeam : virtual public PokeGeneral, virtual public PokePersonal, virtua class Team { PROPERTY(QString, defaultTier) + PROPERTY(QString, hackMons) protected: PokeTeam m_pokes[6]; Pokemon::gen m_gen; @@ -224,7 +226,7 @@ class Team void toXml(QDomDocument &doc) const; QString toXml() const; bool saveToFile(const QString &path) const; - bool importFromTxt(const QString &path); + bool importFromTxt(const QString &path, bool hack = false); bool importFromAndroid(const QString &path); QString exportToTxt() const; QString exportToAndroid() const; @@ -234,7 +236,7 @@ class Team QString path() const {return m_path;} void setName(const QString &name); void setFolder(const QString &folder); - + void setIllegal(bool hack); /* Runs some check to validate a team better, and edits invalid values */ void sanityCheck(); private: diff --git a/src/libraries/TeambuilderLibrary/pokemovesmodel.cpp b/src/libraries/TeambuilderLibrary/pokemovesmodel.cpp index 15a901290b..c398b554bb 100644 --- a/src/libraries/TeambuilderLibrary/pokemovesmodel.cpp +++ b/src/libraries/TeambuilderLibrary/pokemovesmodel.cpp @@ -13,28 +13,35 @@ QHash map_container_with_value(T container, const U & return ret; } -PokeMovesModel::PokeMovesModel(const Pokemon::uniqueId &id, Pokemon::gen gen, QObject *parent) : QAbstractTableModel(parent), id(id), gen(gen) +PokeMovesModel::PokeMovesModel(const Pokemon::uniqueId &id, Pokemon::gen gen, QObject *parent, bool hackmons) : QAbstractTableModel(parent), id(id), gen(gen), hackmons(hackmons) { loadData(); } -QHash getMoves(const Pokemon::uniqueId &num, Pokemon::gen gen, bool root = true) { +QHash getMoves(const Pokemon::uniqueId &num, Pokemon::gen gen, bool root = true, bool hackmons = false) { QHash ret; - if (gen.num != 1 && gen.num != 3) { - ret = getMoves(num, Pokemon::gen(gen.num-1, GenInfo::NumberOfSubgens(gen.num-1)-1), false); + if (!hackmons) { + if (gen.num != 1 && gen.num != 3) { + ret = getMoves(num, Pokemon::gen(gen.num-1, GenInfo::NumberOfSubgens(gen.num-1)-1), false); + } + return ret.unite(map_container_with_value(PokemonInfo::TMMoves(num, gen), root ? QObject::tr("TM/HM") : QObject::tr("%1G TM/HM").arg(gen.num))) + .unite(map_container_with_value(PokemonInfo::TutorMoves(num, gen), root ? QObject::tr("Tutor") : QObject::tr("%1G Tutor").arg(gen.num))) + .unite(map_container_with_value(PokemonInfo::LevelMoves(num, gen), root ? QObject::tr("Level") : QObject::tr("%1G Level").arg(gen.num))) + .unite(map_container_with_value(PokemonInfo::PreEvoMoves(num, gen), root ? QObject::tr("Pre Evo") :QObject:: tr("%1G Pre Evo").arg(gen.num))) + .unite(map_container_with_value(PokemonInfo::EggMoves(num, gen), root ? QObject::tr("Breeding") : QObject::tr("%1G Breeding").arg(gen.num))) + .unite((gen.num == 5 ? map_container_with_value(PokemonInfo::dreamWorldMoves(num, gen), QObject::tr("Dream World")) : QHash())) + .unite(map_container_with_value(PokemonInfo::SpecialMoves(num, gen), root ? QObject::tr("Special", "Learning") : QObject::tr("%1G Special").arg(gen.num))); + } else { + QSet allMoves = MoveInfo::Moves(gen); + allMoves.remove(Move::NoMove); + allMoves.remove(Move::Struggle); + return ret = map_container_with_value(allMoves, QObject::tr("Hackmons")); } - return ret.unite(map_container_with_value(PokemonInfo::TMMoves(num, gen), root ? QObject::tr("TM/HM") : QObject::tr("%1G TM/HM").arg(gen.num))) - .unite(map_container_with_value(PokemonInfo::TutorMoves(num, gen), root ? QObject::tr("Tutor") : QObject::tr("%1G Tutor").arg(gen.num))) - .unite(map_container_with_value(PokemonInfo::LevelMoves(num, gen), root ? QObject::tr("Level") : QObject::tr("%1G Level").arg(gen.num))) - .unite(map_container_with_value(PokemonInfo::PreEvoMoves(num, gen), root ? QObject::tr("Pre Evo") :QObject:: tr("%1G Pre Evo").arg(gen.num))) - .unite(map_container_with_value(PokemonInfo::EggMoves(num, gen), root ? QObject::tr("Breeding") : QObject::tr("%1G Breeding").arg(gen.num))) - .unite((gen.num == 5 ? map_container_with_value(PokemonInfo::dreamWorldMoves(num, gen), QObject::tr("Dream World")) : QHash())) - .unite(map_container_with_value(PokemonInfo::SpecialMoves(num, gen), root ? QObject::tr("Special", "Learning") : QObject::tr("%1G Special").arg(gen.num))); } void PokeMovesModel::loadData() { - QHash sets = getMoves(id, gen); + QHash sets = getMoves(id, gen, true, hackmons); storage.clear(); foreach(int key, sets.uniqueKeys()) { diff --git a/src/libraries/TeambuilderLibrary/pokemovesmodel.h b/src/libraries/TeambuilderLibrary/pokemovesmodel.h index 056acb6adf..8ad64b2770 100644 --- a/src/libraries/TeambuilderLibrary/pokemovesmodel.h +++ b/src/libraries/TeambuilderLibrary/pokemovesmodel.h @@ -8,7 +8,7 @@ class PokeMovesModel : public QAbstractTableModel { public: - PokeMovesModel(const Pokemon::uniqueId &id, Pokemon::gen gen = Pokemon::gen(), QObject *parent=0); + PokeMovesModel(const Pokemon::uniqueId &id, Pokemon::gen gen = Pokemon::gen(), QObject *parent=0, bool hackmons = false); void setPokemon(const Pokemon::uniqueId &id, Pokemon::gen gen = Pokemon::gen()); int rowCount(const QModelIndex &parent) const; @@ -34,7 +34,7 @@ class PokeMovesModel : public QAbstractTableModel Pokemon::uniqueId id; Pokemon::gen gen; - + bool hackmons; QMap > storage; QList names; };