/*
* The Mana Server
* Copyright (C) 2010 The Mana Development Team
*
* This file is part of The Mana Server.
*
* The Mana Server 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 2 of the License, or
* any later version.
*
* The Mana Server 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 The Mana Server. If not, see .
*/
#include "attack.h"
#include
#include "common/defines.h"
#include "game-server/character.h"
#include "game-server/skillmanager.h"
AttackInfo *AttackInfo::readAttackNode(xmlNodePtr node)
{
std::string skill = XML::getProperty(node, "skill", std::string());
unsigned skillId;
if (utils::isNumeric(skill))
skillId = utils::stringToInt(skill);
else
skillId = skillManager->getId(skill);
if (!skill.empty() && !skillManager->exists(skillId))
{
LOG_WARN("Error parsing Attack node: Invalid skill " << skill
<< " taking default skill");
skillId = skillManager->getDefaultSkillId();
}
unsigned id = XML::getProperty(node, "id", 0);
unsigned priority = XML::getProperty(node, "priority", 0);
unsigned warmupTime = XML::getProperty(node, "warmuptime", 0);
unsigned cooldownTime = XML::getProperty(node, "cooldowntime", 0);
unsigned reuseTime = XML::getProperty(node, "reusetime", 0);
unsigned short baseDamange = XML::getProperty(node, "basedamage", 0);
unsigned short deltaDamage = XML::getProperty(node, "deltadamage", 0);
unsigned short chanceToHit = XML::getProperty(node, "chancetohit", 0);
unsigned short range = XML::getProperty(node, "range", 0);
Element element = elementFromString(
XML::getProperty(node, "element", "neutral"));
DamageType type = damageTypeFromString(
XML::getProperty(node, "type", "other"));
Damage dmg;
dmg.id = id;
dmg.skill = skillId;
dmg.base = baseDamange;
dmg.delta = deltaDamage;
dmg.cth = chanceToHit;
dmg.range = range;
dmg.element = element;
dmg.type = type;
AttackInfo *attack = new AttackInfo(priority, dmg, warmupTime, cooldownTime,
reuseTime);
return attack;
}
void Attacks::add(AttackInfo *attackInfo)
{
mAttacks.push_back(Attack(attackInfo));
attack_added.emit(*mAttacks.rbegin());
}
void Attacks::remove(AttackInfo *attackInfo)
{
for (std::vector::iterator it = mAttacks.begin(),
it_end = mAttacks.end(); it != it_end; ++it)
{
if ((*it).getAttackInfo() == attackInfo)
{
if (mCurrentAttack && mCurrentAttack->getAttackInfo() == attackInfo)
mCurrentAttack = 0;
attack_removed.emit(*it);
mAttacks.erase(it);
return;
}
}
}
void Attacks::markAttackAsTriggered()
{
mCurrentAttack->markAsTriggered();
mCurrentAttack = 0;
}
Attack *Attacks::getTriggerableAttack()
{
if (!mCurrentAttack)
return 0;
int cooldownTime = mCurrentAttack->getAttackInfo()->getCooldownTime();
if (mAttackTimer.remaining() <= cooldownTime)
{
return mCurrentAttack;
}
return 0;
}
void Attacks::startAttack(Attack *attack)
{
mCurrentAttack = attack;
mAttackTimer.set(attack->getAttackInfo()->getWarmupTime() +
attack->getAttackInfo()->getCooldownTime());
}
void Attacks::getUsuableAttacks(std::vector *ret)
{
assert(ret != 0);
// we have a current Attack
if ((!mAttackTimer.expired() && mCurrentAttack))
return;
for (std::vector::iterator it = mAttacks.begin();
it != mAttacks.end(); ++it)
{
Attack &attack = *it;
if (attack.isUsuable())
{
ret->push_back(&attack);
}
}
}