diff options
Diffstat (limited to 'src/game-server/attack.cpp')
-rw-r--r-- | src/game-server/attack.cpp | 124 |
1 files changed, 93 insertions, 31 deletions
diff --git a/src/game-server/attack.cpp b/src/game-server/attack.cpp index 4f04255..1825b86 100644 --- a/src/game-server/attack.cpp +++ b/src/game-server/attack.cpp @@ -20,58 +20,120 @@ #include "attack.h" -void Attacks::add(const Attack &attack) +#include <cassert> + +#include "common/defines.h" + +#include "game-server/character.h" +#include "game-server/skillmanager.h" + +AttackInfo *AttackInfo::readAttackNode(xmlNodePtr node) { - mAttacks.push_back(attack); - // Slow, but safe. - mAttacks.sort(); + 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::clear() +void Attacks::add(AttackInfo *attackInfo) { - mAttacks.clear(); + mAttacks.push_back(Attack(attackInfo)); } -void Attacks::stop() +void Attacks::remove(AttackInfo *attackInfo) { - for (std::list<Attack>::iterator it = mAttacks.begin(); - it != mAttacks.end(); ++it) + for (std::vector<Attack>::iterator it = mAttacks.begin(), + it_end = mAttacks.end(); it != it_end; ++it) { - it->halt(); + if ((*it).getAttackInfo() == attackInfo) + { + if (mCurrentAttack && mCurrentAttack->getAttackInfo() == attackInfo) + mCurrentAttack = 0; + mAttacks.erase(it); + return; + } } - mActive = false; } -void Attacks::start() +void Attacks::markAttackAsTriggered() { - for (std::list<Attack>::iterator it = mAttacks.begin(); - it != mAttacks.end(); ++it) + mCurrentAttack->markAsTriggered(); + mCurrentAttack = 0; +} + +Attack *Attacks::getTriggerableAttack() +{ + if (!mCurrentAttack) + return 0; + + int cooldownTime = mCurrentAttack->getAttackInfo()->getCooldownTime(); + if (mAttackTimer.remaining() <= cooldownTime) { - // If the attack is inactive, we hard reset it. - if (!it->getTimer()) - it->reset(); - else - it->softReset(); + return mCurrentAttack; } - mActive = true; + + return 0; } -void Attacks::tick(std::list<Attack> *ret) +void Attacks::startAttack(Attack *attack) { - for (std::list<Attack>::iterator it = mAttacks.begin(); + mCurrentAttack = attack; + mAttackTimer.set(attack->getAttackInfo()->getWarmupTime() + + attack->getAttackInfo()->getCooldownTime()); +} + +void Attacks::getUsuableAttacks(std::vector<Attack *> *ret) +{ + assert(ret != 0); + + // we have a current Attack + if ((!mAttackTimer.expired() && mCurrentAttack)) + return; + for (std::vector<Attack>::iterator it = mAttacks.begin(); it != mAttacks.end(); ++it) { - if (it->tick()) - { - if (mActive) - it->reset(); - else - it->halt(); - } + Attack &attack = *it; - if (ret && it->isReady()) + if (attack.isUsuable()) { - ret->push_back(*it); + ret->push_back(&attack); } } } |