/////////////////////////////////////////////////////////////////////////////
// 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 "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 unsigned _id) :
Object(par, _id),
name(""),
accuracy(1, 1),
power(0),
type(UINT_MAX),
special(false),
powerPoints(0),
target(UINT_MAX),
targetChoice(UINT_MAX),
ignoreAccuracy(false),
canFlinch(false),
canRandom(false),
canSnatch(false),
sound(false),
description("")
{
}
Move::Move(const Pokemod& par, const Move& m, const unsigned _id) :
Object(par, _id)
{
*this = m;
}
Move::Move(const Pokemod& par, const QString& fname, const unsigned _id) :
Object(par, _id)
{
load(fname, _id);
}
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) == UINT_MAX)
{
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;
}
unsigned Move::getNewId() const
{
unsigned i = 0;
for (; (i < getEffectCount()) && (getEffectIndex(i) != UINT_MAX); ++i)
;
return i;
}
void Move::load(const QString& fname, const unsigned _id) throw(Exception)
{
Ini ini(fname);
if (_id == UINT_MAX)
ini.getValue("id", id);
else
id = _id;
unsigned i;
unsigned 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 unsigned n, const unsigned d) throw(Exception)
{
accuracy.set(n, d);
}
void Move::setAccuracyNum(const unsigned n) throw(Exception)
{
accuracy.setNum(n);
}
void Move::setAccuracyDenom(const unsigned d) throw(Exception)
{
accuracy.setDenom(d);
}
void Move::setType(const unsigned t) throw(BoundsException)
{
if (pokemod.getTypeIndex(t) == UINT_MAX)
throw(BoundsException("Move", "type"));
type = t;
}
void Move::setSpecial(const bool s)
{
special = s;
}
void Move::setPowerPoints(const unsigned p) throw(BoundsException)
{
if (!p)
throw(BoundsException("Move", "powerPoints"));
powerPoints = p;
}
void Move::setTarget(const unsigned t) throw(BoundsException)
{
if (T_End <= t)
throw(BoundsException("Move", "target"));
target = t;
}
void Move::setNumTargets(const unsigned n) throw(BoundsException)
{
if (!n || ((pokemod.getRules().getMaxFight() << 1) < n))
throw(BoundsException("Move", "numTargets"));
numTargets = n;
}
void Move::setTargetChoice(const unsigned t) throw(BoundsException)
{
if (C_End <= t)
throw(BoundsException("Move", "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;
}
QString Move::getName() const
{
return name;
}
Frac Move::getAccuracy() const
{
return accuracy;
}
unsigned Move::getType() const
{
return type;
}
bool Move::getSpecial() const
{
return special;
}
unsigned Move::getPowerPoints() const
{
return powerPoints;
}
unsigned Move::getTarget() const
{
return target;
}
unsigned Move::getNumTargets() const
{
return numTargets;
}
unsigned 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 unsigned i) const throw(IndexException)
{
if (getEffectCount() <= i)
throw(IndexException("Move"));
return effects.at(i);
}
MoveEffect& Move::getEffect(const unsigned i) throw(IndexException)
{
if (getEffectCount() <= i)
throw(IndexException("Move"));
return effects[i];
}
const MoveEffect& Move::getEffectByID(const unsigned i) const throw(IndexException)
{
return getEffect(getEffectIndex(i));
}
MoveEffect& Move::getEffectByID(const unsigned i) throw(IndexException)
{
return getEffect(getEffectIndex(i));
}
unsigned Move::getEffectIndex(const unsigned _id) const
{
for (unsigned i = 0; i < getEffectCount(); ++i)
{
if (effects[i].getId() == _id)
return i;
}
return UINT_MAX;
}
unsigned Move::getEffectCount() const
{
return effects.size();
}
MoveEffect& Move::newEffect()
{
effects.append(MoveEffect(pokemod, getNewId()));
return effects[getEffectCount() - 1];
}
MoveEffect& Move::newEffect(const QString& fname)
{
effects.append(MoveEffect(pokemod, fname, getNewId()));
return effects[getEffectCount() - 1];
}
MoveEffect& Move::newEffect(const MoveEffect& e)
{
effects.append(MoveEffect(pokemod, e, getNewId()));
return effects[getEffectCount() - 1];
}
void Move::deleteEffect(const unsigned i) throw(IndexException)
{
if (getEffectCount() <= i)
throw(IndexException("Move"));
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 (unsigned i = 0; i < rhs.getEffectCount(); ++i)
newEffect(rhs.getEffect(i));
return *this;
}