///////////////////////////////////////////////////////////////////////////// // Name: pokemod/Move.cpp // Purpose: Define a move that can be learned // Author: Ben Boeckel // Modified by: Ben Boeckel // Created: Sat May 26 2007 22:51:21 // Copyright: ©2007-2008 Ben Boeckel and Nerdy Productions // Licence: // This program 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 . ///////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include "Pokemod.h" #include "MoveEffect.h" #include "Move.h" const QStringList Move::TargetStr = QStringList() << "Player" << "Enemy" << "Both" << "Random"; const QStringList Move::ChoiceStr = QStringList() << "Player" << "Enemy" << "Random"; Move::Move(const Pokemod* par, const int _id) : Object("Move", par, _id), name(""), accuracy(1, 1), power(0), type(-1), special(false), powerPoints(0), target(-1), targetChoice(-1), ignoreAccuracy(false), canFlinch(false), canRandom(false), canSnatch(false), sound(false), description("") { } Move::Move(const Pokemod* par, const Move& m, const int _id) : Object("Move", par, _id) { *this = m; } Move::Move(const Pokemod* par, const QString& fname, const int _id) : Object("Move", par, _id) { load(fname, _id); } Move::~Move() { for (QListIterator i(effects); i.hasNext(); ) delete i.next(); } bool Move::validate() const { bool valid = true; pokemod->validationMsg(QString("---Move \"%1\" with id %2---").arg(name).arg(id), Pokemod::V_Msg); if (name == "") { pokemod->validationMsg("Name is not defined"); valid = ""; } if (pokemod->getTypeIndex(type) == -1) { pokemod->validationMsg("Invalid type"); valid = false; } if (!powerPoints) { pokemod->validationMsg("Invalid number of power points"); valid = false; } if (T_End <= target) { pokemod->validationMsg("Invalid target"); valid = false; } if (!target || (pokemod->getRules()->getMaxFight() << (target == T_Both)) < numTargets) { pokemod->validationMsg("Invalid number of targets"); valid = false; } if (C_End <= targetChoice) { pokemod->validationMsg("Invalid target choice"); valid = false; } if (getEffectCount()) { QMap idChecker; for (QListIterator i(effects); i.hasNext(); i.next()) { if (!i.peekNext()->isValid()) valid = false; ++idChecker[i.peekNext()->getId()]; } for (QMapIterator i(idChecker); i.hasNext(); i.next()) { if (1 < i.value()) { pokemod->validationMsg(QString("There are %1 effects with id %2").arg(i.value()).arg(i.key())); valid = false; } } } else { pokemod->validationMsg("There are no effects"); valid = false; } return valid; } int Move::getNewId() const { int i = 0; for (; (i < getEffectCount()) && (getEffectIndex(i) != -1); ++i) ; return i; } void Move::load(const QString& fname, const int _id) throw(Exception) { Ini ini(fname); if (_id == -1) ini.getValue("id", id); else id = _id; int i; int j; ini.getValue("name", name); ini.getValue("accuracy-n", i, 1); ini.getValue("accuracy-d", j, 1); accuracy.set(i, j); ini.getValue("power", power, 0); ini.getValue("type", type); ini.getValue("special", special, false); ini.getValue("powerPoints", powerPoints, 1); ini.getValue("target", target); ini.getValue("numTargets", numTargets, 0); ini.getValue("targetChoice", targetChoice); ini.getValue("ignoreAccuracy", ignoreAccuracy, false); ini.getValue("canFlinch", canFlinch, false); ini.getValue("canRandom", canRandom, false); ini.getValue("canSnatch", canSnatch, false); ini.getValue("sound", sound, false); ini.getValue("description", description, ""); QStringList path = pokemod->getPath().split('/'); path.removeLast(); QDir fdir(path.join("/")); effects.clear(); if (fdir.cd("effect")) { for (QStringListIterator i(fdir.entryList(QStringList("*.pini"), QDir::Files, QDir::Name)); i.hasNext(); ) newEffect(i.next()); } } void Move::save() const throw(Exception) { Ini ini; ini.addField("id", id); ini.addField("name", name); ini.addField("accuracy-n", accuracy.getNum()); ini.addField("accuracy-d", accuracy.getDenom()); ini.addField("power", power); ini.addField("type", type); ini.addField("special", special); ini.addField("powerPoints", powerPoints); ini.addField("target", target); ini.addField("numTargets", numTargets); ini.addField("targetChoice", targetChoice); ini.addField("ignoreAccuracy", ignoreAccuracy); ini.addField("canFlinch", canFlinch); ini.addField("canRandom", canRandom); ini.addField("canSnatch", canSnatch); ini.addField("sound", sound); ini.addField("description", description); ini.save(QString("%1/move/%2/data.pini").arg(pokemod->getPath()).arg(name)); for (QListIterator i(effects); i.hasNext(); ) i.next()->save(name); } void Move::setName(const QString& n) { name = n; } void Move::setAccuracy(const int n, const int d) throw(Exception) { accuracy.set(n, d); } void Move::setAccuracyNum(const int n) throw(Exception) { accuracy.setNum(n); } void Move::setAccuracyDenom(const int d) throw(Exception) { accuracy.setDenom(d); } void Move::setType(const int t) throw(BoundsException) { if (pokemod->getTypeIndex(t) == -1) throw(BoundsException(className, "type")); type = t; } void Move::setSpecial(const bool s) { special = s; } void Move::setPowerPoints(const int p) throw(BoundsException) { if (!p) throw(BoundsException(className, "powerPoints")); powerPoints = p; } void Move::setTarget(const int t) throw(BoundsException) { if (T_End <= t) throw(BoundsException(className, "target")); target = t; } void Move::setNumTargets(const int n) throw(BoundsException) { if (!n || ((pokemod->getRules()->getMaxFight() << 1) < n)) throw(BoundsException(className, "numTargets")); numTargets = n; } void Move::setTargetChoice(const int t) throw(BoundsException) { if (C_End <= t) throw(BoundsException(className, "targetChoice")); targetChoice = t; } void Move::setIgnoreAccuracy(const bool i) { ignoreAccuracy = i; } void Move::setCanFlinch(const bool c) { canFlinch = c; } void Move::setCanRandom(const bool c) { canRandom = c; } void Move::setCanSnatch(const bool c) { canSnatch = c; } void Move::setSound(const bool s) { sound = s; } void Move::setDescription(const QString& d) { description = d; } QString Move::getName() const { return name; } Frac Move::getAccuracy() const { return accuracy; } int Move::getType() const { return type; } bool Move::getSpecial() const { return special; } int Move::getPowerPoints() const { return powerPoints; } int Move::getTarget() const { return target; } int Move::getNumTargets() const { return numTargets; } int Move::getTargetChoice() const { return targetChoice; } bool Move::getIgnoreAccuracy() const { return ignoreAccuracy; } bool Move::getCanFlinch() const { return canFlinch; } bool Move::getCanRandom() const { return canRandom; } bool Move::getCanSnatch() const { return canSnatch; } bool Move::getSound() const { return sound; } QString Move::getDescription() const { return description; } const MoveEffect* Move::getEffect(const int i) const throw(IndexException) { if (getEffectCount() <= i) throw(IndexException(className)); return effects.at(i); } MoveEffect* Move::getEffect(const int i) throw(IndexException) { if (getEffectCount() <= i) throw(IndexException(className)); return effects[i]; } const MoveEffect* Move::getEffectByID(const int i) const throw(IndexException) { return getEffect(getEffectIndex(i)); } MoveEffect* Move::getEffectByID(const int i) throw(IndexException) { return getEffect(getEffectIndex(i)); } int Move::getEffectIndex(const int _id) const { for (int i = 0; i < getEffectCount(); ++i) { if (effects[i]->getId() == _id) return i; } return -1; } int Move::getEffectCount() const { return effects.size(); } MoveEffect* Move::newEffect() { effects.append(new MoveEffect(pokemod, getNewId())); return effects[getEffectCount() - 1]; } MoveEffect* Move::newEffect(const QString& fname) { effects.append(new MoveEffect(pokemod, fname, getNewId())); return effects[getEffectCount() - 1]; } MoveEffect* Move::newEffect(const MoveEffect& e) { effects.append(new MoveEffect(pokemod, e, getNewId())); return effects[getEffectCount() - 1]; } void Move::deleteEffect(const int i) throw(IndexException) { if (getEffectCount() <= i) throw(IndexException(className)); delete effects[i]; effects.removeAt(i); } Move& Move::operator=(const Move& rhs) { if (this == &rhs) return *this; name = rhs.name; accuracy = rhs.accuracy; power = rhs.power; type = rhs.type; special = rhs.special; powerPoints = rhs.powerPoints; target = rhs.target; numTargets = rhs.numTargets; targetChoice = rhs.targetChoice; ignoreAccuracy = rhs.ignoreAccuracy; canFlinch = rhs.canFlinch; canRandom = rhs.canRandom; canSnatch = rhs.canSnatch; sound = rhs.sound; description = rhs.description; effects.clear(); for (int i = 0; i < rhs.getEffectCount(); ++i) effects.append(new MoveEffect(pokemod, *rhs.getEffect(i), rhs.getEffect(i)->getId())); return *this; }